服务报价 | 域名主机 | 网络营销 | 软件工具| [加入收藏]
 热线电话: #
当前位置: 主页 > php教程 > php教程 >

PHP框架中的文件载入的实现(自动载入/PSR规范/命名空间)

时间:2016-12-02 09:43来源:未知 作者:最模板 点击:
PHP框架中的各个目录下面的各个.php文件是如何实现加载的,他上网搜索,一搜一大把,都是再说php中有自动加载函数,是自动加载函数完成类文件的自动加载的,但是具体的还是不明白

PHP框架中的各个目录下面的各个.php文件是如何实现加载的,他上网搜索,一搜一大把,都是再说php中有自动加载函数,是自动加载函数完成类文件的自动加载的,但是具体的还是不明白。是的,框架的自动载入的完成的确是依靠PHP提供的自动载入的函数来完成,但是除此以外,还有几个需要注意点,如果不搞明白,就不能真正的理解框架具体的实现方式。那么这里就总结一下:

(1):总所周知,php完成自动加载是依靠__autoload()函数或者spl_autoload_register()函数来实现,具体的使用方法大家都知道,这里就不赘述了。这里说一下两者之间的区别。

目前,实现自动加载,大家几乎都使用spl_autoload_register()函数,而不是使用__autoload()函数,这是因为,在同一个脚本中__autoload()函数不能够重复进行定义,而spl_autoload_register()函数却可以实现注册多次加载函数,这样我们就可以更加灵活的进行文件的自动加载了。

下面的代码因为重复定义了__autoload()函数,所以会报错。

<?php
//定义加载函数1
function __autoload($class_name){
       //加载文件
       require_once("./".$class_name.".php");
}
//定义加载函数2
function __autoload($class_name){
       //加载文件
       require_once("./".$class_name.".php");
}
?>

但是下面使用spl_autoload_register()函数就不会报错:

<?php
function autoload_one($class_name){
      require_once("");
}
function autoload_two($class_name){
      require_once("");
}
spl_autoload_register('autoload_one');
spl_autoload_register('autoload_two');
?>

(2):参考上面的两个函数的代码,传递的参数都是$class_name,也就是需要加载的类的名称。如果我们实例化一个类,就会自动的将该类的名称赋值给$class_name。如果我们实例化一个带有命名空间的类,就会将该类所处的命名空间以及该类的名称传递给$class_name。看下面的代码:

<?php
function __autoload($class_name){
      require_once("./".$class_name.".php");
      echo $class_name."<br/>";  //打印出User\Parent
}
$a = new User\Parent(); //实例化User命名空间下的Parent类
?>

好了,现在我们就可以得到想要实例化的类的名称,那么下面的问题就是如何根据传递过来的类的名字来找到该类文件,并进行加载了。

(3):在了解如何根据传递过来的类的名称(包括命名空间)去找类之前,我们还必须要了解一下PHP编程的规范,了解了规范,你就会彻底明白到底是怎么回事。这里说的PHP开发规范指的是PSR规范,它是PHP开发的事实标准,主流的PHP开发框架都是遵循PSR开发规范。比如ThinkPHP框架就支持PSR开发标准。

PSR规范目前包含五个具体的规范(包括PSR-0,PSR-1,PSR-2,PSR-3,PSR-4)。这里我们具体的说一下PSR-0以及PSR-4规范,其他的规范我们这里就不提,有兴趣的同学可以自己百度。PSR-0规范如下:

                             1):命名空间必须与绝对路径一致。

                             2):类名的首字母必须要大写。

                             3):除了入口文件以外,其他的.php文件中必须只有一个类,不能有可执行的代码。

根据PSR-o规范,命名空间空间必须要与绝对路径一致,也就是说如果你要将一个名为HomeController的类文件设置在App\User\Controller的命名空间之下,那么就必须要将该文件放到当前目录下面(入口文件)下面的./App/User/Controller文件夹下面。反过来一样,如果你需要在./App/User/Controller文件夹下面创建一个类文件,那么这个类文件的命名空间也必须是App\User\Controller。

PSR-4规范基本和PSR-0规范一致,区别在与PSR-4是对下划线(underscore)的定义不同。PSR-4中,在类名中使用下划线没有任何特殊含义。而PSR-0则规定类名中的下划线_会被转化成目录分隔符。

了解了上面的三点,我们就可以理清主流PHP框架中实现类文件加载的机制了。

(1):在入口文件中定义类文件的加载处理函数,比如说spl_autoload_register()函数。

(2):index.php处理用户的请求,处理传递过来的参数,解析路由,分析出需要请求的类名,方法名。

(3):实例化类,根据传入的类名称,根据PSR-0/PSR-4规范,分析出类文件的路径,进行加载

大体的步骤就是这样的,当然了,一个成熟的框架真正的加载流程要比上面说的复杂的多得多,有兴趣的可以研究框架源码。

补:另外,因为主流的框架都广泛的采用命名空间,所以就会大量的使用use来引用其他各个命名空间下定义的各个类。有些同学可能没有看到require()来加载类文件,所以就以为use可以自动的完成文件的加载。其实并不是这样的,use并不会进行类文件的加载。之所以use之后就完成了加载,还是因为框架定义了自动加载函数的原因,使用use来引入类与使用new来实例化类的时候,都会触发类的自动加载。

(责任编辑:最模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------