反射的概念 反射通常被定义为程序在执行时检查自身并修改其逻辑的能力。在技术方面,反射是要求对象告诉你它的属性和方法,并改变那些成员(甚至是私有成员)
反射的利用 ReflectionClass 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 ReflectionClass implements Reflector { const integer IS_IMPLICIT_ABSTRACT = 16 ; const integer IS_EXPLICIT_ABSTRACT = 32 ; const integer IS_FINAL = 64 ; public $name ; public __construct ( mixed $argument ) public static export ( mixed $argument [, bool $return = false ] ) : string public getConstant ( string $name ) : mixed public getConstants ( ) : array public getConstructor ( ) : ReflectionMethod public getDefaultProperties ( ) : array public getDocComment ( ) : string public getEndLine ( ) : int public getExtension ( ) : ReflectionExtension public getExtensionName ( ) : string public getFileName ( ) : string public getInterfaceNames ( ) : array public getInterfaces ( ) : array public getMethod ( string $name ) : ReflectionMethod public getMethods ([ int $filter ] ) : array public getModifiers ( ) : int public getName ( ) : string public getNamespaceName ( ) : string public getParentClass ( ) : ReflectionClass public getProperties ([ int $filter ] ) : array public getProperty ( string $name ) : ReflectionProperty public getReflectionConstant ( string $name ) : ReflectionClassConstant|false public getReflectionConstants ( ) : array public getShortName ( ) : string public getStartLine ( ) : int public getStaticProperties ( ) : array public getStaticPropertyValue ( string $name [, mixed &$def_value ] ) : mixed public getTraitAliases ( ) : array public getTraitNames ( ) : array public getTraits ( ) : array public hasConstant ( string $name ) : bool public hasMethod ( string $name ) : bool public hasProperty ( string $name ) : bool public implementsInterface ( string $interface ) : bool public inNamespace ( ) : bool public isAbstract ( ) : bool public isAnonymous ( ) : bool public isCloneable ( ) : bool public isFinal ( ) : bool public isInstance ( object $object ) : bool public isInstantiable ( ) : bool public isInterface ( ) : bool public isInternal ( ) : bool public isIterable ( ) : bool public isIterateable ( ) : bool public isSubclassOf ( string $class ) : bool public isTrait ( ) : bool public isUserDefined ( ) : bool public newInstance ( mixed $args [, mixed $... ] ) : object public newInstanceArgs ([ array $args ] ) : object public newInstanceWithoutConstructor ( ) : object public setStaticPropertyValue ( string $name , string $value ) : void public __toString ( ) : string }
__construct ReflectionClass的__construct
用于构造类对象
1 2 3 4 5 6 7 8 9 10 11 12 <?php class Test { private $a; public $b; public function hello ( ) { echo "hello" ; } } $class = new ReflectionClass('Test' ); var_dump($class);
输出结果
1 2 3 4 class ReflectionClass#1 (1) { public $name => string (4 ) "Test" }
获取方法并执行 创建实例并执行方法
1 2 3 $class = new ReflectionClass('Test' ); $test=$class->newInstance(); $test->hello();
输出结果
反射读取私有成员 用到getProperties
方法,然后setAccessible
设置变量可读
1 2 3 4 5 6 7 8 9 10 11 12 <?php class FlagSDK { private $hash='xxxx' ; } $sdk = new FlagSDK(); $reflect = new ReflectionClass($sdk); $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PROTECTED); foreach ($props as $prop) { $prop->setAccessible(true ); print $prop->getName() . "t" ; print $prop->getValue($sdk)."n" ; }
输出结果
反射执行私有方法 使用getMethod
获取Method,然后setAccessible
设置方法可读
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?php class FlagSDK {private $hash='xxxx' ;public function verify ($key ) { if (sha1($key) === $this ->getHash()) { return "too{young-too-simple}" ; } return false ; } private function getHash ( ) { return 'xxxxx' ; } } $hash=new FlagSDK(); $objReflectClass = new ReflectionClass('FlagSDK' ); $method = $objReflectClass->getMethod('getHash' ); $method->setAccessible(true ); $re=$method->invokeArgs($hash,array ()); echo $re;
读取公有变量 1 2 3 4 $FlagSDK = new FlagSDK; $reflectionClass = new ReflectionClass('FlagSDK' ); $reflectionClass->getProperty('hash' )->setValue($FlagSDK,'aaaa' ); var_dump($FlagSDK->hash);
读取私有变量 1 2 3 4 5 6 $FlagSDK = new FlagSDK; $reflectionClass = new ReflectionClass('FlagSDK' ); $reflectionProperty = $reflectionClass->getProperty('hash' ); $reflectionProperty->setAccessible(true ); $reflectionProperty->setValue($FlagSDK, 'aaaa' ); var_dump($reflectionProperty->getValue($FlagSDK));
查看所有类的方法 以下脚本是查找所有包括__destruct()
…的方法和对应类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php $classes = get_declared_classes(); foreach ($classes as $class) { $methods = get_class_methods($class); foreach ($methods as $method) { if (in_array($method, array ( '__destruct' , '__wakeup' , '__call' , '__callStatic' , 'open' ))) { print $class . '::' . $method . "\n" ; } } }
更多用法 https://www.php.net/manual/zh/class.reflectionclass.php
参考链接:
https://www.dazhuanlan.com/lois_td/topics/1614774