Класс PHP Factory с переменным числом аргументов - PullRequest
3 голосов
/ 09 марта 2012

Я должен создать (своего рода) фабричный класс, который принимает переменное число аргументов и передает их классу, который будет вызывать

<?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

Ответы [ 4 ]

5 голосов
/ 09 марта 2012

Нашел этот ответ, читая о ReflectionClass .Это, кажется, работает лучше всего

<?php
class Factory {
    # ...
    public function __construct(){
        $args = func_get_args();
        $a = new ReflectionClass('A');
        $this->foo = $a->newInstanceArgs($args);
    }
    # ...
}
2 голосов
/ 09 марта 2012
$class = "A";
$foo = new $class(1, 2, 56); // i think this not solve your problem

Или используйте ReflectionClass или, возможно, конструктор с внедрением свойства.

1 голос
/ 09 марта 2012

Я думаю, что вы должны решить эту проблему, не передавая значения в конструктор, а скорее используя цепочку.

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

Я надеюсь, что, по крайней мере, вы направитесь в полезном направлении.С этим типом рисунка вы можете делать всякие сумасшедшие вещи.

0 голосов
/ 09 марта 2012

Попробуйте, в соответствии с первым примером php doc: http://us2.php.net/call_user_func_array

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