未知php代码分析,如何利用reflection反射分析类class?
发布于 作者:苏南大叔 来源:程序如此灵动~反射既然能分析函数,也就能黑盒分析代码中的类。在本文中,苏南大叔就来对系统类和一个自定义类进行一下黑盒分析。看看在php8
中ReflectionClass
是个什么样的效果。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码经验文章。本文测试环境:win10
,nginx@1.15.11
,php@8.2.10-nts
。本文的代码部分使用了php8
中的最新特性的写法。如果您运行的时候报错,请检查是否使用的是php8
系列,或者改写一下代码也可以。
类定义和实体对象
在本文中,必须清晰的界定反射代码所操作的对象。是类的定义,还是被实例化后的对象?
例如,在下面的代码中:
$obj = new ClassA("abc");
这里$obj
就是实例对象,ClassA
就是类的定义。它们之间至少差着一个参数abc
,它们两个并不是一个东西。所以,在向本文中的各种函数中,传递要分析的对象的时候,请想清楚自己传递的到底是类,还是实例。
获得公有变量
直接使用get_class_vars()
就可以获得这个类的所有公开属性。(拿不到私有属性的,不要费力气了)
var_dump(get_class_vars("ClassA"));
获得公有方法
直接使用get_class_methods()
就可以获得这个类的所有公开方法。(拿不到私有方法的,不要费力气了)
var_dump(get_class_methods("ClassA"));
反射ReflectionClass 可以获得的信息
现在假设对类ClassA
进行分析:
$r = new ReflectionClass("ClassA");
$constants = $r->getConstants();
获得内容 | 使用方法 |
---|---|
类常量 | $r->getConstants() |
类默认属性 | $r->getDefaultProperties() |
文件名 | $r->getFileName() |
类定义开始行 | $r->getStartLine() |
类定义结束行 | $r->getEndLine() |
类定义注释 | $r->getDocComment() |
其它.. | ... |
这里并不是全部信息,只是苏南大叔认为可能比较常用的。更多可用方法可以参考:
获得实例变量
前面已经说过了,实例和类定义是不一样的。类定义是模版,只可以被实例化。而实例是注入了灵魂,是可以操作的对象。那么,这里可以使用get_object_vars()
获得实例变量的可用属性。
var_dump(get_object_vars($obj));
类的实例化,并不会影响类方法。所以,这里并不存在get_object_methods()
的类似函数,可以直接去分析对应的类。比如:
var_dump(get_object_vars(get_class($obj)));
实例代码分析对象
本文打算利用ReflectionClass
对如下两个类进行分析:
1、ReflectionClass
自身进行分析。
2、自定义类SuNan
进行分析。
分析调用代码:
function analyze($class_name){
echo "\nget_class_vars():\n";
print_r(get_class_vars($class_name));
echo "\nget_class_methods():\n";
print_r(get_class_methods($class_name));
//#####################################
$r = new ReflectionClass($class_name);
echo "\ngetConstants():\n";
print_r($r->getConstants());
echo "\ngetDefaultProperties():\n";
print_r($r->getDefaultProperties());
echo "\ngetFileName():\n";
print_r($r->getFileName());
echo "\ngetStartLine():\n";
print_r($r->getStartLine());
echo "\ngetEndLine():\n";
print_r($r->getEndLine());
echo "\ngetDocComment():\n";
print_r($r->getDocComment());
//#####################################
echo "\nget_object_vars():\n";
print_r(get_object_vars($r));
}
分析ReflectionClass
analyze("ReflectionClass");
结果输出:
get_class_vars():
Array
(
[name] =>
)
get_class_methods():
Array
(
[0] => __construct
[1] => __toString
[2] => getName
[3] => isInternal
[4] => isUserDefined
[5] => isAnonymous
[6] => isInstantiable
[7] => isCloneable
[8] => getFileName
[9] => getStartLine
[10] => getEndLine
[11] => getDocComment
[12] => getConstructor
[13] => hasMethod
[14] => getMethod
[15] => getMethods
[16] => hasProperty
[17] => getProperty
[18] => getProperties
[19] => hasConstant
[20] => getConstants
[21] => getReflectionConstants
[22] => getConstant
[23] => getReflectionConstant
[24] => getInterfaces
[25] => getInterfaceNames
[26] => isInterface
[27] => getTraits
[28] => getTraitNames
[29] => getTraitAliases
[30] => isTrait
[31] => isEnum
[32] => isAbstract
[33] => isFinal
[34] => isReadOnly
[35] => getModifiers
[36] => isInstance
[37] => newInstance
[38] => newInstanceWithoutConstructor
[39] => newInstanceArgs
[40] => getParentClass
[41] => isSubclassOf
[42] => getStaticProperties
[43] => getStaticPropertyValue
[44] => setStaticPropertyValue
[45] => getDefaultProperties
[46] => isIterable
[47] => isIterateable
[48] => implementsInterface
[49] => getExtension
[50] => getExtensionName
[51] => inNamespace
[52] => getNamespaceName
[53] => getShortName
[54] => getAttributes
)
getConstants():
Array
(
[IS_IMPLICIT_ABSTRACT] => 16
[IS_EXPLICIT_ABSTRACT] => 64
[IS_FINAL] => 32
[IS_READONLY] => 65536
)
getDefaultProperties():
Array
(
)
getFileName():
getStartLine():
getEndLine():
getDocComment():
get_object_vars():
Array
(
[name] => ReflectionClass
)
分析自定义类
自定义类的定义如下:
/**
* 类定义的注释信息
*/
class SuNan{
var $city = "北京"; //analyze
const FROM = "北京朝阳";
public $name = "苏南大叔";
public int $age = 18;
private bool $rich = true;
public function __construct(public string $www,private string $domain){
}
public function getWww(){
return $this->www."=>".$this->getDomain();
}
private function getDomain(){
return $this->domain;
}
}
分析自定义类SuNan
:
analyze("SuNan");
结果输出:
get_class_vars():
Array
(
[city] => 北京
[name] => 苏南大叔
[age] => 18
[www] =>
)
get_class_methods():
Array
(
[0] => __construct
[1] => getWww
)
getConstants():
Array
(
[FROM] => 北京朝阳
)
getDefaultProperties():
Array
(
[city] => 北京
[name] => 苏南大叔
[age] => 18
[rich] => 1
)
getFileName():
C:\Users\sunan\Desktop\test\php\test.php
getStartLine():
6
getEndLine():
21
getDocComment():
/**
* 类定义的注释信息
*/
get_object_vars():
Array
(
[name] => SuNan
)
再次对比class_vars
和object_vars
$sn = new SuNan("程序如此灵动", "newsn.net");
print_r(get_class_vars("SuNan"));
print_r(get_object_vars($sn));
输出:
Array
(
[city] => 北京
[name] => 苏南大叔
[age] => 18
[www] =>
)
Array
(
[city] => 北京
[name] => 苏南大叔
[age] => 18
[www] => 程序如此灵动
)
相关文档
- https://newsn.net/say/php-reflect-class.html
- https://newsn.net/say/php-reflect-function.html
- https://newsn.net/say/php-trace-plus.html
- https://newsn.net/say/php-debug-var.html
- https://newsn.net/say/php-debug-func.html
结束语
本文主要是讲述对php
的类做黑盒分析的方式和方法。更多的php
相关经验文章,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。