(4)映射类(ReflectionClass)
ReflectionClass类允许你反向映射类。
ReflectionClass类允许你反向映射类。
<? php
interface MySerializable { // ...}
class My Object { // ...}
/** A counter class */
class Counter extends MyObject implements MySerializable
{ 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]/n" .
" declared in %s/n" .
" lines %d to %d/n" .
" having the modifiers %d [%s]/n" ,
$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:/n %s/n" , var_export ( $class -> getDocComment (), 1 ));
// Print which interfaces are implemented by this class
printf ( "--->Implements:/n %s/n" , var_export ( $class -> getInterfaces (), 1 ));
// Print class constants
printf ( "--->Constants:%s/n" , var_export ( $class -> getConstants (), 1 ));
// Print class properties
printf ( "--->Properties:%s/n" , var_export ( $class -> getProperties (), 1 ));
// Print class methods
printf ( "--->Methods:%s/n" , var_export ( $class -> getMethods (), 1 ));
// If this class is instantiable, create an instance
if ( $class -> isInstantiable ())
{ $counter = $class -> newInstance ();注1
echo '---> $counter is instance? ' ;
echo $class -> isInstance ( $counter ) ? 'yes' : 'no' ;注2
echo "/n---> new Object() is instance? " ;
echo $class -> isInstance (new Object ()) ? 'yes' : 'no' ;
}
?>
输出:===> The user-defined class 'Counter' [extends ReflectionClass::__set_state(array( 'name' => 'MyObject',))]declared in D:/develop/html/j.phplines 5 to 12having the modifiers 524288 []--->Documentation: '/** A counter class */'--->Implements:array ('MySerializable' =>ReflectionClass::__set_state(array( 'name' => 'MySerializable',)), )--->Constants:array ( 'START' => 0, )--->Properties:array (0 => ReflectionProperty::__set_state(array( 'name' => 'c', 'class' => 'Counter', )),)--->Methods:array (0 => ReflectionMethod::__set_state(array( 'name' => 'count', 'class' => 'Counter', )),)---> $counter is instance? yes---> new MyObject() is instance? no注1: 方法newInstance()通过象call_user_func()这样的函数接受自变量的一个变化的数值。如果有很多参数则可以通过newInstanceArgs()方法
注2:new class=new ReflectionClass('Foo');$class->isInstance($arg)等价于$arg instanceof Foo或is_a($arg, 'Foo').
(5) 映射方法(ReflectionMethod)
ReflectionMethod类允许你反射类方法。
ReflectionMethod类允许你反射类方法。
<? 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)/n" .
" declared in %s/n" .
" lines %d to %d/n" .
" having the modifiers %d[%s]/n" ,
$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 -> getStartLine (),
$method -> getEndline (),
$method -> getModifiers (),
implode ( ' ' , Reflection :: getModifierNames ( $method -> getModifiers ()))
);
// Print documentation comment
printf ( "--->Documentation:/n %s/n" , var_export ( $method -> getDocComment (), 1 ));
if( $statics = $method -> getStaticVariables ()) //Print static variables if existant
{ printf ( "--->Static variables:%s/n" , var_export ( $statics , 1 )); }
printf ( "--->Invokation results in: " ); //Invoke the method
var_dump ( $method -> invoke ( NULL ));注
?>输出:===> The user-defined final public static method 'increment' (which is a regular method) declared in D:/develop/html/j.phplines 8 to 8having the modifiers 261[final public static]--->Documentation:'/** Increment counter* @final*@static* @access public* @return int*/'--->Invokation results in: int(1)
注:试图调用私有的,保护的或抽象的方法将导致被invoke()方法抛出一个异常。静态方法如上所视,你必须通过NULL作为第一个自变量来invoke()。而非静态方法通过类的实例来调用。
(6) 映射属性(ReflectionProperty)
ReflectionProperty类允许你反射类属性。例子:
ReflectionProperty类允许你反射类属性。例子:
<? php
class String
{ public $length = 5 ; }
// Create an instance of the ReflectionProperty class
$prop =new ReflectionProperty ( 'String' , 'length' );
// Print out basic information
printf ( "===> The%s%s%s%s property '%s' (which was %s)/n" .
" having the modifiers %s/n" ,
$prop -> isPublic () ? ' public' : '' ,
$prop -> isPrivate () ? ' private' : '' ,
$prop -> isProtected () ? ' protected' : '' ,
$prop -> isStatic () ? ' static' : '' ,
$prop -> getName (),
$prop -> isDefault () ? 'declared at compile-time' : 'created at run-time' ,
var_export ( Reflection :: getModifierNames ( $prop -> getModifiers ()), 1 )
);
$obj = new String (); //Create an instance of String
printf ( "--->Value is: " ); //Get current value
var_dump ( $prop -> getValue ( $obj ));
$prop -> setValue ( $obj , 10 ); // Change value
printf ( "---> Setting value to 10, new value is: " );
var_dump ( $prop -> getValue ( $obj ));
var_dump ( $obj ); //Dump object
?>
输出:===> The public property 'length' (which was declared at compile-time)having the modifiers array (0 => 'public',)--->Value is: int(5)---> Setting value to 10, new value is: int(10)object(String)#2 (1) {["length"]=> int(10)}注:试图获得或设置私有的或保护的类属性的值将导致一个被抛出的异常。
(7) 映射扩展(ReflectionExtension)
ReflectionExtension类允许你反射扩展。你可以在使用get_loaded_extensions()运行的时候重新返回所有加载的扩展。(没有研究,用的也不多,暂时不详细讨论了)
ReflectionExtension类允许你反射扩展。你可以在使用get_loaded_extensions()运行的时候重新返回所有加载的扩展。(没有研究,用的也不多,暂时不详细讨论了)
当然,你也可以通过继承来扩展这些类,比如:
<?php
/** My Reflection_Method class */
class My_Reflection_Method extends ReflectionMethod
{ public $visibility = '' ;
public function __construct ( $o , $m )
{ parent :: __construct ( $o , $m );
$this -> visibility = Reflection :: getModifierNames ( $this -> getModifiers ());
}
}
class T { protected function x () { } } //Demo class #1
class U extends T { function x () { } } //Demo class #2
var_dump (new My_Reflection_Method ( 'U' , 'x' )); //Print out information
?>输出:object(My_Reflection_Method)#1 (3) {["visibility"]=> array(1){ [0]=> string(6) "public" }["name"]=> string(1) "x"["class"]=> string(1) "U"}