note 89636 added to function.call-user-func
| From: | edgar dot klerks at gmail dot com | Date: | Tue, 17 Mar 2009 15:18:48 +0000 |
| Subject: | note 89636 added to function.call-user-func | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-152048@lists.php.net to get a copy of this message | ||
An entirely OO solution to add dynamicly methods to classes, I used in a project:
<?php
class ProductPart {
protected $data;
protected $plugins = array();
function __construct($data){
$this->data = $data;
}
public function register(ProductPlugin $plugin){
if(!in_array($plugin, $this->plugins)){
$this->plugins[$plugin->toString()] = $plugin;
} else {
throw new Exception('Function allready defined');
}
}
public function unregister(ProductPlugin $plugin){
if(isset($this->plugins[$plugin->toString()])){
unset($this->plugins[$plugin->toString()]);
} else {
throw new Exception('No such function');
}
}
protected function __call($method, $args) {
if(isset($this->plugins[$method])){
array_unshift(&$args, $this->data);
array_unshift(&$args, $this);
return $this->plugins[$method]->run($args[0], $args[1], $args[2]);
} else {
throw new Exception('No such function');
}
}
} ?>
I simplified the class somewhat for clearity.
With this class, you can dynamicly add and remove classes by calling register or unregister.
Register will store the object in an associative array by calling toString (as defined by
ProductPlugin) and saving the method under the returned string in the array. (In this case the name
of the method the class adds.)
When a method is called, which isn't standard in the object, _call will lookup the called
method in the array. If found, __call run the method of the plugin with the provided arguments. I
restricted the user provided argument to 1, because I want to force the user to use associative
arrays.
Because I chose an array to store my classes, removing a function is quite simple. However the
unregister function isn't optimal, I better pass a string instead of a plugin object. I
didn't test it yet on performance.
The ProductPlugin class:
<?php
abstract class ProductPlugin {
protected $name = null;
abstract public function run($obj, $data, $args);
public function __construct($data = null) {
if($this->name === null){
throw new Exception('Name must be defined');
}
$this->init($data);
}
protected function init($data){
}
public function toString(){
return $this->name;
}
}
?>
And at last some demonstration code:
<?php
$bla = new ProductPart(array('HelloWorld' => 'Hello world'));
$hello = new helloPlugin();
$bla->register($hello);
$bla->HelloWorld();
$bla->unregister($hello);
$bla->HelloWorld();
?>
----
Server IP: 83.137.20.135
Probable Submitter: 92.65.202.85
----
Manual Page -- http://www.php.net/manual/en/function.call-user-func.php
Edit -- https://master.php.net/note/edit/89636
Del: integrated -- https://master.php.net/note/delete/89636/integrated
Del: useless -- https://master.php.net/note/delete/89636/useless
Del: bad code -- https://master.php.net/note/delete/89636/bad+code
Del: spam -- https://master.php.net/note/delete/89636/spam
Del: non-english -- https://master.php.net/note/delete/89636/non-english
Del: in docs -- https://master.php.net/note/delete/89636/in+docs
Del: other reasons-- https://master.php.net/note/delete/89636
Reject -- https://master.php.net/note/reject/89636
Search -- https://master.php.net/manage/user-notes.php