Skip to content

Instantly share code, notes, and snippets.

@jsebrech
Last active August 29, 2015 14:19
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 jsebrech/b92d015a605072a1e0bb to your computer and use it in GitHub Desktop.
Save jsebrech/b92d015a605072a1e0bb to your computer and use it in GitHub Desktop.
Anonymous classes in PHP 5.4+
<?php
function new_($items = null, $extra = "") {
while (class_exists($name = "Anon".rand(), FALSE)) {};
$class =
'class '.$name." ".$extra.PHP_EOL.
'{'.PHP_EOL.
' private $_fns = array();'.PHP_EOL.
' public function __construct($items) {'.PHP_EOL.
' foreach ($items ?: array() as $name => $value) {'.PHP_EOL.
' if (is_callable($value)) {'.PHP_EOL.
' $this->_fns[$name] = $value->bindTo($this, $this);'. PHP_EOL.
' } else {'.PHP_EOL.
' $this->$name = $value;'.PHP_EOL.
' }'.PHP_EOL.
' }'.PHP_EOL.
' }'.PHP_EOL;
foreach ($items as $key => $value) {
if (is_callable($value)) {
$class .= ' public function '.$key.'(';
$first = true;
foreach ($params = (new ReflectionFunction($value))->getParameters() as $param) {
if ($first) { $first = false; } else { $class .= ","; };
$hint = $param->getClass() ? $param->getClass()->name : "";
$class .= $hint.' $'.$param->getName();
};
$class .= ') { call_user_func_array($this->_fns["'.$key.'"], func_get_args()); }'.PHP_EOL;
} else {
$class .= ' public $'.$key.';'.PHP_EOL;
}
};
eval($class."}");
return new $name($items);
}
interface Test {
public function setA(DateTime $p);
}
$o = new_([
'a' => new DateTime("2011-12-19"),
'setA' => function(DateTime $p) { $this->a = $p; }
], "implements Test");
$o->setA(new DateTime());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment