Last active
March 6, 2018 12:29
-
-
Save ngyuki/7c6648cfc769f8143309 to your computer and use it in GitHub Desktop.
Example of uopz di experimental
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
interface SayInterface | |
{ | |
public function say(); | |
} | |
class Ore implements SayInterface | |
{ | |
public function say() | |
{ | |
return "oreore"; | |
} | |
} | |
class Are implements SayInterface | |
{ | |
private $name; | |
/** | |
* @var SayInterface | |
*/ | |
private $say; | |
public function __construct($name) | |
{ | |
$this->name = $name; | |
} | |
public function setSay(SayInterface $say) | |
{ | |
$this->say = $say; | |
} | |
public function say() | |
{ | |
return "$this->name and {$this->say->say()}"; | |
} | |
} | |
class Sore implements SayInterface | |
{ | |
private $name; | |
public function __construct($name) | |
{ | |
$this->name = $name; | |
} | |
public function say() | |
{ | |
return $this->name; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once __DIR__ . '/uopz-di.php'; | |
require_once __DIR__ . '/uopz-di-classes.php'; | |
/// | |
echo (new Ore())->say() . PHP_EOL; | |
// oreore | |
/// | |
Di::register([ | |
'Ore' => [ | |
'class' => 'Are', | |
'params' => ['are'], | |
'setters' => [ | |
'setSay' => [Di::lazyNew('Sore')], | |
], | |
], | |
'Sore' => [ | |
'class' => 'Sore', | |
'params' => ['sore'], | |
], | |
]); | |
echo (new Ore())->say() . PHP_EOL; | |
// are and sore | |
/// | |
Di::register([]); | |
echo (new Ore())->say() . PHP_EOL; | |
// oreore | |
/// | |
Di::register([ | |
'Ore' => [ | |
'class' => 'Sore', | |
'params' => ['dare?'], | |
], | |
]); | |
echo (new Ore())->say() . PHP_EOL; | |
// dare? | |
/// | |
echo get_class(new Ore()) . PHP_EOL; | |
// uopz.Ore.Sore |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Di | |
{ | |
private static $instance; | |
private $config; | |
private $reflection; | |
public static function register(array $config) | |
{ | |
if (isset(self::$instance) == false) { | |
self::$instance = new self(); | |
} | |
self::$instance->config = $config; | |
} | |
public static function lazyNew($class) | |
{ | |
return new DiLazyNew($class); | |
} | |
protected function __construct() | |
{ | |
$this->reflection = new \ReflectionClass('ReflectionClass'); | |
uopz_overload(ZEND_NEW, function (&$class) { | |
$this->overload($class); | |
}); | |
} | |
private function overload(&$class) | |
{ | |
if (isset($this->config[$class]) == false) { | |
return; | |
} | |
$cfg = $this->config[$class]; | |
$orig = $class; | |
$base = isset($cfg['class']) ? $cfg['class'] : $class; | |
$class = "uopz.$orig.$base"; | |
if (class_exists($class, false)) { | |
return; | |
} | |
$construct = function ($orig, $obj, $scope) { | |
$this->construct($orig, $obj, $scope); | |
}; | |
uopz_compose($class, [$base], [ | |
'__construct' => function () use ($construct) { | |
list (, $class) = explode('.', get_class($this)); | |
$construct($class, $this, function ($method, $args) { | |
call_user_func_array(['parent', $method], $args); | |
}); | |
} | |
]); | |
} | |
private function construct($class, $obj, $scope) | |
{ | |
$cfg = isset($this->config[$class]) ? $this->config[$class]: []; | |
$params = isset($cfg['params']) ? $cfg['params'] : []; | |
$setters = isset($cfg['setters']) ? $cfg['setters'] : []; | |
if (count($params) || method_exists(get_parent_class($obj), '__construct')) { | |
$scope('__construct', $this->createArgs($params)); | |
} | |
foreach ($setters as $methodName => $methodParams) { | |
$scope($methodName, $this->createArgs($methodParams)); | |
} | |
} | |
private function newInstance($class) | |
{ | |
$cfg = isset($this->config[$class]) ? $this->config[$class]: []; | |
$class = isset($cfg['class']) ? $cfg['class'] : $class; | |
$params = isset($cfg['params']) ? $cfg['params'] : []; | |
$setters = isset($cfg['setters']) ? $cfg['setters'] : []; | |
/* @var $reflection \ReflectionClass */ | |
$reflection = $this->reflection->newInstance($class); | |
$obj = $reflection->newInstanceArgs($this->createArgs($params)); | |
foreach ($setters as $methodName => $methodParams) { | |
$method = $reflection->getMethod($methodName); | |
$method->setAccessible(true); | |
$method->invokeArgs($obj, $this->createArgs($methodParams)); | |
} | |
return $obj; | |
} | |
private function createArgs($params) | |
{ | |
$args = []; | |
foreach ($params as $val) { | |
if ($val instanceof DiLazyNew) { | |
$args[] = $this->newInstance($val->getClass()); | |
} else { | |
$args[] = $val; | |
} | |
} | |
return $args; | |
} | |
} | |
class DiLazyNew | |
{ | |
private $class; | |
public function __construct($class) | |
{ | |
$this->class = $class; | |
} | |
public function getClass() | |
{ | |
return $this->class; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment