首页 php框架 ThinkPHP ThinkPHP关于ArrayAccess和直接执行魔术访问返回实例的区别

ThinkPHP关于ArrayAccess和直接执行魔术访问返回实例的区别

Dec 29, 2020 am 11:31 AM
thinkphp

本文会对实例化控制器为引子然后解析关于ArrayAccess和直接执行魔术访问返回实例的区别

前言

在上文中对路由进行了特别的详解,也从应用初始化开始解析一直到路由调度返回给路由检测这一环节。

路由检测获取到的值如下图,也就是路由调度最终返回的值。

使用的路由规则为Route::get('hello/:name', 'index/index/:name');

image.png

打印的地方

image.png

路由检测打印的结果

从上图可以看出重要数据都是在dispatc中存放的,接下来就会对控制器进行详解。

最先说明的就是的当路由检测完毕之后执行的实例化控制器操作。

一、实例化控制器

先来看一下是怎么执行到实例化控制器吧!

毫无疑问代码肯定是先从入口文件开始执行的,这里使用容器返回一个App的实例,然后去调用App类中的run方法。

image.png

入口文件

下来就会来到执行应用程序,在这个方法中也是在上文刚刚解析的路由。

所以检测路由执行完就会去执行实例化控制器。

image.png

执行应用程序

在路由检测执行完之后返回的是think\route\dispatch\Module Object这个类,并且这个类赋值给了变量$dispatch

image.png

路由检测

接着看一下本方法的这块代码,这里使用的是中间件,在这快代码中还是用了闭包,对闭包的概念不清晰的就需要回头啃基础了。

image.png

中间件

在上图中咔咔圈出来的一个地方就是$dispatch->run()这块代码,接下来就要对这块代码进行解析了。

在检测路由最终的返回值可以知道其实这个方法是在think\route\dispatch\Module这个类中。

接着就需要对这个类中的run方法进行解析了,这个方法也就是执行路由调度。

在这个方法中不管是获取路由参数还是检测路由、数据自动验证都不会执行(是按照咔咔上文给的路由地址为案例)。

image.png

执行路由调度

所以根据上图代码就会执行到$data = $this->exec();这里。

跟踪这个方法会到下图地方存在一个抽象类,这里需要知道的是抽象类。

image.png

抽象类

对抽象类做出解释

  • 抽象类不能被实例化
  • 有抽象方法的类一定是抽象类;类必须要abstract修饰
  • 抽象方法不能有函数体;即abstract function fun();
  • 抽象类中的非抽象方法,可以被子类调用
  • 非抽象子类继承抽象类,子类必须实现父类的所有抽象方法
  • 抽象子类继承抽象类,无需继承父类的抽象方法

根据上图的原则可以看到Dispatch这个类是抽象类。

所以就会有俩种情况, 一种是抽象类继承抽象类,无需继承父类的抽象方法。

另一种是非抽象子类继承抽象类,子类必须实现父类的所有抽象方法。

image.png

抽象类

怎么去找谁继承了Dispatch

这个时候是不是有一个疑问就是怎么去找Dispatch的子类。

在这个图中可以看到本类Dispatch,但是还有一个dispatch这个目录。

根据路由检测返回的数据可以轻而易举的就知道是thinkphp/library/think/route/dispatch/Module.php这个类。

image.png

寻找子类

来到thinkphp/library/think/route/dispatch/Module.php查看exec方法。

那么接下来的任务就是对这个方法进行深入的解读了。

image.png

实例化控制器

先看第一行代码$this->app['hook']->listen('module_init');,在这里使用了容器ArrayAccess用数组的形式访问对象,然后执行的魔术方法__get,当访问不存在的属性时会去执行make方法。

使用编辑器追踪这个app会到thinkphp/library/think/route/Dispatch.php这个类里边,在这个类的构造函数中可以看到对于app这个属性是赋值了一个App实例。

image.png

寻找app类的实例化

接着来到App类可以看到继承的是Container类。

image.png

继承类

在容器这块已经不止一次的说过这块的知识点了,访问不存在的属性回去执行容器的__get魔术方法。

image.png

魔术方法访问不存在的属性会执行

所以说这块的参数会传入hook,并且会返回hook的实例,关于这个实例是怎么返回的在容器那一节中说的很是详细,可以去看一下哈!

image.png

返回hook的实例

接下来就会去执行hook的listen方法,监听标签的行为。

image.png

监听标签的行为

此时可以来到应用行为扩展定义文件,可以看到这个参数为模块初始化,但是因为这个值是空的。

所以在上图不会去执行,那么就把应用初始化的值给放到这个参数里边进行简单的测试。

这个类就是执行的钩子,对门面类的优化操作。

image.png

应用行为扩展定义文件

那么代码就会执行到$results[$key] = $this->execTag($name, $tag, $params);这里来。

参数说明

  • $name = string(22) "behavior\LoadBehavior"
  • $tag = module_init

接着通过正则对传过来的参数进行处理,最终返回moduleInit

然后通过$obj = Container::get($class);返回behavior\LoadBehavior的实例

最终通过is_callable这个函数进行验证,检测类里边的方法是否可以被调用,方法数组格式,这个方法后期咔咔单独写一篇文章作为对象来解析,这里只需要知道会返回false即可。

然后会把本类的$portal这个值赋值给$method,这个值就是run。

最后通过$result = $this->app->invoke($call, [$params]);这行代码,这行代码的底部执行就是通过反射机制实现的。

最后这段代码会返回NULL。

实例化控制器

接下来就是进行实例化控制器,调用的方法是$this->app->controller()

这里需要注意的是list这个函数,这个函数的后边会返回一个数组,然后list中的俩个变量会分别为索引0和1。

判断也会去执行第一个,同样会执行到容器类的make方法,这个方法会直接返回app\index\controller\Index这个类的实例。

image.png

实例化(分层)控制器 格式:[模块名/]控制器名

二、关于ArrayAccess和直接执行魔术访问返回实例的区别

有一部分小伙伴都已经学会了ArrayAccess和魔术方法__get的使用了。

估计也有一部分在这俩个地方处于模糊地段,咔咔将这俩个放在一起在解析一次。

先聊ArrayAccess的使用

这个案例在之前也给大家演示过,主要就是实现ArrayAccess的这个类。

image.png

这是之前写的一个测试方法

然后在来到控制器进行使用,先进行实例化,之前实现的案例如下。

但是这次需要实现的案例并不是下图所实现的。

image.png

控制器进行使用

接下来使用下图的方式进行访问,直接使用数组访问对象属性。

在上图中可以看到设置了一个属性title为kaka,在这个案例中直接用数组形式直接获取。

看到返回结果为kaka,也就是说直接使用数组形式访问对象的属性。

image.png

新的访问访问

image.png

打印结果

总结

在第一次案例的实现过程中,忽略了一步,就是使用对象直接以数组形式直接访问对象的属性。

可以看到的是可以直接获取到的,那么接下来将这个思想套到框架中在来看一下。

框架实战案例

在上一期文章中解析的路由中存在以下代码,接下来进行简单的解析一下。

image.png

路由类

先来看一下这个app的值打印出来就是think\App Object对象。

image.png

打印的app值

think\App Object这个对象去访问request时,因为app属性就没有这个request,又因为app类是继承着container类,所以会去容器类执行下图方法。

image.png

执行此方法

然后就会去执行__get方法,执行make方法返回对应的实例。

image.png

执行此方法返回实例对象

此时你要是还有疑问就是,怎么就咔咔说会执行就会执行呢!

接下来咔咔带着大家做一个简单的测试就知道了。

在这个位置中随机打印一个数值。

image.png

测试案例

然后来到容器类的ArrayAccess的offsetGet方法中打印一下传过来的值。

看一下打印结果,就很明确了。

image.png

在这里插入图片描述

image.png

打印结果

关于ArrayAccess的使用就到这里就结束了,这也是在之前的基础上详细的进行了一次说明,接下来对容器中的__get方法进行详解,看在什么情况会执行__get方法。

__get方法使用详解

这个案例请看下图中的这个$this->hook

image.png

初始化应用

同样的道理先来调试一下这个$this是什么值。

打印这个值都没什么必要,因为就是在本类中。

image.png

打印结果

在类中属性的访问应该都会,就是直接使用$this-> 即可。

所以说当系统访问$this->hook这个的时候,由于App类是不存在hook这个属性的,所以就会去执行容器类的魔术方法。

image.png

魔术方法

然后在去执行make方法,创建类的实例。

image.png

创建类的实例

总结

所以说是用ArrayAccess和__get魔术方法,最终都是执行的make方法返回类的实例。

当遇到this->config就是执行的容器的__get方法。

当遇到app['request']就是执行的ArrayAccess然后执行offsetGet

  • __get是针对类的属性,当类的属性不存在时会执行
  • ArrayAccess当是用实例化好的类以数组形式访问时,如果不存在就会执行offsetGet这个方法。
    推荐教程:《thinkphp

以上是ThinkPHP关于ArrayAccess和直接执行魔术访问返回实例的区别的详细内容。更多信息请关注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
thinkphp项目怎么运行 thinkphp项目怎么运行 Apr 09, 2024 pm 05:33 PM

运行 ThinkPHP 项目需要:安装 Composer;使用 Composer 创建项目;进入项目目录,执行 php bin/console serve;访问 http://localhost:8000 查看欢迎页面。

thinkphp有几个版本 thinkphp有几个版本 Apr 09, 2024 pm 06:09 PM

ThinkPHP 拥有多个版本,针对不同 PHP 版本而设计。主要版本包括 3.2、5.0、5.1 和 6.0,而次要版本用于修复 bug 和提供新功能。当前最新稳定版本为 ThinkPHP 6.0.16。在选择版本时,需考虑 PHP 版本、功能需求和社区支持。建议使用最新稳定版本以获得最佳性能和支持。

thinkphp怎么运行 thinkphp怎么运行 Apr 09, 2024 pm 05:39 PM

ThinkPHP Framework 的本地运行步骤:下载并解压 ThinkPHP Framework 到本地目录。创建虚拟主机(可选),指向 ThinkPHP 根目录。配置数据库连接参数。启动 Web 服务器。初始化 ThinkPHP 应用程序。访问 ThinkPHP 应用程序 URL 运行。

laravel和thinkphp哪个好 laravel和thinkphp哪个好 Apr 09, 2024 pm 03:18 PM

Laravel 和 ThinkPHP 框架的性能比较:ThinkPHP 性能通常优于 Laravel,专注于优化和缓存。Laravel 性能良好,但对于复杂应用程序,ThinkPHP 可能更适合。

thinkphp怎么安装 thinkphp怎么安装 Apr 09, 2024 pm 05:42 PM

ThinkPHP 安装步骤:准备 PHP、Composer、MySQL 环境。使用 Composer 创建项目。安装 ThinkPHP 框架及依赖项。配置数据库连接。生成应用代码。启动应用并访问 http://localhost:8000。

开发建议:如何利用ThinkPHP框架实现异步任务 开发建议:如何利用ThinkPHP框架实现异步任务 Nov 22, 2023 pm 12:01 PM

《开发建议:如何利用ThinkPHP框架实现异步任务》随着互联网技术的迅猛发展,Web应用程序对于处理大量并发请求和复杂业务逻辑的需求也越来越高。为了提高系统的性能和用户体验,开发人员常常会考虑利用异步任务来执行一些耗时操作,比如发送邮件、处理文件上传、生成报表等。在PHP领域,ThinkPHP框架作为一款流行的开发框架,提供了一些便捷的方式来实现异步任务。

thinkphp性能怎么样 thinkphp性能怎么样 Apr 09, 2024 pm 05:24 PM

ThinkPHP 是一款高性能的 PHP 框架,具备缓存机制、代码优化、并行处理和数据库优化等优势。官方性能测试显示,它每秒可处理超过 10,000 个请求,实际应用中被广泛用于京东商城、携程网等大型网站和企业系统。

开发建议:如何利用ThinkPHP框架进行API开发 开发建议:如何利用ThinkPHP框架进行API开发 Nov 22, 2023 pm 05:18 PM

开发建议:如何利用ThinkPHP框架进行API开发随着互联网的不断发展,API(ApplicationProgrammingInterface)的重要性也日益凸显。API是不同应用程序之间进行通信的桥梁,它可以实现数据共享、功能调用等操作,为开发者提供了相对简单和快速的开发方式。而ThinkPHP框架作为一款优秀的PHP开发框架,具有高效、可扩展和易用

See all articles