As I am working on a piece of code that needs the decorator pattern, I wanted to make it really simple to use by handling the __call magic method.
As a matter of fact, when I use the decorator pattern (here, to add a singleton, add some methods and forbid some others) some of the methods have no need to be overridden. So using __call is a good way to simplify the code.
My situation raises when some methods need arguments passed by reference.
To give an example, I created a XPDO class that decores PDO. It is not my former case but I can’t show that one.
<?php
class XPDO{
private static $dbInstance=null;
private $pdoConnexion;
static function getInstance(){
if(self::$dbInstance ==null){
self::$dbInstance = new XPDO(/*tes params*/);
}
return self::$dbInstance;
}
private function __clone(){
}
private function __construct(){
$this->pdoConnexion = new PDO('mysql:localhost;dbname=blog','root','');
}
/**
*on possède toutes les méthodes de PDO mais en plus certaines qui nous sont propres ou qui
*surchargent/limitent celles de PDO si telles qu'elles sont implémentées dans PDO, on ne les aime pas.
*/
public function __call($method, $args){
if(is_callable(array($this,$method))){
return call_user_func_array(array($this,$method),$args);
}else if(is_callable(array($this->pdoConnexion,$method))){
return call_user_func_array(array($this->pdoConnexion,$method),$args);
}
}
/**
*
*@param string $query the query we want to add the where
*@param string $param name of the column
*@return string the identifier that we would use to bind a value
*/
private function addAndWhere(&$query,$param){
$uid = rand(1,100000);
if(strpos($query,'WHERE')){
$query.= ' AND '.$param.'=:'.$param.$uid;
}else{
$query.= ' WHERE '.$param.'=:'.$param.$uid;
}
return $param.$uid;
}
}
$pdo = XPDO::getInstance();
$query = 'SELECT * FROM sometable';
var_dump($pdo->addAndWhere($query,'smth'));
var_dump($query);
this would fail because addAndWhere expects a reference and a copy is given.
This code can be easily fixed by passing addAndWhere to public, and it has sense. Here it is just an example. Now imagine it is PDO that needs a reference and you got my point.
From php manual in Overloading page
there are no clean solutions.
You can do only
but this is DEPRECATED since 5.3, with relative warning.