They use Refection
How can Symfony prevent PHP from protesting that not enough arguments were fed to the constructor
Reflection allows you to inspect the definition of other "things" in PHP. Among them are Classes their methods, and the arguments for those methods.
<?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));
Outputs:
Type: bar
bool(true)
You can see it here
Then you just use is_a()
or whatever to see if an "input" object has bar
as one of it's ancestors. And as you can see in this simplified example if we had object $bar, we would know that it's perfectly good as an input to our constructor because it returns true.
I should note SO is probably not the right place to ask this, but i could use it in one of my many projects so I didn't mind figuring it out. Also I never used Symphony...
Special thanks to this SO question for the last bit on parsing the type hint:
PHP Reflection - Get Method Parameter Type As String
That said I would have figured the Regx out in about 10 seconds, the export method no so much.
This is the extent of the documentation on it
http://php.net/manual/en/reflectionparameter.export.php
Literally
public static string ReflectionParameter::export ( string $function , string $parameter [, bool $return ] )