PHP Statik Yöntemleri zincirleme?

8 Cevap php

Birlikte statik bir sınıf kullanarak zincir statik yöntemlerle mümkün mü? Ben böyle bir şey yapmak istedim ki:

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

. . . ve tabii ki ben $ değer sayısını 14 atanmasını isterim., bu mümkün mü?

: - (! Bir örneği değil, siz "kendi kendine" geri dönemezsiniz): Update, ama benim düşüncelerim bana almış bu nerede bu işe yaramazsa

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;
    }
}

Dışarı çalıştıktan sonra, ben sadece basit ziyade zincir statik işlev çağrıları (yukarıdaki örnekte bir şekilde tweaked olabilir olmadıkça, mümkün görünmüyor ki) çalışırken daha bir sınıf örneği ile çalışmak daha mantıklı olacağını düşünüyorum.

8 Cevap

Ben yaptığın her bir statik üyesi değerini değiştiren aslında, zira yukarıda Camilo tarafından sağlanan çözüm gibi, ve sen başlatmasını sonra, (sadece syntatic şeker olsa bile) zincirleme istiyorsun beri TestClass muhtemelen gitmek için en iyi yoldur .

Eğer sınıfın örneğinin kısıtlamak isterseniz ben bir Singleton deseni öneririm:

class TestClass
{   
    public static $currentValue;

    private static $_instance = null;

    private __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 $this::$currentValue;
    }
}

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

PHP5.3 Little çılgın kodu ... sadece eğlence için.

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();

TOVALUE (x) bir nesne döndürür, böyle yapabilirsin:

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

TOVALUE nesnenin yeni bir örneğini döndürür ve her yeni yöntem $ bunun bir örneğini dönen, onu mutasyona kaydıyla.

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();

Sen her zaman statik ve örnek yöntemleri gibi kalan olarak Birinci yöntemi kullanabilirsiniz:

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

Ya da daha iyisi:

 $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);
     }
 }

Sadece bir Bilginize .. ben (burada sitede) kafamın üst kapalı bu yazdı. Yani, koşmak değil, ama bu fikir. Ben de eval bir özyinelemeli yöntem çağrısı yaptı olabilir, ama bu basit olabilir düşündüm. Başka yardım hazırlamak veya sağlamak için bana isterseniz lütfen bana bildirin.

Özetle ... hayır. Çözünürlük operatörü (::) :) TetsClass :: TOVALUE (5) kısmı için işe yarayacağını, ancak bundan sonra her şey sadece bir sözdizimi hatası verecektir.

Ad alanları 5.3 uygulanır sonra, :: operatörleri "zincirleme" var, ancak tüm bu yapacağım ad alanı ağacının üzerinden detaya olup; bu gibi şeylerin ortasında yöntemleri olması mümkün olmayacaktır.

Hayır, bu iş olmaz. :: Operator geri sınıfa değerlendirmek gerekiyor, bu yüzden TestClass :: TOVALUE (5) değerlendirir sonra, :: (3) yöntemi yalnızca sonuncusunun cevaba değerlendirmek mümkün olacaktır ekleyin. TOVALUE (5) tamsayı 5 döndü Yani, temelde int çağırıyor olacak (5) :: besbelli bir hata olan (3) ekleyin.

The best that can be done

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

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