【发布时间】:2012-12-05 11:19:36
【问题描述】:
我有一堂课:
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
现在让我们假设我想要记录所有操作。我不想在addnewnumber() 中添加Logger::add(); 之类的内容-也许无法修改该类。那怎么解决呢?
【问题讨论】:
标签: php
我有一堂课:
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
现在让我们假设我想要记录所有操作。我不想在addnewnumber() 中添加Logger::add(); 之类的内容-也许无法修改该类。那怎么解决呢?
【问题讨论】:
标签: php
在某些情况下,您可以使用代理类来包装您的对象并允许您使用__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 而不是 Phone)【讨论】:
您不能在每个类的每个方法上自动调用某些日志记录功能。如果你想在手机的 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 方法时,它会记录号码,然后调用实际方法。
【讨论】: