反思——反思
在面向对象编程中,对象被赋予了内省的能力,这个内省的过程就是反射。反思,直观理解就是根据目的地找到出发点和源头。比如一个裸对象,我们只能通过这个对象知道它的类和方法。反射是指扩展和分析PHP程序,导出或呈现关于类、方法、属性、参数等的详细信息。,包括注释,在PHP的运行状态下。这种动态获取信息、动态调用对象方法的功能称为反射API。
如何使用反射API
& lt?服务器端编程语言(Professional Hypertext Preprocessor的缩写)
classperson{
public $ name
public $ gender
publicfunctionsay(){
echo $this->名字,“tis ”,$ this->;性别," rn ";
}
publicfunctionset($name,$value){
回应“将$name设置为$ value rn”;
$this->。$ name = $ value
}
publicfunctionget($name){
if(!isset($ this->;$name)){
回声“未设置”;
$this->。$name= "为您设置默认值";
}
返回$this->。$ name
}
}
$ student = new person();
$student->姓名= '汤姆';
$student->性别= '男';
$student->年龄=24岁;
现在,我应该怎么做才能得到这个学生对象的方法和属性列表?如以下代码所示:
//获取对象属性列表
$ reflect = NewreflectionObject($ student);
$props=$reflect->。getProperties();
foreach($props as$prop){
打印$prop->getName()。“n”;
}
//获取对象方法列表
$m=$reflect->。getMethods();
foreach($m as$prop){
打印$prop->getName()。“n”;
}
您也可以使用类函数而不是反射API来返回对象属性的关联数组和更多信息:
//返回对象属性的关联数组
var _ dump(get _ object _ var($ student));
//类属性
var _ dump(get _ class _ vars(get _ class($ student));
//返回类的方法名数组
var _ dump(get _ class _ methods(get _ class($ student));
如果这个对象是从其他页面传过来的,你怎么知道它属于哪个类?它可以用一个代码来完成:
//获取对象属性列表所属的类
echo get _ class($ student);
反射API显然更强大,甚至可以还原这个类的原型,包括方法的访问权限,比如:
//反射得到类的原型
$ obj = NewReflectionClass(' person ');
$ CLaSS name = $ obj->;getName();
$ Methods = $ Properties = array();
foreach($ obj->;getProperties()作为$v)
{
$ Properties[$ v->;GetName()]= $ v;
}
foreach($ obj->;getMethods()作为$v)
{
$ Methods[$ v->;GetName()]= $ v;
}
echo " class { $ className } n { n
is _ array($ Properties)& amp;& ampksort($ Properties);
foreach($ Properties as $ k = & gt;$v)
{
回声“t”;
echo $v->isPublic()?public ':',$v->。isPrivate()?private ':',
$v->。isProtected()?受保护的':',
$v->。isStatic()?静态“:”;
echo " t { $ k } n
}
回声“n”;
if(is _ array($ Methods))k sort($ Methods);
foreach($方法为$k = >;$v)
{
echo " TF function { $ k }(){ } n ";
}
echo " } n
输出如下:
classperson
{
公共性别
publicname
functionget(){}
functionset(){}
functionsay(){}
}
而且PHP手册里有几十个反射API。可以说反射完全描述了一个类或者对象的原型。反射不仅可以用于类和对象,还可以用于函数、扩展模块、异常等等。
反射的效果是什么
反射可用于文档生成。因此,它可以用来扫描文件中的类,并逐个生成描述文档。
既然反射可以找出一个类的内部结构,那么是否可以作为钩子来实现插件功能呢?还是做一个动态代理?
例如:
& lt?服务器端编程语言(Professional Hypertext Preprocessor的缩写)
classmysql {
functionconnect($db){
Echo“连接到数据库$ { db[0]} rn”;
}
}
classsqlproxy {
private $ target
functionconstruct($tar){
$this->。target[]= new $ tar();
}
functioncall($name,$args){
foreach($ this->;目标为$obj){
$ r = NewreflectionClass($ obj);
if($ method = $ r->;getMethod($name)){
if($ method->;isPublic()& amp;& amp!$ method->;isAbstract()){
Echo“在方法之前截取LOGrn
$ method->;invoke($obj,$ args);
Echo“方法后截取rn”;
}
}
}
}
}
$ obj = newsql proxy(' MySQL ');
$obj->connect(' member ');
在正常开发中,使用反射的地方并不多:一个是调试对象,一个是获取类信息。在MVC和插件开发中,反射是很常见的,但是消耗很大,如果能找到替代品就不要滥用。
PHP有Token函数,可以实现一些反射函数。从简单灵活的角度来看,最好使用已经提供的反射API。
在很多情况下,利用好反射可以让代码保持优雅简洁,但是反射也可以破坏类的封装,因为反射可以强制不应该暴露的方法或者属性,这既是优点也是缺点。
1.《reflection PHP高级特性之反射(Reflection)》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《reflection PHP高级特性之反射(Reflection)》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/yule/1220257.html