【问题标题】:PHP OOP: Method ChainingPHP OOP:方法链
【发布时间】:2010-06-07 15:47:12
【问题描述】:

我有以下代码,

<?php
class Templater
{
    static $params = array();

    public static function assign($name, $value)
    {
        self::$params[] = array($name => $value);
    }

    public static function draw()
    {
        self::$params;
    }
}


 $test = Templater::assign('key', 'value');
 $test = Templater::draw();
 print_r($test);

如何更改此脚本以便使用它?

$test = Templater::assign('key', 'value')->assign('key2', 'value2')->draw();
print_r($test);

【问题讨论】:

  • 您可能还想修改 assign() 方法,以便它可以接受键 => 值的数组。
  • 你应该更精确地确定你真正想做的事情。一个简单的关联数组是否符合您的目的?

标签: php oop method-chaining


【解决方案1】:

您不能将Method Chaining 与静态方法一起使用,因为您不能返回类级别范围(return self 不会这样做)。将您的方法更改为常规方法,并在您希望允许链接的每个方法中更改return $this

请注意,您不应使用T_PAAMAYIM_NEKUDOTAYIM 访问实例方法,因为它会引发E_STRICT 通知。使用T_OBJECT_OPERATOR 调用实例方法。

另见:

【讨论】:

    【解决方案2】:

    你不应该使用静态成员:

    class Templater
    {
        private array $params = [];
    
        public function assign($name, $value) : self
        {
            $this->params[$name] = $value;
    
            return $this;
        }
    
        public function draw()
        {
            // do something with $this->params
        }
    }
    
    $test = (new Templater())->assign('key', 'value')->assign('key2', 'value2')->draw();
    

    【讨论】:

    • 你不能像这样链接构造函数!
    【解决方案3】:

    只需使用实例变量和实例函数,而不是静态的。

    <?php
    class Templater
    {
        $params = array();
    
        public function assign($name, $value)
        {
            $this->params[] = array($name => $value); 
            return $this;
        }
    
        public function draw()
        {
            echo $this->params;
            return $this;
        }
    }
    
    $test = new Templater();
    $test->assign('key', 'value')->assign('key2', 'value2')->draw();
    print_r($test);
    

    【讨论】:

    • 您需要添加“return $this;”在 assign() 方法的末尾,否则链接将不起作用。
    【解决方案4】:

    ////////

    类模板 { 静态 $params = array();

    public static function assign($name, $value)
    {
        self::$params[] = array($name => $value);
        return new Templater;
    }
    
    public static function draw()
    {
        return self::$params;
    }
    

    }

    $test = Templater::assign('key', 'value')->assign('key2', 'value2')->draw(); print_r($test);

    【讨论】:

    • 这个答案缺少教育解释和正确的格式。
    【解决方案5】:

    像这样混合静态调用和实例调用一般来说是一种糟糕的形式,省略那个(除非你给出一个需要静态的理由)。您正在使用的另一个概念是调用链,它是使用返回实现的。

    class Templater
    {
        protected $params = array();
    
        public function assign($name, $value) {
            $this->params[] = array($name => $value);
            return $this;
        }
    
        public function draw() {
            // do drawing w/ $this->params;
            return $this;
        }
    }
    

    【讨论】:

      【解决方案6】:
      class Templater
      {   
          public static $params;
      
          private static $_instance = null;
      
          public static function init()
          {
              if (self::$_instance === null)
              {
                  self::$_instance = new self;
              }
      
              return self::$_instance;
          }
      
          public function assign($name, $value)
          {
              self::$params[$name] = $value;
              return $this;
          }
      
          public function draw()
          {
              return self::$params;
          }
      }
      
      $test = Templater::init()->assign('key', 'value')->assign('key2', 'value2')->draw();
      

      【讨论】:

        猜你喜欢
        • 2011-01-19
        • 2015-04-22
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        • 2011-06-15
        • 1970-01-01
        • 2021-12-07
        • 1970-01-01
        相关资源
        最近更新 更多