PHP 新手入门指南 - 使用命名空间

首先来了解一下命名空间:

(PHP 5 >= 5.3.0, PHP 7)

什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。

在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:

  • 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  • 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

PHP 命名空间提供了一种将相关的类、函数和常量组合到一起的途径。

更多关于命名空间的详细内容,请参考 官方文档

小实践

接下来我们通过小实践将这个系列手记中的项目中增加命名空间的运用。

首先,我们对 core目录下的类文件加入命名空间:

  • App.php, Request.php, Router.php

开头部分添加:

namespace App\Core;
  • database/Connection.php, database/QueryBuilder.php

开头部分添加:

namespace App\Core\Database;

其次,对控制器目录下的类文件 PageController.phpUsersControler.php 添加命名空间:

namespace App\Controllers;

use App\Core\App;

因为控制器类中都有用到了 App\Core\App 类,通过 use 关键字是引入命名空间下的类,以便我们不需要每次都是这样书写代码:

$users = App\Core\App::get('database')->selectAll('users');

如果 use 引入了命名空间下的类,只需要这样即可:

$users = App::get('database')->selectAll('users');

同时,在 core/bootstrap.php 中,也需要引入命名空间。

在开头部分添加:

use App\Core\App;
use App\Core\Database\{QueryBuilder, Connection};

可以看到通过中括号和逗号的分隔能添加多命名空间下的类的引入。这里因为 QueryBuilderConnection 在同一命名空间下,很自然可以通过这个方式引入它们。

项目的入口文件 index.php 中也有用到命名空间类,也需要引入:

// index.php
<?php

require 'vendor/autoload.php';
require 'core/bootstrap.php';

use App\Core\{Router, Request};

Router::load('app/routes.php')
    ->direct(Request::uri(), Request::method());

当我们使用了命名空间,我们的路由解析需要调整,否则会找不到类而无法实例化出错,所以在 core/Router.php 中,对 callAction 修改后如下:

public function callAction($controllerName, $action)
{
    $controller = "App\\Controllers\\{$controllerName}";
    $controller = new $controller;

    if (! method_exists($controller, $action)) {
        throw new Exception("{$controllerName} does not respond to the {$action}.");
    }

    return $controller->$action();
}

这里拼接字符串 App\\Controllers\\{$controllerName} 定义了控制所在命名空间。


至此,所有的修改都完成,接下来我们需要重新生成自动加载类:

composer dump-autoload

运行程序,可以看到效果如初,命名空间就此运用到了项目中。

自定义框架

在这个实践的基础之上,有之前的 controllersviews 目录,我们可以再建立一个 models 目录,来存放项目会用到的模型类。

models 目录下新建 Project.php 文件:

<?php

namespace App\Models;

class Project
{
    // ...  
}

我们可以通过这样的方式来完善模型类,逐步分类 MVC 层次的各个部分,让程序结构变得更加清晰。

我们还可以进一步的将项目的目录结构进行一些调整,效果如下:

目录结构

这里新建了一个 app 目录,并将 controllers, modelsviews, routes.php 纳入了进去,形成了应用程序的结构层次。

再看看 core 目录中的内容,不难发现,它通常被可以认为是一个框架的核心基础,它提供了加载器 bootstrap.php,应用容器 App.php,路由和请求 (Router.phpRequest.php),数据库操作类 (ConnectionQueryBuilder),为应用程序提供核心功能。

虽然这里是通过简单的代码实现,但从整体上看来,我们算是构建了一个简单的自定义框架,即使不是非常完美,但也有模有样。

如果想继续扩展,让它变得强大,那就动手做吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容