我正在为 PHP 实现一个日志系统,但我有点卡住了。
所有配置都在一个 XML 文件中定义,该文件声明了要记录的每个方法。XML 被很好地解析并转换为多维数组 ( classname => array of methods
)。到目前为止,一切都很好。
我们举一个简单的例子:
#A.php
class A {
public function foo($bar) {
echo ' // Hello there !';
}
public function bar($foo) {
echo " $ù$ùmezf$z !";
}
}
#B.php
class B {
public function far($boo) {
echo $boo;
}
}
现在,假设我有这个配置文件:
<interceptor>
<methods class="__CLASS_DIR__A.php">
<method name="foo">
<log-level>INFO</log-level>
<log-message>Transaction init</log-message>
</method>
</methods>
<methods class="__CLASS_DIR__B.php">
<method name="far">
<log-level>DEBUG</log-level>
<log-message>Useless</log-message>
</method>
</methods>
</interceptor>
我只希望在运行时(一旦 XML 解析器完成了他的工作)是:
#Logger.php (its definitely NOT a final version) -- generated by the XML parser
class Logger {
public function __call($name,$args) {
$log_level = args[0];
$args = array_slice($args,1);
switch($method_name) {
case 'foo':
case 'far':
//case .....
//write in log files
break;
}
//THEN, RELAY THE CALL TO THE INITIAL METHOD
}
}
#"dynamic" A.php
class A extends Logger {
public function foo($log_level, $bar) {
parent::foo($log_level, $bar);
echo ' // Hello there !';
}
public function bar($foo) {
echo " $ù$ùmezf$z !";
}
}
#"dynamic" B.php
class B extends Logger {
public function far($log_level, $boo) {
parent::far($log_level, $bar);
echo $boo;
}
}
一旦 XML 解析器完成了它的工作,这里最大的挑战就是将 A 和 B 转换成它们的“动态”版本。
理想的情况是完全不修改 A 和 B 的代码(我的意思是,在文件中)来实现这一点 - 或者至少在程序完成后找到一种方法来恢复其原始版本。
明确地说,我想找到最合适的方法来拦截 PHP 中的方法调用。
你对它有什么想法?
PS:当然,客户端代码上不应该有任何后果(无论是否启用拦截,都没有区别)。