HacKerQWQ的博客空间

php反射利用总结

Word count: 739Reading time: 4 min
2021/08/31 Share

反射的概念

反射通常被定义为程序在执行时检查自身并修改其逻辑的能力。在技术方面,反射是要求对象告诉你它的属性和方法,并改变那些成员(甚至是私有成员)

反射的利用

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用于构造类对象

image-20210831231343029

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();

输出结果

1
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";
}

输出结果

1
2
hash
xxxx

反射执行私有方法

使用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

CATALOG
  1. 1. 反射的概念
  2. 2. 反射的利用
    1. 2.1. ReflectionClass
      1. 2.1.1. __construct
      2. 2.1.2. 获取方法并执行
    2. 2.2. 反射读取私有成员
    3. 2.3. 反射执行私有方法
    4. 2.4. 读取公有变量
    5. 2.5. 读取私有变量
  3. 3. 查看所有类的方法
  4. 4. 更多用法