php - PHP 5.* 中的方法拦截

标签 php interceptor xml-parsing

我正在为 PHP 实现一个日志系统,但我有点卡住了。

所有配置都在 XML 文件中定义,该文件声明要记录的每个方法。 XML 可以很好地解析并转换为多维数组(classname => 方法数组)。到目前为止,一切顺利。

举个简单的例子:

#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:当然,客户端代码不应该有任何后果(无论是否启用拦截都没有什么不同)。

最佳答案

您可以使用eval()来实际定义类,但您应该非常小心eval() 函数可能非常危险。

类似这样的事情:

$parentName = 'Bar';

eval('class Foo extends ' . $parentName . ' { }');

http://php.net/eval

关于php - PHP 5.* 中的方法拦截,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2694037/

相关文章:

xml - 真正删除 XMLParser 对象 Groovy 中的节点

php - 在共享内存中记录访问

php - 为现有 MySQL 模式实现模糊的唯一标识符

php - codeigniter,将对象传递给 View

c - xmlParseMemory 对传递的字符串大小有限制吗

apache-spark - 从 PySpark 中的列加载 XML 字符串

php - php 中的消息未打印在浏览器上?

Angular 8 订阅拦截器中的可观察对象

spring - 使用 Spring Boot 拦截器重定向

java - 是否可以在没有 RoundTimeout 注解的情况下拦截超时方法?