Skip to content

Instantly share code, notes, and snippets.

@neonxp
Created December 18, 2012 13:27
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 neonxp/4327975 to your computer and use it in GitHub Desktop.
Save neonxp/4327975 to your computer and use it in GitHub Desktop.
<?php
/**
* Simple DI container for projects with legacy code without PSR-0 classes and namespaces
* Usage:
* require_once('DIC/Container.php');
* $c = new Container();
* $c->get('example')->method();
*/
class Container {
private $services = null;
private $path = null;
public function __construct($serviceFile = 'services.json', $path = null) {
if (!file_exists($serviceFile)) {
throw new Exception("No such service definition file: $serviceFile");
}
$json = file_get_contents($serviceFile);
$this->services = json_decode($json, true);
if (is_null($path)) {
$this->path = __DIR__ . '/../';
}
}
public function get($service) {
if (!isset($this->services[$service])) {
throw new Exception("No such service: " . $service);
}
$serviceDefinition = $this->services[$service];
if (isset($serviceDefinition['file'])) {
if (file_exists( . $serviceDefinition['file'])) {
require_once($this->path . $serviceDefinition['file']);
} else {
throw new Exception("No such file: " . $this->path . $serviceDefinition['file']);
}
} else {
throw new Exception("File section required for $service");
}
$class = $serviceDefinition['class'];
$instance = null;
if (class_exists($class)) {
if (isset($serviceDefinition['arguments'])) {
$refMethod = new ReflectionMethod($class, '__construct');
$params = $refMethod->getParameters();
$re_args = array();
foreach($params as $key=>$param) {
if (isset($param->name)) {
$re_args[$key] = $this->parseArgument($serviceDefinition['arguments'][$param->name]);
}
}
$refClass = new ReflectionClass($class);
$instance = $refClass->newInstanceArgs((array) $re_args);
} else {
$instance = new $class();
}
} else {
throw new Exception("Class $class not found");
}
if (is_null($instance)) {
throw new Exception("Class $class not instanced");
}
if ($serviceDefinition['calls']) {
foreach($serviceDefinition['calls'] as $method => $arguments) {
if (method_exists($instance, $method)) {
$re_args = array();
if (!empty($arguments)) {
foreach ($arguments as $argument) {
$re_args[] = $this->parseArgument($argument);
}
}
call_user_func_array(array($instance, $method), $re_args);
} else {
throw new Exception("No such method $method on $class");
}
}
}
return $instance;
}
private function parseArgument($argument) {
if (substr($argument,0,1) == '@') {
$service = substr($argument,1);
return $this->get($service);
} else {
return $argument;
}
}
}
{
"example": {
"file" : "example/example.php",
"class" : "exampleClass",
"arguments" : {
"client" : "@fooService"
}
},
"fooService": {
"file" : "foo/bar.php",
"class" : "bar",
"calls" : {
"init": {
"param1" : "test... test...",
"param2" : 123456
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment