Skip to content

Instantly share code, notes, and snippets.

@AmyStephen
Created May 17, 2013 05:35
Show Gist options
  • Save AmyStephen/5597142 to your computer and use it in GitHub Desktop.
Save AmyStephen/5597142 to your computer and use it in GitHub Desktop.
Uses Reflection to extract Constructor Parameters
<?php
/**
* Standard Dependency Injector
*
* @package Molajo
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @copyright 2013 Amy Stephen. All rights reserved.
*/
namespace Molajo\IoC\Handler;
use Exception;
use ReflectionClass;
use ReflectionParameter;
use Molajo\IoC\Exception\InjectorException;
use Molajo\IoC\Handler\AbstractInjector;
use Molajo\IoC\Api\InjectorInterface;
/**
* Standard Dependency Injector
*
* @author Amy Stephen
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @copyright 2013 Amy Stephen. All rights reserved.
* @since 1.0
*/
class StandardInjector extends AbstractInjector implements InjectorInterface
{
/**
* Constructor
*
* @param $options
*
* @since 1.0
*/
public function __construct($options)
{
$this->service_namespace = $options['service'];
$this->store_instance_indicator = true;
parent::__construct($options);
}
/**
* Instantiate Class
*
* @param bool $create_static
*
* @return object
* @since 1.0
* @throws InjectorException
*/
public function instantiate($create_static = false)
{
$options = array();
$reflect = new ReflectionClass($this->service_namespace);
$parameters = $reflect->getMethod('__construct')->getParameters();
foreach ($parameters as $parameter) {
if (isset($this->options[$parameter->name])) {
$options[$parameter->name] = $this->options[$parameter->name];
}
}
try {
$this->service_instance = new $this->service_namespace(implode(',', $options));
} catch (Exception $e) {
throw new InjectorException
('IoC: Injector Instance Failed for ' . $this->service_namespace
. ' failed.' . $e->getMessage());
}
return $this;
}
}
@AmyStephen
Copy link
Author

I am using Reflection to determine the parameter names in the Class Constructor.

Then, I match that list to the $this->options array passed into the IoCC.

How do I pass the values into the Class Construction?

Above, on line 56, I implode the array, and the values are correctly displayed, separated by a column, but it ends up being the first parameter.

@jwpage
Copy link

jwpage commented May 17, 2013

On L56, I think you're looking for call_user_func_array(array($this->service_namespace, '__construct'), $options) instead.

Update: actually, I don't think you can use call_user_func_array with a __construct argument, but you can use reflection instead: $reflect->newInstanceArgs($options)

@AmyStephen
Copy link
Author

I tried the call_user_func_array - but I did not try newInstanceArgs (nor had I heard about it)

I'll read up tomorrow on this http://php.net/manual/en/reflectionclass.newinstanceargs.php

Changed 65 to:

 $this->service_instance = new $this->service_namespace($reflect->newInstanceArgs($options))

But - obviously that was not what you meant.

Thanks for the pointer!

@AmyStephen
Copy link
Author

So, you mean quite literally - do just what you said! /me gets ready to go to sleep!

THANK YOU! Awesome!

$this->service_instance = $reflect->newInstanceArgs($options);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment