【问题标题】:PHP Factory class with variable number of arguments具有可变数量参数的 PHP 工厂类
【发布时间】:2012-03-09 19:19:09
【问题描述】:

我将创建一个(某种)工厂类,它接受可变数量的参数并将它们传递给它将调用的类

<?php

class A {
    private $a;
    private $b;
    private $c;
    public function __construct($a=1, $b=2, $c=3){
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
    }
}

class B {
    private $foo;

    public function __construct(){
        $args = func_get_args();
        $this->foo = call_user_func_array(array('A', '__construct'), $args);
    }

    public function getObject(){
        return $this->foo;
    }
}

$b = new B(10, 20, 30);  
var_dump($b->getObject()); // should return equivalent of new A(10,20,30);

我收到了这个错误

PHP Warning:  call_user_func_array() expects parameter 1 to be a valid callback, non-static method A::__construct() cannot be called statically

【问题讨论】:

    标签: php oop factory


    【解决方案1】:

    发现这个答案阅读关于ReflectionClass。这似乎效果最好

    <?php
    class Factory {
        # ...
        public function __construct(){
            $args = func_get_args();
            $a = new ReflectionClass('A');
            $this->foo = $a->newInstanceArgs($args);
        }
        # ...
    }
    

    【讨论】:

      【解决方案2】:
      $class = "A";
      $foo = new $class(1, 2, 56); // i think this not solve your problem
      

      或者使用 ReflectionClass 或者使用属性注入的构造函数注入。

      【讨论】:

      • 这仍然在传递静态数量的变量。不过感谢 ReflectionClass 指针;这导致了正确的答案。
      【解决方案3】:

      我认为您应该通过不将值传递给构造函数,而是通过链接来解决问题。

      class MyFactory() {
          public $data;
      
          public static function factory( $data = null ) {
              return new MyFactory( $data );
          }
          public function addArgument( $argValue ) {
              $this->data[] = $argValue;
              return $this;
          }
      
          public function doSomeFunction() {
              $data = $this->data; //is an array, so you can loop through and do whatever.
              /* now your arbitrarily long array of data points can be used to do whatever. */
          }
      }
      

      你可以这样使用它:

      $factory = MyFactory::factory();
      $factory
          ->addArgument( '21' )
          ->addArgument( '903' )
          ->addArgument( '1' )
          ->addArgument( 'abc' )
          ->addArgument( 'jackson' )
          ->doSomeFunction();
      

      我希望至少能让你朝着一个有用的方向前进。你可以用这种模式做各种疯狂的事情。

      【讨论】:

      • Kristian,这是一个很好的答案,但不幸的是我无法在我的示例中修改 A 类。 B 类将用作它的包装器,它也实例化它。
      【解决方案4】:

      试试这个,根据php doc第一个例子:http://us2.php.net/call_user_func_array

      $this->foo = call_user_func_array(array(new A, '__construct'), $args);
      

      【讨论】:

      • @Truth 你在说什么?询问一个新对象与询问一个静态函数 new A vs A::Function 是有区别的
      • 那为什么 PHP.net 建议它这样做呢?
      • 如果A 在构造函数中有任何强制参数,这不起作用,因为new A 将尝试在call_user_func_array 有机会将我的$args 发送到之前构造一个新对象它。 PHP对这个问题的实际解决方法见上面的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 2018-07-20
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      相关资源
      最近更新 更多