<?php
class callbacks{
protected $queue=[];
//fire the queue
public function __invoke($args){
$size=count($this->queue);
for ($i=0;$i<$size;$i++)
call_user_func_array($this->queue[$i],$args);
}
public function add(callable $func){
$size=count($this->queue);
$this->queue[$size]=$func;
}
}
trait dynamicMethods{
protected $methods=[];
final function __call($method, $args){
if (!isset($this->methods[$method]))
throw new Exception("Invalid method call: $method. ");
$this->methods[$method]($args);
}
final function __set($name,$value){
if (isset($this->methods[$name]))
throw new Exception("$name is declared as a dynamicMethod. ");
$this->$name=$value;
}
public function bind($name,callable $func){
if (!is_string($name))
throw new Exception("Method name must be a string. ");
if (isset($this->$name))
throw new Exception(__CLASS__."->$name is already declared. ");
if (!isset($this->methods[$name]))
$this->methods[$name]=new callbacks;
$this->methods[$name]->add($func);
}
}
class alfa{
use dynamicMethods;
}
$a=new alfa;
try{
//Creates a new method named 'hola'
$a->bind('hola', function ($mundo){
echo "hola $mundo";
});
//Calls hola method.
$a->hola('mundo.<br/>');
//Extend the 'hola' method
$a->bind('hola',function ($mundo){
echo "adios $mundo";
});
$a->hola('mundo cruel.<br/>');
$a->undeclared();//throws exception.
}catch(Exception $e){
echo $e->getMessage();
}
echo $a->hola;//empty response. throws PHP_NOTICE
?>