Skip to content

Instantly share code, notes, and snippets.

@timdev
Last active June 19, 2016 00:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timdev/bd4a1bedb7ed0a1c9838d234c2222b9b to your computer and use it in GitHub Desktop.
Save timdev/bd4a1bedb7ed0a1c9838d234c2222b9b to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace App\Action;
use Interop\Container\ContainerInterface;
use ReflectionClass;
use Zend\ServiceManager\Factory\AbstractFactoryInterface;
/**
* Abstract factory that uses reflection to determine the requested action's constructor argument types
* and fetch them from the container.
*
* Inspired by: https://xtreamwayz.com/blog/2015-12-30-psr7-abstract-action-factory-one-for-all
*/
class AbstractActionFactory implements AbstractFactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
// Construct a new ReflectionClass object for the requested action
$reflection = new ReflectionClass($requestedName);
// Get the constructor
$constructor = $reflection->getConstructor();
if (is_null($constructor)) {
// There is no constructor, just return a new class
return new $requestedName;
}
// Get the parameters
$parameters = $constructor->getParameters();
$dependencies = [];
foreach ($parameters as $parameter) {
// Get the parameter class
$class = $parameter->getClass();
// Get the class from the container
$dependencies[] = $container->get($class->getName());
}
// Return the requested class and inject its dependencies
return $reflection->newInstanceArgs($dependencies);
}
public function canCreate(ContainerInterface $container, $requestedName)
{
// Only accept Action classes
if (substr($requestedName, -6) == 'Action') {
return true;
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment