当我正在处理需要装饰器模式的代码时,我想通过处理__call魔术方法使其变得非常简单。
事实上,当我使用装饰器模式(这里,添加单例,添加一些方法并禁止其他方法)时,一些方法不需要被覆盖。所以使用__call是简化代码的好方法。
当某些方法需要通过引用传递的参数时,我的情况会引发。
举个例子,我创建了一个解析PDO的XPDO类。这不是我以前的情况,但我无法证明这一点。
<?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);
这会失败,因为addAndWhere需要引用并给出副本。 通过将addAndWhere传递给public,可以很容易地修复此代码,这很有意义。这只是一个例子。现在想象一下,PDO需要一个参考,你明白我的观点。
答案 0 :(得分:1)
从重载页面的php手册
这些魔法方法的所有参数都不能通过引用传递。
没有干净的解决方案。
你只能做
$pdo->addAndWhere(&$query,'smth');
但是自5.3以来,这是 DEPRECATED ,带有相对警告。