سؤال

هل من الممكن أن سلسلة أساليب ثابتة معا باستخدام ثابت الصف ؟ أقول أردت أن تفعل شيئا مثل هذا:

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();

...و من الواضح أنني أريد $قيمة يتم تعيين رقم 14.هل هذا ممكن ؟

التحديث:أنها لا تعمل (لا يمكنك العودة "الذات" - انها لا مثيل!), ولكن هذا هو المكان أفكاري اتخذت لي:

class TestClass {
    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return self;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return self;
    }

    public static function result() {
        return self::$value;
    }
}

بعد العمل الذي أعتقد أنه سيكون مجرد معنى أكثر من مجرد العمل مع فئة سبيل المثال بدلا من محاولة سلسلة ثابتة المكالمات وظيفة (الذي لا يبدو ممكنا إلا إذا المثال أعلاه يمكن أنب بطريقة أو بأخرى).

هل كانت مفيدة؟

المحلول

أنا أحب الحل المقدمة من قبل كاميلو أعلاه ، أساسا لأن كل ما تفعله هو تغيير قيمة ثابت عضو منذ كنت لا تريد تسلسل (على الرغم من انها فقط syntatic السكر) ، ثم إنشاء TestClass هو على الارجح أفضل وسيلة للذهاب.

أقترح على نمط المفرد إذا كنت ترغب في تقييد مثيل من فئة:

class TestClass
{   
    public static $currentValue;

    private static $_instance = null;

    private function __construct () { }

    public static function getInstance ()
    {
        if (self::$_instance === null) {
            self::$_instance = new self;
        }

        return self::$_instance;
    }

    public function toValue($value) {
        self::$currentValue = $value;
        return $this;
    }

    public function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return $this;
    }

    public function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return $this;
    }

    public function result() {
        return self::$currentValue;
    }
}

// Example Usage:
$result = TestClass::getInstance ()
    ->toValue(5)
    ->add(3)
    ->subtract(2)
    ->add(8)
    ->result();

نصائح أخرى

class oop{
    public static $val;

    public static function add($var){
        static::$val+=$var;
        return new static;
    }

    public static function sub($var){
        static::$val-=$var;
        return new static;
    }

    public static function out(){
        return static::$val;
    }

    public static function init($var){
        static::$val=$var;
        return new static;      
    }
}

echo oop::init(5)->add(2)->out();

الجنون رمز على php5.3...فقط من أجل المتعة.

namespace chaining;
class chain
    {
    static public function one()
        {return get_called_class();}

    static public function two()
        {return get_called_class();}
    }

${${${${chain::one()} = chain::two()}::one()}::two()}::one();

مع php7 سوف تكون قادرة على استخدام المطلوب بناء الجملة لأن من جديد زي متغير الجملة

<?php

abstract class TestClass {

    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
        return __CLASS__;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return __CLASS__;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return __CLASS__;
    }

    public static function result() {
        return self::$currentValue;
    }

}

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();
echo $value;

Demo

إذا toValue(x) بإرجاع كائن, هل يمكن أن تفعل مثل هذا:

$value = TestClass::toValue(5)->add(3)->substract(2)->add(8);

تنص على أن toValue يعود مثيل جديد من الكائن و كل طريقة المقبل وتتبدل ، العودة مثيل $هذا.

يمكن دائما استخدام الأسلوب الأول كما ثابت المتبقية كما أساليب المثال:

$value = Math::toValue(5)->add(3)->subtract(2)->add(8)->result();

أو الأفضل من ذلك:

 $value = Math::eval(Math::value(5)->add(3)->subtract(2)->add(8));

class Math {
     public $operation;
     public $operationValue;
     public $args;
     public $allOperations = array();

     public function __construct($aOperation, $aValue, $theArgs)
     {
       $this->operation = $aOperation;
       $this->operationValue = $aValue;
       $this->args = $theArgs;
     }

     public static function eval($math) {
       if(strcasecmp(get_class($math), "Math") == 0){
            $newValue = $math->operationValue;
            foreach ($math->allOperations as $operationKey=>$currentOperation) {
                switch($currentOperation->operation){
                    case "add":
                         $newvalue = $currentOperation->operationValue + $currentOperation->args;
                         break;
                    case "subtract":
                         $newvalue = $currentOperation->operationValue - $currentOperation->args;
                         break;
                }
            }
            return $newValue;
       }
       return null;
     }

     public function add($number){
         $math = new Math("add", null, $number);
         $this->allOperations[count($this->allOperations)] &= $math;
         return $this;
     }

     public function subtract($number){
         $math = new Math("subtract", null, $number);
         $this->allOperations[count($this->allOperations)] &= $math;
         return $this;
     }

     public static function value($number){
         return new Math("value", $number, null);
     }
 }

فقط لمعلوماتك..كتبت هذا من قمة رأسي (هنا على الموقع).لذا قد لا تعمل, ولكن تلك هي الفكرة.أنا يمكن أن يكون أيضا لم متكررة طريقة الدعوة إلى وحدة التقييم ، ولكن أعتقد أن هذا قد يكون أكثر بساطة.واسمحوا لي أن أعرف إذا كنت تريد مني أن وضع أو تقديم أي مساعدة أخرى.

من الناحية الفنية يمكنك استدعاء أسلوب ثابت على سبيل المثال مثل $object::method() في PHP 7+ حتى عودته مثيل جديد يجب أن تعمل كبديل return self. بل يعمل.

final class TestClass {
    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
        return new static();
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return new static();
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return new static();
    }

    public static function result() {
        return self::$currentValue;
    }
}

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();

var_dump($value);

النواتج int(14).

هذا عن نفسه كما تعود __CLASS__ كما تستخدم في إجابة أخرى.آمل أن لا أحد من أي وقت مضى تقرر في الواقع استخدام هذه الأشكال من API, ولكن هل سألت عن ذلك.

باختصار...لا.:) القرار المشغل (::) هل تعمل TetsClass::toValue(5) جزء ، ولكن كل شيء بعد ذلك سوف يعطي خطأ في بناء الجملة.

مرة واحدة في مساحات تنفذ في 5.3, هل يمكن أن يكون "بالسلاسل" ::المشغلين ، ولكن كل ما عليك القيام به هو انتقل لأسفل عبر مساحة شجرة ؛ فإنه لن يكون من الممكن أن يكون طرق في وسط مثل هذه الأمور.

أفضل ما يمكن القيام به

class S
{
    public static function  __callStatic($name,$args)
    {
        echo 'called S::'.$name . '( )<p>';
        return '_t';
    }
}

$_t='S';
${${S::X()}::F()}::C();

هذا هو أكثر دقة وأسهل للقراءة ودية (يسمح رمز الإنجاز)

class Calculator
{   
    public static $value = 0;

    protected static $onlyInstance;

    protected function __construct () 
    {
        // disable creation of public instances 
    }

    protected static function getself()
    {
        if (static::$onlyInstance === null) 
        {
            static::$onlyInstance = new Calculator;
        }

        return static::$onlyInstance;
    }

    /**
     * add to value
     * @param numeric $num 
     * @return \Calculator
     */
    public static function add($num) 
    {
        static::$value += $num;
        return static::getself();
    }

    /**
     * substruct
     * @param string $num
     * @return \Calculator
     */
    public static function subtract($num) 
    {
        static::$value -= $num;
        return static::getself();
    }

    /**
     * multiple by
     * @param string $num
     * @return \Calculator
     */
    public static function multiple($num) 
    {
        static::$value *= $num;
        return static::getself();
    }

    /**
     * devide by
     * @param string $num
     * @return \Calculator
     */
    public static function devide($num) 
    {
        static::$value /= $num;
        return static::getself();
    }

    public static function result()
    {
        return static::$value;
    }
}

على سبيل المثال:

echo Calculator::add(5)
        ->subtract(2)
        ->multiple(2.1)
        ->devide(10)
    ->result();

النتيجة:0.63

لا, هذا لن يعمل.على :: المشغل يحتاج إلى تقييم مرة أخرى إلى فئة ، وذلك بعد TestClass::toValue(5) يقيم ، ::add(3) الطريقة فقط سوف تكون قادرة على تقييم على الجواب من واحد آخر.

حتى إذا toValue(5) عاد صحيح 5 ، سوف تكون أساسا الدعوة int(5)::add(3) الذي من الواضح أنه خطأ.

أكثر طريقة أسهل من أي وقت مضى لقد وجدت طريقة تسلسل من مثيل جديد أو أسلوب ثابت من فئة أدناه.لقد استخدمت في وقت متأخر ثابت ملزم هنا و أنا حقا أحب هذا الحل.

لقد خلق أداة لإرسال متعددة إعلام المستخدم على الصفحة التالية باستخدام tostr في Laravel.

<?php

namespace App\Utils;

use Session;

use Illuminate\Support\HtmlString;

class Toaster
{
    private static $options = [

        "closeButton" => false,

        "debug" => false,

        "newestOnTop" => false,

        "progressBar" => false,

        "positionClass" => "toast-top-right",

        "preventDuplicates" => false,

        "onclick" => null,

        "showDuration" => "3000",

        "hideDuration" => "1000",

        "timeOut" => "5000",

        "extendedTimeOut" => "1000",

        "showEasing" => "swing",

        "hideEasing" => "linear",

        "showMethod" => "fadeIn",

        "hideMethod" => "fadeOut"
    ];

    private static $toastType = "success";

    private static $instance;

    private static $title;

    private static $message;

    private static $toastTypes = ["success", "info", "warning", "error"];

    public function __construct($options = [])
    {
        self::$options = array_merge(self::$options, $options);
    }

    public static function setOptions(array $options = [])
    {
        self::$options = array_merge(self::$options, $options);

        return self::getInstance();
    }

    public static function setOption($option, $value)
    {
        self::$options[$option] = $value;

        return self::getInstance();
    }

    private static function getInstance()
    {
        if(empty(self::$instance) || self::$instance === null)
        {
            self::setInstance();
        }

        return self::$instance;
    }

    private static function setInstance()
    {
        self::$instance = new static();
    }

    public static function __callStatic($method, $args)
    {
        if(in_array($method, self::$toastTypes))
        {
            self::$toastType = $method;

            return self::getInstance()->initToast($method, $args);
        }

        throw new \Exception("Ohh my god. That toast doesn't exists.");
    }

    public function __call($method, $args)
    {
        return self::__callStatic($method, $args);
    }

    private function initToast($method, $params=[])
    {
        if(count($params)==2)
        {
            self::$title = $params[0];

            self::$message = $params[1];
        }
        elseif(count($params)==1)
        {
            self::$title = ucfirst($method);

            self::$message = $params[0];
        }

        $toasters = [];

        if(Session::has('toasters'))
        {
            $toasters = Session::get('toasters');
        }

        $toast = [

            "options" => self::$options,

            "type" => self::$toastType,

            "title" => self::$title,

            "message" => self::$message
        ];

        $toasters[] = $toast;

        Session::forget('toasters');

        Session::put('toasters', $toasters);

        return $this;
    }

    public static function renderToasters()
    {
        $toasters = Session::get('toasters');

        $string = '';

        if(!empty($toasters))
        {
            $string .= '<script type="application/javascript">';

            $string .= "$(function() {\n";

            foreach ($toasters as $toast)
            {
                $string .= "\n toastr.options = " . json_encode($toast['options'], JSON_PRETTY_PRINT) . ";";

                $string .= "\n toastr['{$toast['type']}']('{$toast['message']}', '{$toast['title']}');";
            }

            $string .= "\n});";

            $string .= '</script>';
        }

        Session::forget('toasters');

        return new HtmlString($string);
    }
}

هذا العمل على النحو التالي.

Toaster::success("Success Message", "Success Title")

    ->setOption('showDuration', 5000)

    ->warning("Warning Message", "Warning Title")

    ->error("Error Message");

وظيفية بالكامل مثال على طريقة تسلسل مع ساكنة سمات:

<?php


class Response
{
    static protected $headers = [];
    static protected $http_code = 200;
    static protected $http_code_msg = '';
    static protected $instance = NULL;


    protected function __construct() { }

    static function getInstance(){
        if(static::$instance == NULL){
            static::$instance = new static();
        }
        return static::$instance;
    }

    public function addHeaders(array $headers)
    {
        static::$headers = $headers;
        return static::getInstance();
    }

    public function addHeader(string $header)
    {
        static::$headers[] = $header;
        return static::getInstance();
    }

    public function code(int $http_code, string $msg = NULL)
    {
        static::$http_code_msg = $msg;
        static::$http_code = $http_code;
        return static::getInstance();
    }

    public function send($data, int $http_code = NULL){
        $http_code = $http_code != NULL ? $http_code : static::$http_code;

        if ($http_code != NULL)
            header(trim("HTTP/1.0 ".$http_code.' '.static::$http_code_msg));

        if (is_array($data) || is_object($data))
            $data = json_encode($data);

        echo $data; 
        exit();     
    }

    function sendError(string $msg_error, int $http_code = null){
        $this->send(['error' => $msg_error], $http_code);
    }
}

مثال على الاستخدام:

Response::getInstance()->code(400)->sendError("Lacks id in request");

استخدام PHP 7!إذا كان لديك مزود ويب لا يمكن --> تغيير موفر!لا قفل في الماضي.

final class TestClass {
    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
        return __CLASS__;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return __CLASS__;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return __CLASS__;
    }

    public static function result() {
        return self::$currentValue;
    }
}

و استخدام بسيط جدا:

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();

var_dump($value);

عودة (أو رمي خطأ):

int(14)

الانتهاء من العقد.

القاعدة الأولى:معظم تطورت للصيانة هو دائما أفضل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top