Chaining Static Methods in PHP?

前端 未结 16 1950
情歌与酒
情歌与酒 2020-11-27 14:25

Is it possible to chain static methods together using a static class? Say I wanted to do something like this:

$value = TestClass::toValue(5)::add(3)::subtrac         


        
相关标签:
16条回答
  • 2020-11-27 14:55

    In a nutshell... no. :) The resolution operator (::) would work for the TetsClass::toValue(5) part, but everything after that will just give a syntax error.

    Once namespaces are implemented in 5.3, you can have "chained" :: operators, but all that'll do is drill down through the namespace tree; it won't be possible to have methods in the middle of things like this.

    0 讨论(0)
  • 2020-11-27 14:57

    Here's another way without going through a getInstance method (tested on PHP 7.x):

    class TestClass
    {
        private $result = 0;
    
        public function __call($method, $args)
        {
            return $this->call($method, $args);
        }
    
        public static function __callStatic($method, $args)
        {
            return (new static())->call($method, $args);
        }
    
        private function call($method, $args)
        {
            if (! method_exists($this , '_' . $method)) {
                throw new Exception('Call undefined method ' . $method);
            }
    
            return $this->{'_' . $method}(...$args);
        }
    
        private function _add($num)
        {
            $this->result += $num;
    
            return $this;
        }
    
        private function _subtract($num)
        {
            $this->result -= $num;
    
            return $this;
        }
    
        public function result()
        {
            return $this->result;
        }
    }
    

    The class can be used as following:

    $res1 = TestClass::add(5)
        ->add(3)
        ->subtract(2)
        ->add(8)
        ->result();
    
    echo $res1 . PHP_EOL; // 14
    
    $res2 = TestClass::subtract(1)->add(10)->result();
    echo $res2 . PHP_EOL; // 9
    
    0 讨论(0)
  • 2020-11-27 14:58
    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();
    
    0 讨论(0)
  • 2020-11-27 15:02

    Technically you can call a static method on an instance like $object::method() in PHP 7+, so returning a new instance should work as a replacement for return self. And indeed it works.

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

    Outputs int(14).

    This about same as returning __CLASS__ as used in other answer. I rather hope no-one ever decides to actually use these forms of API, but you asked for it.

    0 讨论(0)
提交回复
热议问题