2013-06-25 5 views
3

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

$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 дважды. Итак, есть ли способ использовать аргументы вызываемой функции для создания нового экземпляра, который будет проходить через функцию или classname во время создания экземпляра?

+0

'новый $ класс, или' новый класс, ' –

+1

@YogeshSuthar Это будет работать на * известный * число аргументов; Я думаю, проблема здесь в том, что аргументы неизвестны. – Dan

+0

@Bracketworks, что правильно – topherg

ответ

4

Если вы не против того, чтобы с помощью отражения: ReflectionClass::newInstanceArgs

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

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


На основе обсуждения, я просто о внесении изменений гипотетического решения с 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); 
}  
+0

Ну, его определенно медленнее, но поскольку он используется только время от времени, его не так уж плохо – topherg

+0

@cgoddard Точно; если это интегральный компонент, используемый тысячами раз, то, возможно, это не самое быстрое решение, но опять же, если это так, то это может быть признаком того, что вы делаете то, что вам не нужно;) – Dan

+0

Вправо, я реализовал эту функцию, но я включил метод проверки количества переданных аргументов, если он не используется, он просто использует 'new $ class', если 1 аргумент, то' new $ class (func_get_arg (0)) ', если 2 аргумента, то 'new $ class (func_get_arg (0), func_get_arg (1))', после чего он возвращается к 'ReflectionClass'. Экономит много времени обработки – topherg