我有一堂课:
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
现在让我们假设我想记录所有操作。我不想在Logger::add();
里面放一些东西addnewnumber()
——也许不可能修改那个类。那怎么解决呢?
我有一堂课:
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
现在让我们假设我想记录所有操作。我不想在Logger::add();
里面放一些东西addnewnumber()
——也许不可能修改那个类。那怎么解决呢?
您不能在每个类的每个方法上自动调用某些日志记录功能。如果你想在手机的 addnewnumber 方法中添加日志记录,而不改变类本身,你可以在你自己的类中扩展它。
class Phone
{
public function addnewnumber($name, $number)
{
}
public function somethingelse()
{
}
}
class MyPhone extends Phone
{
public function addnewnumber($name, $number)
{
Logger::Add();
parent::addnewnumber($name, $number);
}
}
现在您的 MyPhone 类具有所有电话方法,但是当调用 addnewnumber 方法时,它会记录号码,然后调用实际方法。
在某些情况下,您可以使用一个代理类来包装您的对象并允许您使用__call
. 它看起来像这样:
class Proxy
{
private $_target;
public function __construct($target)
{
$this->_target = $target;
}
public function __call($name, $params)
{
$callable = array($this->_target, $name);
if (!is_callable($callable)) {
trigger_error('Call to undefined method '.
get_class($this->_target).'::'.$name, E_USER_ERROR);
}
return $this->dispatch($callable, $params);
}
protected function dispatch($callable, $params)
{
return call_user_func_array($callable, $params);
}
}
然后,您可以从此类派生并覆盖dispatch
以执行自定义处理:
class LoggingProxy extends Proxy
{
protected function dispatch($callable, $params)
{
echo "Before calling ".get_class($callable[0]).'::'.$callable[1]."\n";
$return = parent::dispatch($callable, $params);
echo "After calling ".get_class($callable[0]).'::'.$callable[1]."\n";
return $return;
}
}
并像这样使用它:
$proxy = new LoggingProxy(new Phone);
$proxy->addnewnumber(1, 2);
但是,这种方法确实有一些缺点:
Proxy
而不是 a Phone
)