在PHP中链接静态方法?

时间:2020-03-06 14:38:27  来源:igfitidea点击:

是否可以使用静态类将静态方法链接在一起?说我想做这样的事情:

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

。 。 。并且显然我希望将$ value分配给数字14. 这可能吗?

更新:它不起作用(我们不能返回" self",它不是实例!),但这就是我的想法带给我的地方:

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

解决了这些问题之后,我认为仅使用类实例而不是尝试链接静态函数调用(这似乎不太可能,除非可以对上述示例进行一些调整)才有意义。

解决方案

简而言之……不。 :)解析运算符(::)适用于TetsClass :: toValue(5)部分,但此后的所有操作都将给出语法错误。

一旦在5.3中实现了名称空间,就可以使用"链式" ::运算符,但是要做的就是深入名称空间树;这样的事情就不可能有方法了。

不,这行不通。 ::运算符需要返回一个类,因此在TestClass :: toValue(5)`求值之后,:: add(3)方法将只能对最后一个的答案求值。一。

因此,如果toValue(5)返回整数5,则我们基本上将调用int(5):: add(3)显然是错误的。

如果toValue(x)返回一个对象,则可以这样:

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

提供toValue会返回该对象的一个​​新实例,每个next方法都会对其进行变异,并返回$ this的一个实例。

我喜欢上面Camilo提供的解决方案,基本上是因为我们要做的只是更改静态成员的值,并且因为我们确实想要链接(即使它只是一种合成糖),所以实例化TestClass可能是最好的方法。

如果我们想限制类的实例化,我建议使用Singleton模式:

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

我们可以始终将First方法用作静态方法,而将其余方法用作实例方法:

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

仅供参考。.我在头顶上写了这个(就在网站上)。因此,它可能不会运行,但这就是想法。我也可以对eval进行递归方法调用,但是我认为这可能更简单。如果我们想让我详细说明或者提供其他帮助,请告诉我。