php框架实现之命名空间

时启发 2024-06-27 14:24:01

从理论到实现,不会是一步之遥。

php的PSR4自动加载标准摆在明处,但实现需要有自己的思路。

比如术语class的表现形式为:\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

其中第一个<NamespaceName>,也被称为vender namespace,也即供应商的名称,或者顶级命名空间。

那么php默认的顶级命名空间是什么呢?是\。也就是说,如果php代码中没有通过namespace指定命名空间的话,默认调用的是\命名空间中的类、函数、常量等。而为了避免与\命名空间以及其他开发者定义的类、函数发生冲突,所以才需要将自定义的类、函数等统一放置在自己的命名空间内(假设为example)。

我们先来规范一下项目的整体目录结构:

图1 项目的目录结构

在图1 中,我们将当前目录作为框架的管理目录,public作为作为开放的网站根目录,libs用来存放我们自己的以及导入的库(无关的话题是,public的目录名需要跟Web服务器的设置一致。libs的目录名跟我们要开发的自动加载器的设置一致)

假设我们将类、函数库存放在当前目录的libs下,于是,example命名空间下的类、函数对应的文件,就可以安排在libs\example\目录下。这是命名空间到具体文件的最简单转换方式。比如我们定义了一个HelloWorld类,存放位置为libs\example\HelloWorld.php:

图2 \example\HelloWorld类定义

为了对比实验效果,我们在libs目录下同样定义了一个HelloWorld类:

图3 \HelloWorld类定义

注意一下两个文件代码的区别,第2行和11行不同。第2行表示当前的域名空间。

然后,看一下我们的基本autoloader,我们定义在了al.php之中:

图4 自定义框架的autoloader代码

然后,编辑一下public\index.php:

图5 网站首页index.php的代码

第3行包含了al.php。结果如下图所示:

图6 index.php的执行结果

需要注意的是,index.php中,并未声明当前的namespace,所以使用的是默认的命名空间,对应到目录结构,如同所有库文件的根目录——即当前项目所在目录下的libs子目录。现在,我们重新编写一个index2.php文件,将index.php中的代码改写为以下内容:

图7 index2.php

重点是第2行和第6行。由于声明了当前的命名空间为example,所以$hello赋值时,new HelloWorld()所用的HelloWorld类实际上被解析为\example\HelloWorld类。所以,运行结果如图6一样,并无二致。

0 阅读:3

时启发

简介:读书笔记,编程经验,旅途见闻,人生感悟