namespaces - PHP命名空间 namespace 如何实现自动加载
巴扎黑
巴扎黑 2017-04-10 15:12:07
[PHP讨论组]

测试

namespace 会自动加载,但是我测试的两个文件并没有自动加载:

#/DB/MySql.class.php

namespace DB;

class MySql
{

    public function __construct()
    {
        var_dump(__FILE__);
    }
}
#/index.php

namespace Home;

use DB\MySql;

$mysql = new MySql();

报错

Fatal error: Class 'DB\MySql' not found in D:\localhost\demo\space\index.php on line 23

修改

修改 index.php 改成如下,可以了,但是为什么不能自动加载?

phpnamespace Home;

use DB\MySql;

spl_autoload_register(function ($class) {
    if ($class) {
        $file = str_replace('\\', '/', $class);
        $file .= '.class.php';
        if (file_exists($file)) {
            include $file;
        }
    }
});

$mysql = new MySql();

巴扎黑
巴扎黑

全部回复(3)
天蓬老师

命名空间跟文件加载并无直接关系,
只是有些语言,将命名空间结构和文件结构对应起来了。
以php为例,
一般的命名空间结构,跟php文件结构是存在映射关系的,通过命名空间名称,就能算出该类的实际存储位置,
然后实例化的时候,会触发用设置的spl自动加载函数将文件引入。

天蓬老师
namespace Home;
use DB\MySql;
$mysql = new MySql();

实际执行代码的时候是 new \DB\MySql(); 找不到这个文件的时候就会调用你的autoload函数 并file_exists("DB/MySql.class.php"),在当前目录下查找这个文件,在找不到的情况下然后就是你看到的 错误

巴扎黑

命名空间可以理解成一种虚拟路径,比如:

// a.class.php
namespace A;
class A{
    ...
}

// b.class.php
namespace B;
class B{
    ...
}

即使 a.class.phpb.class.php 存在于同一个文件夹下,在使用他们的时候也需要加入用命名空间。比如现在有一个 c.php, 它和 a.class.phpb.class.php 在同一文件夹下:

// c.php
<?php
include './a.class.php';
include './b.class.php';

$a = new \A\A();
$b = new \B\B();

其中,两个 include 的目的是把两个文件中的内容引入,这样才可以正常使用文件中的内容 (类、变量、函数等) 。而命名空间的作用在于:即使引入了类所在的文件,由于它们被加上了一层「虚拟路径」,因而在实例化的时候也需要加入各自的命名空间才行。

而自动载入,目的是在于将「虚拟路径」和「真实文件路径」相对应,使得在实例化 new A\B\C() 就相当于在使用 ./A/B/C.php 文件中的类。有了这样一个约定,我们就可以在使用类时,只关注命名空间,而不用再繁琐地引入文件了。这是因为有这么一段代码(就是你写的 spl_autoload_register 那段),按照某一约定(PSR0/PSR4,即命名空间路径与实际文件路径相匹配) 帮我们把文件引入的工作给做了。

至于为什么非得写这么一段 spl_autoload_register,那是因为这种对应约定还没被写入 PHP 的语言机制里。不然我们就可以像 Java 中定义和使用「包」的方式一样对待 PHP 项目代码了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号