ReflectionClass::newInstanceArgs
(PHP 5 >= 5.1.3, PHP 7)
ReflectionClass::newInstanceArgs — Создаёт экземпляр класса с переданными параметрами
Описание
$args
] )Создаёт новый экземпляр класса. Принятые аргументы передаются в конструктор класса.
Возвращаемые значения
Возвращает новый экземпляр класса.
Примеры
Пример #1 Пример использования ReflectionClass::newInstanceArgs()
<?php
$class = new ReflectionClass('ReflectionFunction');
$instance = $class->newInstanceArgs(array('substr'));
var_dump($instance);
?>
Результат выполнения данного примера:
object(ReflectionFunction)#2 (1) { ["name"]=> string(6) "substr" }
Ошибки
Если конструктор не является public (общедоступным), то это приведёт к генерации исключения ReflectionException.
Если конструктор отсутствует, а параметр args
имеет один и более аргументов,
то это приведёт к генерации исключения ReflectionException.
Смотрите также
- ReflectionClass::newInstance() - Создаёт экземпляр класса с переданными аргументами
- ReflectionClass::newInstanceWithoutConstructor() - Создаёт новый экземпляр класса без вызова конструктора
- PHP Руководство
- Функции по категориям
- Индекс функций
- Справочник функций
- Расширения, относящиеся к переменным и типам
- Reflection
- Функция ReflectionClass::__construct() - Создаёт объект класса ReflectionClass
- Функция ReflectionClass::export() - Экспортирует класс
- Функция ReflectionClass::getConstant() - Возвращает определенную константу
- Функция ReflectionClass::getConstants() - Возвращает константы
- Функция ReflectionClass::getConstructor() - Возвращает конструктор класса
- Функция ReflectionClass::getDefaultProperties() - Возвращает свойства по умолчанию
- Функция ReflectionClass::getDocComment() - Возвращает doc-блоки комментариев
- Функция ReflectionClass::getEndLine() - Возвращает номер последней строки
- Функция ReflectionClass::getExtension() - Возвращает объект класса ReflectionExtension для расширения, определенного в классе
- Функция ReflectionClass::getExtensionName() - Возвращает имя расширения, определенного в классе
- Функция ReflectionClass::getFileName() - Возвращает имя файла, в котором объявлен класс
- Функция ReflectionClass::getInterfaceNames() - Возвращает имена интерфейсов
- Функция ReflectionClass::getInterfaces() - Возвращает интерфейсы
- Функция ReflectionClass::getMethod() - Возвращает экземпляр ReflectionMethod для метода класса
- Функция ReflectionClass::getMethods() - Возвращает список методов в виде массива
- Функция ReflectionClass::getModifiers() - Возвращает информацию о модификаторах класса
- Функция ReflectionClass::getName() - Возвращает имя класса
- Функция ReflectionClass::getNamespaceName() - Возвращает название пространства имён
- Функция ReflectionClass::getParentClass() - Возвращает родительский класс
- Функция ReflectionClass::getProperties() - Возвращает свойства
- Функция ReflectionClass::getProperty() - Возвращает экземпляр ReflectionProperty для свойства класса
- Функция ReflectionClass::getShortName() - Возвращает короткое имя
- Функция ReflectionClass::getStartLine() - Возвращает номер начальной строки
- Функция ReflectionClass::getStaticProperties() - Возвращает static свойства
- Функция ReflectionClass::getStaticPropertyValue() - Возвращает значение static свойства
- Функция ReflectionClass::getTraitAliases() - Возвращает массив trait-псевдонимов
- Функция ReflectionClass::getTraitNames() - Возвращает массив trait-имён, задействованных в этом классе
- Функция ReflectionClass::getTraits() - Возвращает массив traits, задействованных в этом классе
- Функция ReflectionClass::hasConstant() - Проверяет, задана ли константа
- Функция ReflectionClass::hasMethod() - Проверяет, задан ли метод
- Функция ReflectionClass::hasProperty() - Проверяет, задано ли свойство
- Функция ReflectionClass::implementsInterface() - Проверяет, реализуется ли интерфейс
- Функция ReflectionClass::inNamespace() - Проверяет, определён ли класс в пространстве имён
- Функция ReflectionClass::isAbstract() - Проверяет, является ли класс абстрактным
- ReflectionClass::isAnonymous
- Функция ReflectionClass::isCloneable() - Проверяет, можно ли клонировать этот класс
- Функция ReflectionClass::isFinal() - Проверяет, является ли класс окончательным (final)
- Функция ReflectionClass::isInstance() - Проверяет, принадлежит ли объект классу
- Функция ReflectionClass::isInstantiable() - Проверяет, можно ли создать экземпляр класса
- Функция ReflectionClass::isInterface() - Проверяет, является ли класс интерфейсом
- Функция ReflectionClass::isInternal() - Проверяет, является ли класс встроенным в расширение или в ядро
- Функция ReflectionClass::isIterateable() - Проверяет, является ли класс итерируемым
- Функция ReflectionClass::isSubclassOf() - Проверяет, является ли класс подклассом
- Функция ReflectionClass::isTrait() - Проверяет, является ли класс trait
- Функция ReflectionClass::isUserDefined() - Проверяет, является ли класс пользовательским
- Функция ReflectionClass::newInstance() - Создаёт экземпляр класса с переданными аргументами
- Функция ReflectionClass::newInstanceArgs() - Создаёт экземпляр класса с переданными параметрами
- Функция ReflectionClass::newInstanceWithoutConstructor() - Создаёт новый экземпляр класса без вызова конструктора
- Функция ReflectionClass::setStaticPropertyValue() - Устанавливает значение static-свойства
- Функция ReflectionClass::__toString() - Возвращает строковое представление объекта класса ReflectionClass
Коментарии
Be aware that calling the method newInstanceArgs with an empty array will still call the constructor with no arguments. If the class has no constructor then it will generate an exception.
You need to check if a constructor exists before calling this method or use try and catch to act on the exception.
the newInstanceArgs function cannot call a class' constructor if it has references in its arguments, so be careful what you pass into it:
<?php
class Foo {
function __construct (&$arr) {
$this->arr = &$arr;
}
function createInstance () {
$reflectionClass = new ReflectionClass("Bar");
return $reflectionClass->newInstanceArgs(array($this, $this->arr));
}
function mod($key, $val) {
$this->arr[$key] = $val;
}
}
class Bar {
function __construct (&$foo, &$arr) {
$this->foo = &$foo;
$this->arr = &$arr;
}
function mod($key, $val) {
$this->arr[$key] = $val;
}
}
$arr = array();
$foo = new Foo($arr);
$arr["x"] = 1;
$foo->mod("y", 2);
$bar = $foo->createInstance();
$bar->mod("z", 3);
echo "<pre>";
print_r($arr);
print_r($foo);
print_r($bar);
echo "</pre>";
/*
Output:
Warning: Invocation of Bar's constructor failed in [code path] on line 31
Fatal error: Call to a member function mod() on a non-object in [code path] on line 58
*/
?>
I misunderstood this function to be a sort of setter of Reflection::newInstance() arguments in an array form rather than a creator of new instances itself.
This function is equivilant to call_user_func_array() while Reflection::newInstance() is equivilant to call_user_func()
I use reflection class and also detect whether arguments are passed by reference or passed by value
and then initiate/call the method successfully with those arguments:
<?php
if (count($args) > 1)
{
if (method_exists($class_name, '__construct') === false)
{
exit("Constructor for the class <strong>$class_name</strong> does not exist, you should not pass arguments to the constructor of this class!");
}
$refMethod = new ReflectionMethod($class_name, '__construct');
$params = $refMethod->getParameters();
$re_args = array();
foreach($params as $key => $param)
{
if ($param->isPassedByReference())
{
$re_args[$key] = &$args[$key];
}
else
{
$re_args[$key] = $args[$key];
}
}
$refClass = new ReflectionClass($class_name);
$class_instance = $refClass->newInstanceArgs((array) $re_args);
}
?>
Annoyingly, this will throw an exception for classes with no constructor even if you pass an empty array for the arguments. For generic programming you should avoid this function and use call_user_func_array with newInstance.
This is the way I dynamically instantiate objects in my lightweight IoC container
<?php
class SimpleContainer {
// ...
// Creates an instance of an object with the provided array of arguments
protected function instantiate($name, $args=array()){
if(empty($args))
return new $name();
else {
$ref = new ReflectionClass($name);
return $ref->newInstanceArgs($args);
}
}
// ...
}
?>
I explicitly do NOT handle the case where a user passes constructor arguments for a constructor-less class, as I this SHOULD fail.
With PHP 5.6, we can use the ... (T_ELLIPSIS) operator
<?php
class Test {
public function __construct($a, $b) {
echo $a . ' ' . $b;
}
}
$args = array(12, 34);
new Test(... $args); // Displays "12 34"
?>
Hack to properly instantiate class with private constructor:
<?php
class TestClass
{
private $property;
private function __construct($argument)
{
$this->property = $argument;
}
}
$ref = new ReflectionClass(TestClass::class);
$instance = $ref->newInstanceWithoutConstructor();
var_dump($instance);
echo PHP_EOL . '------------------------' . PHP_EOL . PHP_EOL;
$constructor = $ref->getConstructor();
$constructor->setAccessible(true);
$constructor->invokeArgs($instance, ['It works!']);
var_dump($instance);
// Output:
// class TestClass#3 (1) {
// private $property =>
// NULL
// }
//
// ------------------------
//
// class TestClass#3 (1) {
// private $property =>
// string(9) "It works!"
// }
?>