目录
摘要
目标类
加载问题
加载机制
自动加载机制
怎么使用?
注意问题
反射
反射属性
反射方法
反射注释
反射实例化
反射Person类
反射Grade类
执行类的方法
总结
首页 后端开发 php教程 详解PHP反射技术的代码示例(图文)

详解PHP反射技术的代码示例(图文)

Mar 11, 2017 am 10:23 AM

摘要

相比于Java的反射,PHP中的反射可真的是良心之作。虽然从维护的角度来看,Java更胜一筹也更有优势。但是繁琐的处理也为Java的反射机制增加了一定的学习成本。

今天尝试着使用PHP的反射技术来获取类的信息。
核心操作可以在PHP的官方帮助文档上看到,这里用得最多的就是

getProperties
getMethods
登录后复制

PHP反射方法官方帮助文档

目标类

为了更好的演示反射的结果以及维护,下面就先创建一个类,目录结构如下:
测试所用的目录结构

<?phpclass Person {
    private $name;    private $age;    private $address;    public function __construct($name, $age, $address) {
        $this->name = $name;        $this->age = $age;        $this->address = $address;
    }    public function setter($key, $value) {
        exec ( "{$this}->" . $key . "={$value}" );
    }    /**
     * 通配型的getter方法不好用。
     * <br />
     * 原因: Object Person can not be converted to string.
     * 
     * @param unknown $key         
     * @return string
     */
    public function getter($key) {
        return exec ( "$this" . "->{$key}" );
    }    /**
     * 模拟Java语言实现的getter方法。<br />
     *
     * 缺点: 需要为每一个private属性提供单独的getter方法,使得代码略显臃肿。
     */
    public function getName() {
        return $this->name;
    }
}class Grade {
    private $name;    public function __construct($name) {
        $this->name = $name;
    }    public function setName($name) {
        $this->name = $name;
    }    public function getName() {
        return $this->name;
    }
}
登录后复制

加载问题

加载机制

在正式进行反射操作之前,先来探讨一下__autoload自动加载机制。顾名思义,自动化的进行加载(类,也可以是其他php文件)呗。

对于更深层次而言,这就涉及到PHP解释器的工作原理了。也就是说,我们不可能一个项目只写一个php文件,相反,一个项目中可能会有数以百计的php文件,而且不可避免的会进行相互调用。

也就是说,我们在A文件中声明并实现了一个加法函数,而需要在B文件中进行调用。很明显B文件中根本没有实现这个加法,所以PHP解释器就没办法进行加法运算了。

这个时候就需要让PHP解释器知道这个加法怎么做,于是就需要require / include 包含了这个加法函数的A文件了。

这样,PHP解释器就知道如何解释并运行咱们的PHP文件了。


与PHP相似的是,在Java语言中我们只需要在源文件前面添加import语句,Java虚拟机就能自动的在相关的类信息了。而且强类型的Java可以在编译之前就发现这样的问题,所以代码维护起来比较方便一点。而PHP则需要进行手动的 include/require了。

但是应该清楚的是,这两者换汤不换药而已。

自动加载机制

但是如果对每一个要被引用的php文件进行手动的加载的话,可能就要写好多个这样的加载语句了。所以为了方便处理这种问题,PHP5之后引入了自动加载机制。

void __autoload ( string $class )
登录后复制

$class 就是要进行加载的类的名称,请注意是的名称。


怎么使用?

既然自动加载机制这么好,那么我们要怎么使用呢?

答案就是在需要加载其他类文件的php中,添加一个自定义的__autoload($class) 函数即可。 还是以刚才的文件AB来举例。

文件A中有一个写好的类Person,在文件B中要进行使用。这个时候在文件B中添加一个__aotoload函数即可。而且这个函数的写法也比较的简单(一切按照最简思路来设计的话)。

function __autoload($class) {
    $filename = "$class.class.php";    
    if(!file_exists($filename)){        
    throw new RuntimeException("$filename 文件不存在!");
    }else {        require "$filename";
    }
}
登录后复制

PHP解释器在扫描到文件B的时候会先进行检查,如果未引入目标类Person,则会判断有没有实现__autoload,如果存在则使用自动加载函数进行加载,否则报错退出。

注意问题

虽然上面的自动加载函数比较简单,但是现实中却需要为此付出很多的“代价”,也就是被加载的类文件的名称要和类保持一致(无需区分大小写)。如:

要加载的类的名称为Person,
则该类所在的文件的名称需要为person.class.php,或者Person.class.php
登录后复制

而且,路径问题也是一个比较棘手的问题,在这个简易的自动加载函数中也不难看到,这里他们位于同级目录下,试想一下不满足这个条件的情形,就可以知道这个自动加载函数的代码量将会多么大了吧。

如此的话,也会违反了自动加载机制的设计的初衷。所以按照特定的目录结构存放相关的类文件是非常有必要的。

所谓:增加了冗余的特点,却带来了容易维护的好处。

个人觉得,不妨按照Java语言的目录结构来维护PHP程序,这样会有意想不到的收获的。

反射

下面正式进入反射的话题,在摘要部分已经提到。重点就在于ReflectionClass的使用。

反射属性

<?phprequire &#39;./bean/beans.php&#39;;
// Person 在beans.php文件中声明$protype = new ReflectionClass("Person");
// 可以添加一个参数,来进行过滤操作。如只获取public类型的属性
$properties = $protype->getProperties();
// 反射获取到类的属性信息
foreach ($properties as $property) {    
echo $property."<br />";
}
登录后复制

反射获取累的属性信息

相比于Java,要获取 private属性,PHP更为简单。

反射方法

<?php
require &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass("Person");
$methods = $protype->getMethods();
foreach ($methods as $method) {    
echo $method->getName()."<br />";
}
登录后复制

反射获取类的方法信息

另外,还可以添加过滤条件。给getMethods方法天机一个过滤参数即可。

filter过滤结果为仅包含某些属性的方法。默认不过滤。 

ReflectionMethod::IS_STATIC、 
ReflectionMethod::IS_PUBLIC、 
ReflectionMethod::IS_PROTECTED、 
ReflectionMethod::IS_PRIVATE、 
ReflectionMethod::IS_ABSTRACT、 
ReflectionMethod::IS_FINAL 的任意组合。
登录后复制

反射注释

注释信息,这里就以文档信息为例。

<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );
$properties = $protype->getProperties ();
// 反射获取到类的属性信息
foreach ( $properties as $property ) {    
echo $property . ":";    
$doc = $property->getDocComment ();    
echo "   " . $doc . "<br />";    e
cho "--------------------------------------------------------" . "<br />";
}$methods = $protype->getMethods();
foreach ($methods as $method) {    
echo $method->getName()."<br />";   
 $doc = $method->getDocComment ();    
 echo "   " . $doc . "<br />";    
 echo "--------------------------------------------------------" . "<br />";
}
登录后复制

反射获取文档信息

反射实例化

反射Person类

<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );// 模拟数据库中获取到的值,以关联数组的形式抛出
$values = array(    "name"=>"郭璞",    "age"=> 21,    "address"=>"辽宁省大连市");// 开始实例化
$instance = $protype->newInstanceArgs($values);    
print_r($instance);// 
var_dump($instance);
echo $instance->getName();
登录后复制

反射Person类

反射Grade类

<?phprequire &#39;./bean/beans.php&#39;;$classprotype = new ReflectionClass("Grade");$class = $classprotype->newInstanceArgs(array("name"=>"大三"));
var_dump($class);echo $class->getName();
登录后复制

反射Grade类结果

执行类的方法

$instance->getName(); 
// 执行Person 里的方法getName// 或者:
$method = $class->getmethod(&#39;getName&#39;); 
// 获取Person 类中的getName方法$method->invoke($instance);    
// 执行getName 方法// 或者:$method = $class->getmethod(&#39;setName&#39;); 
// 获取Person 类中的setName方法$method->invokeArgs($instance, array(&#39;snsgou.com&#39;));
登录后复制

总结

回顾一下,本次试验演示了PHP中的反射技术,对比分析了Java语言的反射技术的实现。也只能说各有利弊吧。

在Java中,反射技术是编写框架的基础。虽然在PHP中反射技术不是特别的重要,而且用的时候约束也比较多,稍显鸡肋。但是比葫芦画瓢的话,还是可以做出一些有用的小工具的。


以上是详解PHP反射技术的代码示例(图文)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1671
14
CakePHP 教程
1428
52
Laravel 教程
1331
25
PHP教程
1276
29
C# 教程
1256
24
PHP与Python:了解差异 PHP与Python:了解差异 Apr 11, 2025 am 12:15 AM

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

PHP:网络开发的关键语言 PHP:网络开发的关键语言 Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP行动:现实世界中的示例和应用程序 PHP行动:现实世界中的示例和应用程序 Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP的持久相关性:它还活着吗? PHP的持久相关性:它还活着吗? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

PHP和Python:解释了不同的范例 PHP和Python:解释了不同的范例 Apr 18, 2025 am 12:26 AM

PHP主要是过程式编程,但也支持面向对象编程(OOP);Python支持多种范式,包括OOP、函数式和过程式编程。PHP适合web开发,Python适用于多种应用,如数据分析和机器学习。

PHP与其他语言:比较 PHP与其他语言:比较 Apr 13, 2025 am 12:19 AM

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP和Python:代码示例和比较 PHP和Python:代码示例和比较 Apr 15, 2025 am 12:07 AM

PHP和Python各有优劣,选择取决于项目需求和个人偏好。1.PHP适合快速开发和维护大型Web应用。2.Python在数据科学和机器学习领域占据主导地位。

See all articles