Skip to content

Instantly share code, notes, and snippets.

@pirosikick
Created April 3, 2013 16:38
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 pirosikick/5302906 to your computer and use it in GitHub Desktop.
Save pirosikick/5302906 to your computer and use it in GitHub Desktop.
PHP5.4のClosure::bindToを使ってJavaScriptのクロージャ的なものを作った。
<?php
function context(Closure $function)
{
Context::create($function)->run();
}
class Context
{
private static $_chain = [];
public static function create(Closure $function)
{
$context = new self($function);
array_push(static::$_chain, $context);
return $context;
}
public static function get($index)
{
return isset(self::$_chain[$index]) ? self::$_chain[$index] : false;
}
public static function search(self $context)
{
return array_search($context, self::$_chain, true);
}
private $_values;
private $_function;
private function __construct(Closure $function)
{
$this->_values = [];
$this->_function = $function->bindTo($this);
}
public function run()
{
$function = $this->_function;
$function();
}
private function _parent()
{
$index = self::search($this);
if ($index) {
return self::get($index - 1);
}
return false;
}
public function __set($name, $value)
{
$this->_values[$name] = $value;
}
public function __get($name)
{
if (isset($this->_values[$name])) {
return $this->_values[$name];
}
if ( ! ($parent = $this->_parent())) {
return null;
}
return $parent->__get($name);
}
}
<?php
require 'context.php';
context(function () {
$this->hoge = "outer hoge";
$this->fuga = "outer fuga";
context(function () {
$this->fuga = "inner fuga";
echo $this->hoge, "\n"; // display "outer hoge"
echo $this->fuga, "\n"; // display "inner fuga". overwrite by inner $this->fuga
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment