Chaining Static Methods in PHP?

前端 未结 16 1948
情歌与酒
情歌与酒 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:37

    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();
    
    0 讨论(0)
  • 2020-11-27 14:39

    If toValue(x) returns an object, you could do like this:

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

    Providing that toValue returns a new instance of the object, and each next method mutates it, returning an instance of $this.

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

    People are overcomplicating this like crazy.

    Check this out:

    class OopClass
    {
        public $first;
        public $second;
        public $third;
    
        public static function make($first)
        {
            return new OopClass($first);
        }
    
        public function __construct($first)
        {
            $this->first = $first;
        }
    
        public function second($second)
        {
            $this->second = $second;
            return $this;
        }
    
        public function third($third)
        {
            $this->third = $third;
            return $this;
        }
    }
    

    Usage:

    OopClass::make('Hello')->second('To')->third('World');
    
    0 讨论(0)
  • 2020-11-27 14:41

    Use PHP 7! If your web provider cannot --> change provider! Don't lock in past.

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

    And very simple use:

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

    Return (or throw error):

    int(14)
    

    completed contract.

    Rule one: most evolved and maintainable is always better.

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

    Fully functional example of method chaining with static attributes:

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

    Example of use:

    Response::getInstance()->code(400)->sendError("Lacks id in request");
    
    0 讨论(0)
  • 2020-11-27 14:43

    I like the solution provided by Camilo above, essentially since all you're doing is altering the value of a static member, and since you do want chaining (even though it's only syntatic sugar), then instantiating TestClass is probably the best way to go.

    I'd suggest a Singleton pattern if you want to restrict instantiation of the class:

    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();
    
    0 讨论(0)
提交回复
热议问题