类与对象(PHP5)之十四:映射(反射)Reflection

日期:2006-09-26  作者:喜腾小二  来源:PHPChina


介绍(Introduction)
PHP
5与一个API完全映射来以增加反向工程师类,接口,函数和方法的效率(性能)并加以扩展。另外,
API映射并且为函数,类和方法提供获取文档注释的方法。
API映射是对Zend引擎一个面向对象的扩展。包括以下类:
PHP代码如下:

php
class Reflection { }
interface Reflector { }
class 
ReflectionException extends Exception { }
class 
ReflectionFunction implements Reflector { }
class 
ReflectionParameter implements Reflector { }
class 
ReflectionMethod extends ReflectionFunction { }
class 
ReflectionClass implements Reflector { }
class 
ReflectionObject extends ReflectionClass { }
class 
ReflectionProperty implements Reflector { }
class 
ReflectionExtension implements Reflector { }
?> 


注:为了详细了解这些类,请看下一章。
如果我们将执行如下例子的代码:
例子 19-32.API映射的基本用法
PHP代码如下:

php
Reflection
::export(new ReflectionClass('Exception'));
?> 


上例将输出:

[Copy to clipboard]CODE:
Class [ class Exception ]
{
  - Constants [0] { }
  - Static properties [0] { }
  - Static
methods [0] { }
  - Properties [6] {
    Property [
protected $message ]
    Property [ private $string ]
   
Property [ protected $code ]
    Property [
protected $file ]
    Property [ protected $line ]
   
Property [ private $trace ]
  }
  - Methods [9] {
   
Method [ final private method __clone ] { }
    Method [
public method __construct ] {
      -
Parameters [2] {
        Parameter #0 [ $message ]
    
   Parameter #1 [ $code ]
      }
    }
    Method [
final public method getMessage ] {  }
    Method [
final public method getCode ] {  }
    Method [
final public method getFile ] {  }
    Method [
final public method getLine ] {  }
    Method [
final public method getTrace ] {  }
    Method [
final public method getTraceAsString ] { }
    Method [
public method __toString ] {
}
  }
}
异常映射(ReflectionException)
ReflectionException
扩展标准异常并由API映射抛出。引入了非特定方法或属性。
映射函数(ReflectionFunction)
ReflectionFunction类允许你反向设计函数。
PHP代码如下:

php
class ReflectionFunction implements Reflector
{
    
final private __clone()
    
public object __construct(string name)
    
public string __toString()
    
public static string export()
    
public string getName()
    
public bool isInternal()
    
public bool isUserDefined()
    
public string getFileName()
    
public int getStartLine()
    
public int getEndLine()
    
public string getDocComment()
    
public array getStaticVariables()
    
public mixed invoke(mixedargs)
    
public mixed invokeArgs(array args)
    
public bool returnsReference()
    
public ReflectionParameter[] getParameters()
    
public int getNumberOfParameters()
    
public int getNumberOfRequiredParameters()
}
?> 


注:getNumberOfParameters()和getNumberOfRequiredParameters()在PHP5.0.3中增加,而invokeArgs()是在PHP5.1.0中增加。
为内省一个函数,您必须首先创建ReflectionFunction
类的一个实例。您可以随后访问这个实例中的任何上述方法。
例子 19-33. 使用ReflectionFunction 类
PHP代码如下:

php
/** A simple counter
 * @return  int  */
function counter() 
{   static 
$c 0;
    return 
$c++;
}
// Create an instance of the Reflection_Function class
$func = new ReflectionFunction('counter');
// Print out basic information
printf(
    
"===> The %s function '%s'
"
.
    
"     declared in %s
"
.
    
"     lines %d to %d
"
,
    
$func->isInternal() ? 'internal' 'user-defined',
    
$func->getName(),
    
$func->getFileName(),
    
$func->getStartLine(),
    
$func->getEndline()
);
// Print documentation comment
printf("--->Documentation:
%s
"
,var_export($func->getDocComment(),1));
if (
$statics=$func->getStaticVariables())//Print static variables if existant
{  printf("--->Static variables:%s
"
,var_export($statics,1));  }
printf("--->Invokation results in:");//Invoke the function
var_dump($func->invoke());
//you may prefer to use the export() method
echo "
ReflectionFunction::export() results:
"
;
echo 
ReflectionFunction::export('counter');
?> 


注:方法invoke()通过象call_user_func()这样的函数接受自变量的一个变化的数值。
映射参数
(ReflectionParameter)
ReflectionParameter类取回一个函数或方法的参数的信息。
PHP代码如下:

php
class ReflectionParameter implements Reflector
{
    
final private __clone()
    
public object __construct(string name)
    
public string __toString()
    
public static string export()
    
public string getName()
    
public bool isPassedByReference()
    
public ReflectionClass getClass()
    
public bool isArray()
    
public bool allowsNull()
    
public bool isOptional()
    
public bool isDefaultValueAvailable()
    
public mixed getDefaultValue()
}
?> 


注: 在PHP
5.0.3中增加了getDefaultValue(),
isDefaultValueAvailable()和isOptional(),而isArray()则是在PHP5.1.0中增加的。
为内省函数参数,你必须首先创建ReflectionFunction或ReflectionMethod类的一个实例,然后用getParameters()方法来返回一个数组型参数。
例子
19-34. Using the ReflectionParameter class
PHP代码如下:

php
function foo($a$b$c) { }
function 
bar(Exception $a, &$b$c) { }
function 
baz(ReflectionFunction $a$b 1$c null) { }
function 
abc() { }
//通过命令行用给定的参数创建ReflectionFunction的一个实例   
$reflect = new ReflectionFunction($argv[1]);
echo 
$reflect;
foreach (
$reflect->getParameters() as $i => $param)
{    
printf"-- Parameter #%d: %s {
"
.
        
"   Class: %s
"
.
        
"   Allows NULL: %s
"
.
        
"   Passed to by reference: %s
"
.
        
"   Is optional?: %s
"
.
        
"}
"
,
        
$i
        
$param->getName(),
        
var_export($param->getClass(), 1),
        
var_export($param->allowsNull(), 1),
        
var_export($param->isPassedByReference(), 1),
        
$param->isOptional() ? 'yes' 'no');
}
?> 


映射类(ReflectionClass)
ReflectionClass类允许你反向设计类。
PHP代码如下:

php
class ReflectionClass implements Reflector
{   final private __clone()
    
public object __construct(string name)
    
public string __toString()
    
public static string export()
    
public string getName()
    
public bool isInternal()
    
public bool isUserDefined()
    
public bool isInstantiable()
    
public bool hasConstant(string name)
    
public bool hasMethod(string name)
    
public bool hasProperty(string name)
    
public string getFileName()
    
public int getStartLine()
    
public int getEndLine()
    
public string getDocComment()
    
public ReflectionMethod getConstructor()
    
public ReflectionMethod getMethod(string name)
    
public ReflectionMethod[] getMethods()
    
public ReflectionProperty getProperty(string name)
    
public ReflectionProperty[] getProperties()
    
public array getConstants()
    
public mixed getConstant(string name)
    
public ReflectionClass[] getInterfaces()
    
public bool isInterface()
    
public bool isAbstract()
    
public bool isFinal()
    
public int getModifiers()
    
public bool isInstance(stdclass object)
    
public stdclass newInstance(mixedargs)
    
public ReflectionClass getParentClass()
    
public bool isSubclassOf(ReflectionClass class)
    
public array getStaticProperties()
    
public mixed getStaticPropertyValue(string name [, mixed default])
    
public void setStaticPropertyValue(string namemixed value)
    
public array getDefaultProperties()
    
public bool isIterateable()
    
public bool implementsInterface(string name)
    
public ReflectionExtension getExtension()
    
public string getExtensionName()
}
?> 


HP5.1.0中增加了hasConstant(),
hasMethod(), hasProperty(), getStaticPropertyValue()和
setStaticPropertyValue()。
为了内省一个类,你必须首先创建ReflectionClass类的一个实例,你可以随后访问这个实例任何上述方法。
例子
19-35. 使用ReflectionClass 的类
PHP代码如下:

php
interface Serializable  
{    // ...}
class Object {    // ...}
/** A counter class */
class Counter extends Object implements Serializable 
{   const START 0;
    
private static $c Counter::START;
    
/**Invoke counter
     * @access  public
     * @return  int */
    
public function count() {  return self::$c++;  }
}
// Create an instance of the ReflectionClass class
$class = new ReflectionClass('Counter');
// Print out basic information
printf("===> The %s%s%s %s '%s' [extends %s]
.
    
"     declared in %s
.
    
"     lines %d to %d
.
    
"     having the modifiers %d [%s]
"
,
        
$class->isInternal() ? 'internal' 'user-defined',
        
$class->isAbstract() ? ' abstract' '',
        
$class->isFinal() ? ' final' '',
        
$class->isInterface() ? 'interface' 'class',
        
$class->getName(),
        
var_export($class->getParentClass(), 1),
        
$class->getFileName(),
        
$class->getStartLine(),
        
$class->getEndline(),
        
$class->getModifiers(),
        
implode(' 'Reflection::getModifierNames($class->getModifiers()))
);
// Print documentation comment
printf("--->Documentation:
 %s
"
,var_export($class->getDocComment(),1));
// Print which interfaces are implemented by this class
printf("--->Implements:
 %s
"
,var_export($class->getInterfaces(),1));
// Print class constants
printf("--->Constants:%s
"
,var_export($class->getConstants(),1));
// Print class properties
printf("--->Properties:%s
"
,var_export($class->getProperties(),1));
// Print class methods
printf("--->Methods:%s
"
,var_export($class->getMethods(),1));
// If this class is instantiable, create an instance
if ($class->isInstantiable()) 
{   
$counter $class->newInstance();
    echo 
'---> $counter is instance? '
    echo 
$class->isInstance($counter) ? 'yes' 'no';
    echo 
"
---> new Object() is instance? "
;
    echo 
$class->isInstance(new Object()) ? 'yes' 'no';
}
?> 


注:方法newInstance()通过象call_user_func()这样的函数接受自变量的一个变化的数值。
class=new
ReflectionClass('Foo');$class->isInstance($arg)等价于$arg instanceof
Foo或is_a($arg, 'Foo').

映射方法(ReflectionMethod)
ReflectionMethod类允许你反向设计类方法。
PHP代码如下:

php
class ReflectionMethod extends ReflectionFunction
{   public __construct(mixed class, string name)
    
public string __toString()
    
public static string export()
    
public mixed invoke(stdclass objectmixedargs)
    
public mixed invokeArgs(stdclass object, array args)
    
public bool isFinal()
    
public bool isAbstract()
    
public bool isPublic()
    
public bool isPrivate()
    
public bool isProtected()
    
public bool isStatic()
    
public bool isConstructor()
    
public bool isDestructor()
    
public int getModifiers()
    
public ReflectionClass getDeclaringClass()
    
// Inherited from ReflectionFunction
    
final private __clone()
    
public string getName()
    
public bool isInternal()
    
public bool isUserDefined()
    
public string getFileName()
    
public int getStartLine()
    
public int getEndLine()
    
public string getDocComment()
    
public array getStaticVariables()
    
public bool returnsReference()
   
public ReflectionParameter[] getParameters()
    
public int getNumberOfParameters()
    
public int getNumberOfRequiredParameters()
}
?> 


为了内省一个方法,你必须首先创建ReflectionMethod类的一个实例。你可以随后访问这个实例任何上述方法。
例子
19-36. Using the ReflectionMethod class
PHP代码如下:

php
class Counter
{    private static $c 0;
    
/** Increment counter
     * @final
     * @static
     * @access  public
     * @return  int */    
final public static function increment(){ return ++self::$c; }
}
// Create an instance of the Reflection_Method class
$method = new ReflectionMethod('Counter','increment');
// Print out basic information
printf"===> The %s%s%s%s%s%s%s method '%s' (which is %s)
.
    
"     declared in %s
.
    
"     lines %d to %d
.
    
"     having the modifiers %d[%s]
"
,
        
$method->isInternal() ? 'internal' 'user-defined',
        
$method->isAbstract() ? ' abstract' '',
        
$method->isFinal() ? ' final' '',
        
$method->isPublic() ? ' public' '',
        
$method->isPrivate() ? ' private' '',
        
$method->isProtected() ? ' protected' '',
        
$method->isStatic() ? ' static' '',
        
$method->getName(),
        
$method->isConstructor() ? 'the constructor' 'a regular method',
        
$method->getFileName(),
        
$method->ge

<<<返回技术中心

技术文章

站内新闻

我要啦免费统计