开放的编程资料库

当前位置:我爱分享网 > PHP教程 > 正文

PHP 5 的反射 API

正如DaveyShafik最近指出的那样,他和我一直在为ZendFramework开发一些Web服务。在这样做的过程中,我已经非常熟悉PHP5的反射API,并且开始爱上它。

当我第一次在PHP5之前的更新日志中读到反射API时,我最初的反应是,“谁在乎?”我根本看不出它对语言的有用补充。最近做了一些需要了解他们正在使用的类的项目,我现在了解何时以及如何使用它。当您需要使用在您编写代码时可能未定义的类时,它会大放异彩——基本上,任何分派给其他类的代码。

那么,您可以使用ReflectionAPI执行哪些操作?以下是我所做的一些事情的列表:

  • 确定类中是否存在方法
  • 从类、方法或函数的phpdoc文档块中检索并获取元信息(我在开发Zend_Server_Reflection时大量使用了它)
  • 确定方法是静态的、公共的、私有的还是受保护的
  • 检索函数/方法参数并确定位置、参数是否可选以及默认值可能是什么be,以及参数的名称(即用于标识它的变量名称)
  • 调用具有可变数量参数的函数或方法。这可以用来代替call_user_func/call_user_func_array(),并且$method->invoke()也允许静态方法调用(我不得不向php.net提交错误,因为invokeArgs()不允许静态调用。
  • 用可变数量的参数实例化一个对象实例使用newInstanceArgs()到构造函数。这是我寻找了一段时间的东西;以前,唯一的解决方案是使用eval()(糟糕!)或者让您的构造函数都接受参数的关联数组。这是一个更好、更灵活的解决方案。

各种Reflection类都可以扩展。然而,由于它们都非常相关,我发现代理它们并根据需要覆盖方法更容易。例如,在Zend_Server_Reflection树中,我需要类反射来返回一个Zend_Server_Reflection_Methods数组,这对文档块做了很多自省(获取方法原型,提示参数变量类型和描述等)。所以,我定义了这样的东西:

class Reflection_Class
{
    public function __construct(ReflectionClass $r)
    {
        $this->_reflection = $r;

        foreach ($r->getMethods() as $method) {
            $this->_methods[] = new Reflection_Method($method);
        }
    }

    public function __call($method, $args)
    {
        if (method_exists($r, $method)) {
            return $r->{$method}($args);
        }
    }

    public function getMethods()
    {
        return $this->_methods;
    }
}

显然,这是速记,但您明白了。

反射API对于各种服务器组件非常有用,因为我们可以有一组中央类来执行函数和类内省,然后可以使用这些类来定义服务器可以使用的调度回调。此外,我实现了一个__wakeup()方法,它基本上恢复了整个反射架构,允许我们在调用之间序列化服务器定义——这大大减少了后续调用需要发生的处理量。

我们还在MVC组件中使用它,特别是在Dispatchers中。同样,这允许我们(a)确定是否存在用于分派的方法,以及(b)使用我们可能需要的任何参数调用它。它还允许我们使用可变数量的参数轻松实例化动作控制器对象。

如果您正在为插件架构编写任何类型的代码,我强烈建议您了解ReflectionAPI;它非常强大,可以为您的代码添加一些非常漂亮、简单和灵活的功能。

未经允许不得转载:我爱分享网 » PHP 5 的反射 API

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏