使用场景

大部分情况都需要多个文件才可以完成业务,这就会出现类名冲突的情况发生,命名空间可以解决这类问题。

在操作系统中目录用来将文件管理,它就扮演了命名空间的角色。例如文件 foo.txt 可以同时在目录 /home/grep/home/other 中存在,但在同一个目录中不能存在两个 foot.txt 文件。另外,在目录 /home/grep 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/grep/foo.txt 。这个原理应用到程序设计领域就是命名空间的概念。

基本使用

默认情况下常量、类和函数名都放在全局空间下。命名空间通过 namespace 来声明。

namespace 必须定义在文件头部,并在declare(strict_types=1) 语句下面。

helper.php

  1. function sum()
  2. {
  3. return 'helper sum';
  4. }

test.php

  1. namespace App;
  2. include 'helper.php';
  3. function sum()
  4. {
  5. return 'laot sum';
  6. }
  7. # 使用当前命名空间中的sum
  8. echo sum();
  9. # 使用 helper.php 中的sum
  10. echo \sum();
  • 不指定命名空间时将使用当前命名空间
  • 如果命名空间中的函数或常量未定义,将会使用全局命名空间

子命名空间

PHP 命名空间也允许指定层次化的命名空间的名称,如 App\Controller 形式,一般情况下我们将层次与目录结构匹配。

  1. namespace App\Controller;
  2. class Bootstrap
  3. {
  4. public function make()
  5. {
  6. return __METHOD__;
  7. }
  8. }

引入方式

非限定名称

调用类时没有指定命名空间时,将使用当前命名空间。
下面在使用 User 时没有指定命名空间将使用当前命名空间。

  1. namespace App;
  2. class User
  3. {
  4. public function make()
  5. {
  6. return __METHOD__;
  7. }
  8. }
  9. $user = new User;
  10. echo $user->make();

限定名称

限定名称类似于文件系统中的相对路径。

Order.php

  1. namespace App\Controller;
  2. class Order
  3. {
  4. public static function make()
  5. {
  6. return __METHOD__;
  7. }
  8. }

Test.php

  1. namespace App;
  2. include 'Order.php';
  3. class User
  4. {
  5. public static function make()
  6. {
  7. return __METHOD__;
  8. }
  9. }
  10. echo Controller\Order::make();

使用限定名称调用 Order 类,系统会使用当前命名空间加上 Controller 做为 Order 类的命名空间。

完全限定名称

类似于文件系统中的绝对路径,以下面的代码为例,调用 Order 类时可以使用以下的完全限定方式。

  1. echo \App\Controller\Order::make();

常量

常量 __NAMESPACE__ 的值时包含当前命名空间名称的字符串。

  1. <?php
  2. namespace App;
  3. function factory($class){
  4. return __NAMESPACE__ . '\\' . $class;
  5. }
  6. class User{
  7. public static function make(){
  8. return __METHOD__;
  9. }
  10. }
  11. class Order{
  12. public static function make(){
  13. return __METHOD__;
  14. }
  15. }
  16. echo factory('User')::make();

使用 namespace 关键字可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。

  1. <?php
  2. namespace App;
  3. class Order
  4. {
  5. public static function make()
  6. {
  7. return __METHOD__;
  8. }
  9. }
  10. echo namespace\Order::make();

别名引入

通过操作符 use 来为类或命名空间使用别名。

基本使用

本实例使用的示例目录结构如下:

  1. App
  2. --Controller
  3. -- Comment.php
  4. -- User.php
  5. boot.php

boot.php

  1. namespace Laot;
  2. use App\Controller\User;
  3. include 'App/Controller/User.php';
  4. echo User::make();

如果使用 use App\Controller ,在引入 User 类时方法如下:

  1. Controller\User::make()

别名

在引入多个同名类时会有冲突情况发生,可以通过起别名的方式处理。

  1. namespace Laot;
  2. use App\Controller\User as Member;
  3. include 'App/Controller/User.php';
  4. echo Member::make();

多个引入

可以使用多行 use 或用逗号分隔多个类(空间)形式处理多个导入的情况。

  1. namespace Laot;
  2. use App\Controller\User as Member;
  3. use App\Controller\Comment;
  4. include 'App/Controller/User.php';
  5. include 'App/Controller/Comment.php';
  6. echo Member::make();

使用逗号分隔

  1. <?php
  2. ...
  3. use App\Controller\User as Member, App\Controller\Comment;
  4. ...

自动加载

注册加载

以往的 __autoload 自动加载函数以及在 php7.2 废弃使用,所以使用 spl_autoload_register 函数完成自动加载处理。

  1. <?php
  2. namespace App;
  3. use App\Controller\User;
  4. spl_autoload_register(function ($class){
  5. $file = str_replace('\\', '/', $class).'.php';
  6. if(!is_file($file)){
  7. throw new \Exception("file don't exists");
  8. }
  9. require $file;
  10. });
  11. echo User::make();

使用类方法实现

  1. <?php
  2. namespace App;
  3. use App\Controller\User;
  4. class Bootstrap
  5. {
  6. public function autoload($class)
  7. {
  8. $file = str_replace('\\', '/', $class) . '.php';
  9. if (!is_file($file)) {
  10. throw new \Exception("file don't exists");
  11. }
  12. require $file;
  13. }
  14. }
  15. spl_autoload_register([new Bootstrap, 'autoload']);
  16. echo User::make();

composer

使用 composer 是现在开发建议使用的方式,composer 相关文档教程也会陆续更新,下面简略介绍使用方法。

项目初始

  1. $ composer init

执行上面的命令并一直回车下去。

修改配置文件

个性 composer.json 配置文件,其中 autoload 配置项是自动加载设置。

  • files 是自动加载文件列表,适合于加载函数
  • psr-4 自动加载命名空间与目录对应关系
    1. {
    2. "name": "14778/htdocs",
    3. "authors": [
    4. {
    5. "name": "Laot",
    6. "email": "1477821088@qq.com"
    7. }
    8. ],
    9. "autoload": {
    10. "files": [
    11. "App/helper.php"
    12. ],
    13. "psr-4": {
    14. "App\\": "App"
    15. }
    16. },
    17. "require": {}
    18. }

安装与更新

修改配置文件后执行 composer install 生成vendor,如果修改过配置文件需要执行 composer update

配置

在项目中使用以下代码即可完成自动加载。

  1. include 'vendor/autoload.php';