PHP反射ReflectionClass、ReflectionMethod 入門教程????
作者:SNSGOU?發布于:2014-03-16 16:44:00? 分類:PHP???瀏覽(6145)?
PHP5 具有完整的反射API,添加對類、接口、函數、方法和擴展進行反向工程的能力。
反射是什么?
它是指在PHP運行狀態中,擴展分析PHP程序,導出或提取出關于類、方法、屬性、參數等的詳細信息,包括注釋。這種動態獲取的信息以及動態調用對象的方法的功能稱為反射API。反射是操縱面向對象范型中元模型的API,其功能十分強大,可幫助我們構建復雜,可擴展的應用。
其用途如:自動加載插件,自動生成文檔,甚至可用來擴充PHP語言。
PHP反射api由若干類組成,可幫助我們用來訪問程序的元數據或者同相關的注釋交互。借助反射我們可以獲取諸如類實現了那些方法,創建一個類的實例(不同于用new創建),調用一個方法(也不同于常規調用),傳遞參數,動態調用類的靜態方法。
反射api是PHP內建的OOP技術擴展,包括一些類,異常和接口,綜合使用他們可用來幫助我們分析其它類,接口,方法,屬性,方法和擴展。這些OOP擴展被稱為反射。
?
平常我們用的比較多的是?ReflectionClass類?和?ReflectionMethod類,例如:
07 | ???? private ?$_allowDynamicAttributes ?= false; |
22 | ???? protected ?$biography ; |
24 | ???? public ?function ?getId() { |
25 | ???????? return ?$this ->id; |
28 | ???? public ?function ?setId( $v ) { |
29 | ???????? $this ->id =? $v ; |
32 | ???? public ?function ?getName() { |
33 | ???????? return ?$this ->name; |
36 | ???? public ?function ?setName( $v ) { |
37 | ???????? $this ->name =? $v ; |
40 | ???? public ?function ?getBiography() { |
41 | ???????? return ?$this ->biography; |
44 | ???? public ?function ?setBiography( $v ) { |
45 | ???????? $this ->biography =? $v ; |
?
一、通過ReflectionClass,我們可以得到Person類的以下信息:
- 常量 Contants
- 屬性 Property Names
- 方法 Method Names靜態
- 屬性 Static Properties
- 命名空間 Namespace
- Person類是否為final或者abstract
- Person類是否有某個方法
接下來反射它,只要把類名"Person"傳遞給ReflectionClass就可以了:
1 | $class ?=? new ?ReflectionClass( 'Person' );? |
2 | $instance ??=? $class ->newInstanceArgs( $args );? |
?
1)獲取屬性(Properties):
1 | $properties ?=? $class ->getProperties(); |
2 | foreach ?( $properties ?as ?$property ) { |
3 | ???? echo ?$property ->getName() .? "\n" ; |
默認情況下,ReflectionClass會獲取到所有的屬性,private 和 protected的也可以。如果只想獲取到private屬性,就要額外傳個參數:
1 | $private_properties ?=? $class ->getProperties(ReflectionProperty::IS_PRIVATE); |
可用參數列表:
- ReflectionProperty::IS_STATIC
- ReflectionProperty::IS_PUBLIC
- ReflectionProperty::IS_PROTECTED
- ReflectionProperty::IS_PRIVATE
通過$property->getName()可以得到屬性名。
?
2)獲取注釋:
通過getDocComment可以得到寫給property的注釋。?
01 | foreach ?( $properties ?as ?$property ) { |
02 | ???? if ?( $property ->isProtected()) { |
03 | ???????? $docblock ?=? $property ->getDocComment(); |
04 | ???????? preg_match( '/ type\=([a-z_]*) /' ,? $property ->getDocComment(),? $matches ); |
05 | ???????? echo ?$matches [1] .? "\n" ; |
?
3)獲取類的方法
- getMethods() ? ? ? 來獲取到類的所有methods。
- hasMethod(string) ?是否存在某個方法
- getMethod(string) ?獲取方法
?
4)執行類的方法:
3 | $method ?=? $class ->getmethod( 'getName' );?? |
4 | $method ->invoke( $instance );?????????????? |
6 | $method ?=? $class ->getmethod( 'setName' );?? |
7 | $method ->invokeArgs( $instance ,? array ( 'snsgou.com' )); |
?
二、通過ReflectionMethod,我們可以得到Person類的某個方法的信息:
- 是否“public”、“protected”、“private” 、“static”類型
- 方法的參數列表
- 方法的參數個數
- 反調用類的方法
2 | $method ?=? new ?ReflectionMethod( 'Person' ,? 'test' ); |
4 | if ?( $method ->isPublic() && ! $method ->isStatic()) { |
5 | ???? echo ?'Action is right' ; |
7 | echo ?$method ->getNumberOfParameters();? |
8 | echo ?$method ->getParameters();? |