Search code examples
phpparametersconstructordependency-injectionconstructor-injection

Get construction parameter dependency from php construction function


Using the php ReflectionClass I can find which parameters I have to inject in a class constructor to create a new instance.

$class = new ReflectionClass($this->someClass);
$constructor = $class->getConstructor();
$parameters = $constructor->getParameters();

Is there also a way to get the dependencies of those parameters. So if the constructor of someClass looks like this:

public function __construct(Dependency $dependency){
    $this->dependency = $dependency;
}

Can I somehow get the class Dependency from the constructor function?


Solution

  • ReflectionMethod::getParameters returns an array of ReflectionParameter objects. ReflectionParameters have an method called getClass that will return information about the typehint of the param.

    Example:

    <?php
    interface Y { }
    
    class X
    {
        public function __construct(Y $x, $y=null)
        {
            
        }
    }
    
    $ref = new \ReflectionClass('X');
    
    $c = $ref->getConstructor();
    foreach ($c->getParameters() as $p) {
        var_dump($p->getClass());
    }
    

    Outputs:

    class ReflectionClass#5 (1) {
      public $name =>
      string(1) "Y"
    }
    NULL
    

    Silex's ControllerResolver has a really nice example of how you might use this:

    <?php
    // $params is an array of ReflectionParameter instances
    protected function doGetArguments(Request $request, $controller, array $parameters)
    {
        foreach ($parameters as $param) {
            // check to see if there's a class and if there is, see if the app property
            // is the same type. If so, set the attribute on the request
            if ($param->getClass() && $param->getClass()->isInstance($this->app)) {
                $request->attributes->set($param->getName(), $this->app);
    
                break;
            }
        }
    
        return parent::doGetArguments($request, $controller, $parameters);
    }