私はクラスを持っています:
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
ここで、すべての操作をログに記録するとします。Logger::add();
内部のようなものを入れたくaddnewnumber()
ありません-おそらくそのクラスを変更することはできません。それを解決する方法は?
私はクラスを持っています:
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
ここで、すべての操作をログに記録するとします。Logger::add();
内部のようなものを入れたく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
代わりに渡します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メソッドを呼び出すと、番号がログに記録されてから、実際のメソッドが呼び出されます。