Skip to content

Instantly share code, notes, and snippets.

@nikic
Created June 30, 2012 23:58
Show Gist options
  • Save nikic/3026099 to your computer and use it in GitHub Desktop.
Save nikic/3026099 to your computer and use it in GitHub Desktop.
Something I found in my codebase...
<?php
class Registry implements ArrayAccess {
public $this = null;
protected $impls = array();
protected $curImpl = 0;
public function &__get($key) {
if (isset($this->__onUndefinedProperty)) {
$_ = $this->__onUndefinedProperty($key);
return $_;
}
return $this->$key = new self;
}
public function __call($key, $args) {
if (!isset($this->$key)) {
if (isset($this->__onUndefinedMethod)) {
return $this->__onUndefinedMethod($key, $args);
}
throw new BadMethodCallException(sprintf('Method "%s" does not exist.', $key));
}
if (!is_callable($this->$key)) {
throw new BadMethodCallException(sprintf('Method "%s" is not callable.', $key));
}
$µThis =& µ()->this;
$prevThis = $µThis;
$µThis = $this;
$return = call_user_func_array($this->$key, $args);
$µThis = $prevThis;
return $return;
}
public function __invoke() {
$backtrace = debug_backtrace();
foreach ($backtrace as $info) {
if (isset($info['class'], $info['type'], $info['function'], $info['args'], $info['args'][0])
&& 'Registry' == $info['class'] && '->' == $info['type'] && '__call' == $info['function']
&& 'this' != $info['args'][0]
) {
return call_user_func_array($this->{$info['args'][0]}, func_get_args());
}
}
}
public function offsetSet($key, $impl) {
if (!is_array($impl)) {
throw new InvalidArgumentException('To change the implementation you must pass an array.');
}
if (null === $key) {
if (get_object_vars($this) != array('this' => null, 'impl' => array(), 'curImpl' => 0)) {
$this->impls[$this->curImpl++] = clone $this;
}
$queuedKeys = array();
foreach ($impl as $key => $value) {
if (!is_string($key)) {
$queuedKeys[] = $value;
} else {
if (!empty($queuedKeys)) {
foreach ($queuedKeys as $queuedKey) {
$this->$queuedKey = $value;
}
$queuedKeys = array();
}
$this->$key = $value;
}
}
} else {
throw new Exception('Not implemented');
}
}
public function offsetGet($key) {
return $this->curImpl === $key ? $this : $this->impls[$this->toImplKey($key)];
}
public function offsetExists($key) {
return $this->curImpl === $key || isset($this->impls[$this->toImplKey($key)]);
}
public function offsetUnset($key) {
throw new Exception('Not implemented');
}
protected function toImplKey($key) {
if (!is_int($key)) {
throw new InvalidArgumentException(sprintf('Implementation key "%s" must be an integer.', $key));
}
if ($key < 0) {
$key = $this->curImpl + $key;
}
return $key;
}
}
function µ() {
static $registry = null;
if (null === $registry) {
$registry = new Registry;
}
return $registry;
}
µ()->__onUndefinedProperty = function&($key) {
µ()->this->$key = new Registry;
is_file($file = __DIR__ . '/lib/' . $key . '.php') && require_once $file;
return µ()->this->$key;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment