Symfony 的自动装配在幕后是如何工作的?
How does Symfony's autowiring work behind the scenes?
这不是关于说明(文档就足够了),而是关于事情如何运作的问题。
Symfony 4's autowiring system 允许我们通过简单的类型提示自动注入服务
use App\Util\Rot13Transformer;
class TwitterClient
{
public function __construct(Rot13Transformer $transformer)
{
$this->transformer = $transformer;
}
}
为了更深入地了解 PHP,我查看了 symfony-bundle 源代码,但找不到 "magic" 发生的位置。
Symfony 如何防止 PHP 抗议没有足够的参数被提供给构造函数(或任何使用自动装配的函数)?
他们使用 Refection
How can Symfony prevent PHP from protesting that not enough arguments were fed to the constructor
反射允许您检查 PHP 中其他 "things" 的定义。其中包括 类 它们的方法,以及这些方法的参数。
<?php
class bar
{
//just a placeholder class
};
$bar = new bar(); //instance of bar
//class to inspect
class foo
{
public function __construct( bar $bar)
{
//do something fancy with $bar
}
}
//get the Reflection of the constructor from foo
$Method = new ReflectionMethod('foo', '__construct');
//get the parameters ( I call them arguments)
$Args = $Method->getParameters();
//get the first argument
$Arg = reset($Args);
//export the argument definition
$export = ReflectionParameter::export(
array(
$Arg->getDeclaringClass()->name,
$Arg->getDeclaringFunction()->name
),
$Arg->name,
true
);
//parse it for the typehint
$type = preg_replace('/.*?(\w+)\s+$'.$Arg->name.'.*/', '\1', $export);
echo "\nType: $type\n\n";
var_dump(is_a($bar, $type));
输出:
Type: bar
bool(true)
可以看到here
然后您只需使用 is_a()
或其他任何东西来查看 "input" 对象是否具有 bar
作为其祖先之一。正如您在这个简化示例中看到的那样,如果我们有对象 $bar,我们就会知道它非常适合作为构造函数的输入,因为它 returns true.
我应该注意,SO 可能不是问这个问题的合适地方,但我可以在我的许多项目之一中使用它,所以我不介意弄清楚它。我也从未使用过 Symphony ...
特别感谢这个关于解析类型提示的最后一点的 SO 问题:
PHP Reflection - Get Method Parameter Type As String
也就是说我会在大约 10 秒内弄清楚 Regx,导出方法就没那么多了。
这是关于它的文档的范围
http://php.net/manual/en/reflectionparameter.export.php
字面意思
public static string ReflectionParameter::export ( string $function , string $parameter [, bool $return ] )
正如其他人提到的,他们使用 Reflection. If you want to see how exactly Symfony is doing this, start with autowire()
method here
这不是关于说明(文档就足够了),而是关于事情如何运作的问题。
Symfony 4's autowiring system 允许我们通过简单的类型提示自动注入服务
use App\Util\Rot13Transformer;
class TwitterClient
{
public function __construct(Rot13Transformer $transformer)
{
$this->transformer = $transformer;
}
}
为了更深入地了解 PHP,我查看了 symfony-bundle 源代码,但找不到 "magic" 发生的位置。
Symfony 如何防止 PHP 抗议没有足够的参数被提供给构造函数(或任何使用自动装配的函数)?
他们使用 Refection
How can Symfony prevent PHP from protesting that not enough arguments were fed to the constructor
反射允许您检查 PHP 中其他 "things" 的定义。其中包括 类 它们的方法,以及这些方法的参数。
<?php
class bar
{
//just a placeholder class
};
$bar = new bar(); //instance of bar
//class to inspect
class foo
{
public function __construct( bar $bar)
{
//do something fancy with $bar
}
}
//get the Reflection of the constructor from foo
$Method = new ReflectionMethod('foo', '__construct');
//get the parameters ( I call them arguments)
$Args = $Method->getParameters();
//get the first argument
$Arg = reset($Args);
//export the argument definition
$export = ReflectionParameter::export(
array(
$Arg->getDeclaringClass()->name,
$Arg->getDeclaringFunction()->name
),
$Arg->name,
true
);
//parse it for the typehint
$type = preg_replace('/.*?(\w+)\s+$'.$Arg->name.'.*/', '\1', $export);
echo "\nType: $type\n\n";
var_dump(is_a($bar, $type));
输出:
Type: bar
bool(true)
可以看到here
然后您只需使用 is_a()
或其他任何东西来查看 "input" 对象是否具有 bar
作为其祖先之一。正如您在这个简化示例中看到的那样,如果我们有对象 $bar,我们就会知道它非常适合作为构造函数的输入,因为它 returns true.
我应该注意,SO 可能不是问这个问题的合适地方,但我可以在我的许多项目之一中使用它,所以我不介意弄清楚它。我也从未使用过 Symphony ... 特别感谢这个关于解析类型提示的最后一点的 SO 问题:
PHP Reflection - Get Method Parameter Type As String
也就是说我会在大约 10 秒内弄清楚 Regx,导出方法就没那么多了。
这是关于它的文档的范围
http://php.net/manual/en/reflectionparameter.export.php
字面意思
public static string ReflectionParameter::export ( string $function , string $parameter [, bool $return ] )
正如其他人提到的,他们使用 Reflection. If you want to see how exactly Symfony is doing this, start with autowire()
method here