类反射机制可能是PHP语言中最强大,同时也是最被忽视的一个语言特性。如果你正计划实现一个特别复杂但拥有良好可扩展性的系统,那么你有必要深入了解一下PHP的类反射(Reflection)机制。

反射机制可以让你摆脱那些枯燥乏味却又极度复杂的工作,例如:自动载入插件,自动化文档生成,甚至可以扩展PHP语言本身。

一个简单的语言特性是怎么样支持这么广泛的能力的?PHP的类反射API是由一组能够让你访问程序”元数据“和关联注释的类组成。这就使得你能在程序运行时动态决定一些事情,例如,某一个类的方法么样实现。这一能力帮助你创建一个拥有良好插件体系的程序,你可以那些呆板的插件接口告别了,这意味着你能终于能尽可能少的实现那些繁琐的支持接口了。

反射不仅能让你能够访问程序的”元数据“(metadata),他还能用来实例化类,调用方法,传递参数等。反射API甚至能够让你动态的调用类的静态方法,此外自动化文档生成也是由反射实现的。

反射API

反射API是PHP内建的OOP扩展,他由一组类,异常和接口组合而成。它赋予了你分析其他类,方法,接口,参数及扩展的能力。这一扩展被形象的命名为“反射”(Reflection)。

首先让我们跳过乏味如教科书般的陈词滥调,试着使用以下反射机制,亲生感受一下他强大的威力。

\<?php Reflection::export(new ReflectionExtension('reflection')); ?\>

以上的代码会显示很长的列表,内容是反射api实例的每一个类,方法和参数细节。我们通过Reflection的export方法实现这种输出。

几乎反射API的每一部分都实现了reflector接口,ReflectionExtension也不列外。Export方法递归的显示传递进来的reflector,因此作为接口的一部分,每一个reflector都必须要实现自己的export方法。

在这个例子里,我们从ReflectionExtension类开始,它按次序输出他所有的类和接口,截至是所有的参数和方法。

使用反射,你甚至能为每一个内建的PHP类建立类似输出。要做到这一步,首先要做的就是知道载入了那些类。幸运的是这里有一个现成的方法,get_declared_classes()来实现这一步。

\<?php foreach(get\_declared\_classes() as $class){ Reflection::export(new ReflectionClass($class)); } ?\>

get_declared_classes()返回了所有载入的类,包括内建的php类。但是如果我们只想输出用户自定义的类又该怎么办?你要做的只是在输出前做一个判断。代码如下:

\<?php foreach(get\_declared\_classes() as $class){ $reflectionClass=new ReflectionClass($class); if($reflectionClass-\>isUserDefined()){ Reflection::export($reflectionClass); } } ?\>