ReflectionClass::newInstanceArgs

(PHP 5 >= 5.1.3, PHP 7, PHP 8)

ReflectionClass::newInstanceArgs使用给定参数创建新的类实例

描述

public ReflectionClass::newInstanceArgs(array $args = []): ?object

创建一个新的类实例,给定的参数将传递给类的构造函数。

参数

args

要传递给类构造函数的参数,以 array 形式。

返回值

返回类的新的实例,或在失败时返回 null

错误/异常

如果类的构造函数不是公共的,则会抛出 ReflectionException

如果类没有构造函数,并且 args 参数包含一个或多个参数,则会抛出 ReflectionException

示例

示例 #1 ReflectionClass::newInstanceArgs() 的基本用法

<?php
$class
= new ReflectionClass('ReflectionFunction');
$instance = $class->newInstanceArgs(array('substr'));
var_dump($instance);
?>

上面的示例将输出

object(ReflectionFunction)#2 (1) {
  ["name"]=>
  string(6) "substr"
}

参见

添加注释

用户贡献的注释 8 个注释

kirillsaksin at no-spam dot yandex dot ru
8 年前
正确实例化具有私有构造函数的类的技巧

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

// 输出:
// class TestClass#3 (1) {
// private $property =>
// NULL
// }
//
// ------------------------
//
// class TestClass#3 (1) {
// private $property =>
// string(9) "It works!"
// }

?>
sarfraznawaz2005 at gmail dot com
14 年前
我使用反射类,并检测参数是通过引用传递还是通过值传递
然后使用这些参数成功地初始化/调用方法

<?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);
}
?>
richardcook at gmail dot com
15 年前
如果类的参数中有引用,newInstanceArgs 函数无法调用类的构造函数,因此请谨慎传递参数。

<?php
Foo {
函数
__construct (&$arr) {
$this->arr = &$arr;
}
函数
createInstance () {
$reflectionClass = new ReflectionClass("Bar");

返回
$reflectionClass->newInstanceArgs(数组($this, $this->arr));
}
函数
mod($key, $val) {
$this->arr[$key] = $val;
}
}

Bar {
函数
__construct (&$foo, &$arr) {
$this->foo = &$foo;
$this->arr = &$arr;
}
函数
mod($key, $val) {
$this->arr[$key] = $val;
}
}

$arr = 数组();

$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>";

/*
输出:
警告: 调用 Bar 的构造函数失败 in [code path] on line 31

致命错误: Call to a member function mod() on a non-object in [code path] on line 58
*/
?>
talk at stephensugden dot com
13 年前
这是我在轻量级 IoC 容器中动态实例化对象的方式

<?php

SimpleContainer {

// ...

// 使用提供的参数数组创建对象的实例
受保护的函数 instantiate($name, $args=数组()){
如果(空(
$args))
返回 new
$name();
否则 {
$ref = new ReflectionClass($name);
返回
$ref->newInstanceArgs($args);
}
}
// ...
}
?>

我明确地没有处理用户为无构造函数类传递构造函数参数的情况,因为这应该失败。
dev at yopmail dot com
9 年前
使用 PHP 5.6,我们可以使用 ... (T_ELLIPSIS) 运算符

<?php

Test {
公共函数
__construct($a, $b) {
echo
$a . ' ' . $b;
}
}

$args = 数组(12, 34);
new
Test(... $args); // 显示 "12 34"

?>
sausage at tehsausage dot com
13 年前
烦人的是,即使你为参数传递一个空数组,这也会对没有构造函数的类抛出异常。对于通用编程,你应该避免使用此函数,并使用 call_user_func_array 和 newInstance。
kevinpeno at gmail dot com
14 年前
我误解了这个函数,认为它是在数组形式中设置 Reflection::newInstance() 参数的一种 setter,而不是它本身创建新实例。

此函数等效于 call_user_func_array(),而 Reflection::newInstance() 等效于 call_user_func()
gromit at mailinator dot com
16 年前
请注意,使用空数组调用 newInstanceArgs 方法仍然会调用没有参数的构造函数。如果类没有构造函数,它将生成异常。

在调用此方法之前,你需要检查是否存在构造函数,或者使用 try 和 catch 来处理异常。
To Top