欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

javascript - PHP框架内的控制器能随时用配置文件里的常量,原理是把配置文件加载进来了吗?

程序员文章站 2022-06-15 19:20:43
...
PHP 框架内的控制器能随时用配置文件里的常量,原理是把配置文件include进来了吗?

还有www.baidu.com/index/demo,访问的是index控制器里的demo方法,为什么一个URL 就能去实例化一个控制器类,原理是什么?谢谢

回复内容:

PHP 框架内的控制器能随时用配置文件里的常量,原理是把配置文件include进来了吗?

还有www.baidu.com/index/demo,访问的是index控制器里的demo方法,为什么一个URL 就能去实例化一个控制器类,原理是什么?谢谢

能问出这两个问题,说明题主在使用框架的过程中进行了深入的思考,先赞一个!

想得到这两个问题的答案,需要对 PHP 的本质有一定的了解,我想展开说一下。如果能对大家有一点点帮助,我就很开心了。

1. 在代码的任何地方都能直接调用配置文件中的内容,是因为配置文件被 require 进来并赋值给了一个或多个变量。

代码可以参考:https://github.com/TinyLara/TinyLara/blob/master/bootstrap.php#L11

PHP 作为脚本语言,执行的本质就是把一串字符串(指令)发给一个处理器,然后这个处理器根据指令执行相应的动作。多文件的 PHP 框架也是靠的这种方式运行,requireinclude或者__autoload等,最终组合出来一个巨长的 PHP 代码,由解释器执行,得到结果。配置文件的的内容会被赋给这段巨长的 PHP 代码中的某个 public 变量,在整个生命流程中一直可用。

2. PHP 代码确实可以通过 URL 来实例化类,也可以判断 URL 内容来判断需要加载哪个类,执行哪个 function。

PHP 可以边执行代码边载入文件,可以根据 URL 的不同选择不同的文件载入。目前大多数框架都使用了 PHP 的自动载入,例如 __autoload() 魔术方法,在代码中调用某个类的时候自动载入这个类所在的文件。

你所问的就是 路由 的本质,直接看代码:https://github.com/TinyLara/TinyRoute/blob/master/TinyRoute.php#L86

上面代码中 $last = 'HomeController@home'

不得不感叹,PHP 真是字符串的艺术呀!

在PHP5之前,各个PHP框架如果要实现类的自动加载,一般都是按照某种约定自己实现一个遍历目录,自动加载所有符合约定规则的文件的类或函数。 当然,PHP5之前对面向对象的支持并不是太好,类的使用也没有现在频繁。 在PHP5后,当加载PHP类时,如果类所在文件没有被包含进来,或者类名出错,Zend引擎会自动调用__autoload 函数。此函数需要用户自己实现__autoload函数。 在PHP5.1.2版本后,可以使用spl_autoload_register函数自定义自动加载处理函数。当没有调用此函数,默认情况下会使用SPL自定义的spl_autoload函数。

  1. 实例化一个控制器类或者是其他任何类,跟URL是没有太大关系的。

    实际的逻辑大概是这样的:
    假设这样一个url:http://your.domain.com/path/to/your/file
    那么web服务器收到请求后,会先搜索your.domain.com这个域名对应的根目录是在哪里,假设是在/www
    那么,实际请求的文件就是/www/path/to/your/file。如果这个文件是php类型的,web服务器会把文件先交由php解释器解释,再把结果返回给浏览器。

    单一入口的项目,只是通过web服务器配置,把所有的请求都是映射到类似index.php之类的入口文件。再由程序的逻辑去解析url后面的参数,再决定实例化哪个控制器,或者是调用其他方法。

  2. 第二个问题,你说对了, 本质还是 include

是的,已yii为例,他的配置文件是一个数组,在框架一开始就加载了配置文件。
当请求一个控制器/方法时,会根据框架的注册的autoload查找controller,找到就引用,继续找方法,找不到就报异常。

本人是通过把配置信息写在一个接口类里了,
然后通过spl_authload加载这个类,
调用的时候,先继承这个类,然后直接self::xxx

先将 path context 和 controller class 绑定,如果访问路径与某个 path context 匹配,就实例化 controller class.