【问题标题】:How to programatically change every method to return $this (except predefined list)?如何以编程方式更改每个方法以返回 $this(预定义列表除外)?
【发布时间】:2010-07-16 13:16:50
【问题描述】:

我有一堂课:

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

【问题讨论】:

    标签: php php-5.2


    【解决方案1】:

    如果您不想在每个方法中添加返回 $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());
    

    虽然它确实比你似乎不喜欢的单行更改要多。

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

    【讨论】:

    • 这是我的想法,但这需要为每个方法定义添加前缀。这比在每个方法中都添加return $this 好,但仍然很痛苦。不是一行,继承类中的每个方法都要返回$this,我不想写在那里。
    • 你有什么特别的原因不想在每个方法中写一个 return $this 吗?
    • 这是不必要的代码冗余。如果不需要,我为什么要写它?
    • 这不是代码冗余。 PHP 中任何方法的默认行为都是返回 NULL:选择返回任何其他值(包括 $this)是必要的,附加代码。
    • 这是必要的,额外的代码,我不想在一个地方,而不是每个函数中都有。我不想把它用于一个分支。
    【解决方案2】:

    没有。

    您要么手动完成,要么编写程序来检查源文件并为您完成。

    【讨论】:

      【解决方案3】:

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

      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 设计的。 也许您可以在您的特定问题领域进行一些扩展。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        • 1970-01-01
        • 1970-01-01
        • 2011-07-30
        • 2014-02-13
        相关资源
        最近更新 更多