代码之家  ›  专栏  ›  技术社区  ›  LukLed

如何通过编程更改每个方法以返回$this(预定义列表除外)?

  •  0
  • LukLed  · 技术社区  · 14 年前

    我有一堂课:

    class Module {
    
        public function a(...params...) {
            //do something, doesn't return anything
        }
    
        public function b(...params...) {
            //do something, doesn't return anything
        }
    
        public function c(...params...) {
            //do something, doesn't return anything
        }
    
        public function getAsArray() {
            return get_object_vars($this);
        }
    

    }

    是否可以修改模块类,所以方法a()、b()和c()返回$this?我不想把它写在每个函数中。getasarray()应该返回它所做的。模块将是其他类的基础,我希望此机制在基础中实现,但在继承类中使用它。

    我想这样使用它:

    $module = new Module();
    $module->a()->b()->c()->getAsArray();
    
    3 回复  |  直到 12 年前
        1
  •  1
  •   Mark Baker    14 年前

    如果不想在每个方法中添加一行返回$this的代码,可以执行如下操作:

    class Module {
    
        private function _a($value) {
            echo 'Executing method a<br />';
            $this->aVar = $value;
        }
    
        private function _b($value) {
            echo 'Executing method b<br />';
            $this->bVar = $value;
        }
    
        private function _c($value) {
            echo 'Executing method c<br />';
            $this->cVar = $value;
        }
    
        public function getAsArray() {
            return get_object_vars($this);
        }
    
        public function __call($name, $arguments) {
            echo 'Calling method '.$name.'<br />';
            call_user_func_array(array($this,'_'.$name),$arguments);
            return $this;
        }
    }
    
    
    $x = new Module();
    
    var_dump($x->a(1)->b(2)->c(3)->getAsArray());
    

    虽然这对你来说确实比你不喜欢的单行线变化更重要。

    请注意,您不能以任何方式将立即方法调用合并到新的模块行中。这实际上需要您将实例化的对象存储在一个变量中,然后针对该变量链接方法调用。

        2
  •  1
  •   Manos Dilaverakis    14 年前

    不。

    您可以手工完成,也可以编写一个程序来浏览源文件并为您完成。

        3
  •  0
  •   Dennis Haarbrink    14 年前

    在某些情况下,我使用这个基类:

    abstract class FluentInterface
    {
        public function __call($method, $params)
        {
            if(substr($method, 0, 3) == 'set')
            {
                // remove leading 'set' from method
                $prop = substr($method, 3);
                // lowercase first char
                $prop{0} = strtolower($prop{0});
    
                $rc = new ReflectionClass(get_class($this));
                if($rc->hasProperty($prop))
                {
                    $this->$prop = $params[0];
                    return $this;
                }
            }
    
            return false;
        }
    }
    

    但它是专门为getter/setter设计的。 也许你可以在你的特定问题领域扩展一点。