# Dependency resolver in PHP

I wrote a simple Dependency Resolver in PHP that I'm hoping to get some input on.

The main problem that gave me some trouble was when it had to resolve typed arguments ( like type hinting a constructor argument with an interface, I don't remember exactly what they call it ). The only work around was to let the DependencyResolver know about such dependencies that are not directly resolvable (instantiable).

Note: The class name of this Dependency Resolver is ObjectManager

// dependencies.php
// this is where I define all my dependencies in case if they are not directly instantiable
$deps = array( 'DependentClass' => array( 'depclass' => 'DependencyClass' ) ); ObjectManager::getInstance()->setDependencies($deps);


ObjectManager uses singleton pattern so I can use the same object throughout the flow

// mainfile.php
use DependencyClassInterface;
use AnotherClass;
Class DependentClass {
protected $depClass; public function __construct(DependencyClassInterface$depclass, AnotherClass $another) {$this->depClass = $depClass; } public function doSomething() { echo "Something"; } } ObjectManager::getInstance() ->get('DependentClass') ->doSomething();  And finally the implementation of Dependency Resolver. <?php class ObjectManager { protected$dependencies;

protected static $omInstance; public static function getInstance() { if (!self::$omInstance) {
self::$omInstance = new ObjectManager(); } return self::$omInstance;
}

public function setDependencies(array $dependencies) {$this->dependencies = $dependencies; } public function getDependencies() { return$this->dependencies;
}

public function get($class) {$finalizedParams = array();
$deps = array(); // check if deps are defined if (array_key_exists($class, $this->dependencies)) {$deps = $this->dependencies[$class];
}

$reflector = new ReflectionClass($class);

if (!$reflector->isInstantiable()) { throw new Exception("Class {$class} is not instantiable");
}

$constructor =$reflector->getConstructor();
if ($constructor == null) { return$reflector->newInstance();
}

$parameters =$constructor->getParameters();

foreach ($parameters as$key => $parameter) {$parameterType = $this->getParameterType($parameter);
$parameterName =$parameter->getName();

if ($parameterType == null) { if ($parameter->isDefaultValueAvailable()) {
$finalizedParams[$key] = $parameter->getDefaultValue(); } else { throw new Exception(" Failed resolving argument (dependency) \"$parameterName\" for class $class. Not directly instantiatable. No default value specified."); } continue; }$classReflection = new ReflectionClass($parameterType); // if dep is directly instantiable; save and continue if ($classReflection->isInstantiable()) {
$finalizedParams[$key] = $classReflection->newInstance(); continue; } // if defined in di.php if (array_key_exists($parameterName, $deps)) {$argName = $deps[$parameterName];
$finalizedParams[$key] = ObjectManager::getInstance()->get($argName); continue; } } return$reflector->newInstanceArgs($finalizedParams); } protected function getParameterType(ReflectionParameter$parameter)
{
$export = ReflectionParameter::export( array($parameter->getDeclaringClass()->name,
$parameter->getDeclaringFunction()->name, ),$parameter->name,
true
);
return preg_match('/[>] ([A-z]+) /', $export,$matches)
? \$matches[1] : null;
}
}


Hopefully, you got the idea. It might be an overkill to resolve dependencies this way, but I like the option of an Object Manager being able to do that.