php的自动加载和命名空间

__autoload

魔术变量 __autoload():当需要使用的类没有被引入时,这个函数会在PHP报错前被触发,未定义的类名会被当作参数传入。

注意:Warning
本特性已自 PHP 7.2.0 起废弃。强烈建议不要使用本特性。
见官方文档- https://www.php.net/manual/zh/function.autoload.php

本地调用会报如下错误,Deprecated: __autoload() is deprecated, use spl_autoload_register() instead in XXX

所以,PHP 版本号大于 5.12,都可以使用spl_autoload_register 函数来代替。

命名空间

命名空间是为了解决命名冲突的问题。
使用命名空间只是让类名有了前缀,不容易发生冲突,系统仍然不会进行自动导入。

spl_autoload

一旦调用 spl_autoload_register() 函数,当调用未定义类时,系统就会按顺序调用注册到 spl_autoload_register() 函数的所有函数,而不是自动调用 __autoload() 函数。

PSR-4规范

PSR-4 是关于由文件路径自动载入对应类的相关规范,规范规定了一个完全限定类名需要具有以下结构:

\<顶级命名空间>(\<子命名空间>)*\<类名>

PSR-4 规范中必须要有一个顶级命名空间,它的意义在于表示某一个特殊的目录(文件基目录)。子命名空间代表的是类文件相对于文件基目录的这一段路径(相对路径),类名则与文件名保持一致(注意大小写的区别)。

demo

我们来实现以下自动加载功能。目录结构如下:

demo
….one
……..a.php
….two
……..a.php
….verdor
……..Loader.php
index.php

代码如下:
demo/one/a.php

<?php
namespace app\one;
class A
{
    // 对象实例化时输出当前类名
    function __construct()
    {
        echo 'one/' . __CLASS__;
        echo "\r\n";
    }
}

demo/two/a.php

<?php
namespace app\two;
class A
{
    // 对象实例化时输出当前类名
    function __construct()
    {
        echo 'two/' . __CLASS__;
        echo "\r\n";
    }
}

自动加载文件:demo/verdor/Loader.php

<?php
class Loader
{
    /**
     * 路径映射
     */
    public static $vendorMap = array(
        'app' => __DIR__ . DIRECTORY_SEPARATOR . '..',
    );
    /**
     * 自动加载器
     */
    public static function autoload($class)
    {
        $file = self::findFile($class);
        if (file_exists($file)) {
            self::includeFile($file);
        }
    }
    /**
     * 解析文件路径
     */
    private static function findFile($class)
    {
        $vendor = substr($class, 0, strpos($class, '\\')); // 顶级命名空间
        $vendorDir = self::$vendorMap[$vendor]; // 文件基目录
        $filePath = substr($class, strlen($vendor)) . '.php'; // 文件相对路径
        return strtr($vendorDir . $filePath, '\\', DIRECTORY_SEPARATOR); // 文件标准路径
    }
    /**
     * 引入文件
     */
    private static function includeFile($file)
    {
        if (is_file($file)) {
            include $file;
        }
    }
}

入口文件 demo/index.php

<?php
namespace app;
// 引入加载器
include './verdor/Loader.php'; 
// 注册自动加载
spl_autoload_register('Loader::autoload'); 
new one\A();
new two\A();

在demo目录下运行:

php index.php

one/app\one\A
two/app\two\A

这样我们就实现了自动加载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Galloping-Vijay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值