note 89636 added to function.call-user-func

From: 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

« previous php.notes (#152048) next »