Создание нового экземпляра объекта с массивом аргументов


Я пытаюсь создать новый экземпляр класса, подобный этому:

$obj = new $class;

Я делаю это таким образом, чтобы общий набор функций делал это для нескольких классов, но теперь я реализую некоторые аргументы. Теперь, хотя функция обработчика может выглядеть так:

function newInst($argA = null, $argB = null, $argC = null)

Это должно было бы включать все аргументы заранее и иметь верхний предел. Итак, я пытаюсь сделать что-то вроде этого:

function newInst() {
    $obj = new $class(func_get_args());
    ...
}

Но вместо первого аргумента будучи примененным, я хотел бы, чтобы он применял массив в качестве набора аргументов. Я пытался

function newInst() {
    $obj = new $class;
    call_user_func_array(array($obj, '__construct'), func_get_args());
    ...
}

Но это вызывает функцию __construct дважды. Итак, есть ли способ использовать аргументы вызываемой функции для создания нового экземпляра, который будет проходить через функцию __construct или classname во время создания экземпляра?

Author: topherg, 2013-06-25

1 answers

Если вы не против использования отражения: Класс отражения::newinstanceargs

function createInstance($class, array $arguments) {
    $reflection = new ReflectionClass($class);
    return $reflection->newInstanceArgs($arguments);
}

Отражение предлагает много, и, несмотря на распространенное утверждение, что оно "медленное", очень часто отражение будет настоящим узким местом в вашем приложении; в любом случае любую возможность можно уменьшить с помощью кэширования.


Основываясь на обсуждении, я просто изменяю гипотетическое решение с помощью count() проверок и наивного кэширования; все равно ( определенно) потребуется профилирование.

function createInstance($class, array $arguments) {
    static $cache = [];
    switch (count($arguments)) {
        case 0: return new $class();
        case 1: return new $class($arguments[0]);
        case 2: return new $class($arguments[0], $arguments[1]);
        case 3: return new $class($arguments[0], $arguments[1], $arguments[2]);
    }
    if (!isset($cache[$class])) {
        $cache[$class] = new ReflectionClass($class);
    }
    return $cache[$class]->newInstanceArgs($arguments);
}    
 5
Author: Dan Lugg, 2013-06-25 13:05:03