自动加载

类自动加载

在编写面向对象程序时,每个类新建一个PHP文件,这会带来一个烦恼:每个脚本的开头,都需要require一个长长的列表。这就需要一种自动加载机制。

所谓类自动加载就是当我们想使用某个命名空间下的某个类时,直接use某个类,然后在使用这个类时自动按照某个规则将文件require,不用自己显示的require相应的代码文件。我们在使用一些开源框架时,一般都引入了类自动加载。

在PHP早期版本中通过__autoload()函数完成自动加载,在PHP5以后,官方推荐使用spl_autoload_register()函数实现类自动加载,spl_autoload_register()函数可以注册任意数量的自动加载器,当使用尚未被定义的类时自动去加载。

关于类自动加载也是有一定规范的,PSR-4规定了类自动加载的规范。

1. psr-4

PSR-4关于类自动加载的规范如下:

  • 1.The term “class” refers to classes, interfaces, traits, and other similar structures.

  • 2.A fully qualified class name has the following form:

    \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
    

    1.The fully qualified class name MUST have a top-level namespace name, also known as a “vendor namespace”.

    2.The fully qualified class name MAY have one or more sub-namespace names.

    3.The fully qualified class name MUST have a terminating class name.

    4.Underscores have no special meaning in any portion of the fully qualified class name.

    5.Alphabetic characters in the fully qualified class name MAY be any combination of lower case and upper case.

    6.All class names MUST be referenced in a case-sensitive fashion.

  • 3.When loading a file that corresponds to a fully qualified class name …

1.A contiguous series of one or more leading namespace and sub-namespace names, not including the leading namespace separator, in the fully qualified class name (a “namespace prefix”) corresponds to at least one “base directory”.

2.The contiguous sub-namespace names after the “namespace prefix” correspond to a subdirectory within a “base directory”, in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.

3.The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.

  • 4.Autoloader implementations MUST NOT throw exceptions, MUST NOT raise errors of any level, and SHOULD NOT return a value.

2. 实现

因为作者是Yii2的严重用户,所以习惯性将命名空间和目录对应,且目录全部使用小写字母,一个符合PSR-4规范的自动加载类如下:

/**
 * Class Autoload
 * @datetime 2020/6/29 11:27 上午
 * @author   roach
 * @email    jhq0113@163.com
 */
class Autoload
{
    private function __construct()
    {
    }

    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * @var array
     * @datetime 2020/6/24 10:10 上午
     * @author   roach
     * @email    jhq0113@163.com
     */
    private static $_namespace = [];

    /**注册一个命名空间前缀
     * @param string $prefix
     * @param string $dir
     * @datetime 2020/6/24 10:10 上午
     * @author   roach
     * @email    jhq0113@163.com
     */
    public static function set($prefix, $dir)
    {
        self::$_namespace[ $prefix ] = $dir;
    }

    /**注册多个命名空间前缀
     * @param array $namespaceArray
     * @datetime 2020/6/24 10:14 上午
     * @author   roach
     * @email    jhq0113@163.com
     */
    public static function mset($namespaceArray = [])
    {
        foreach ($namespaceArray as $prefix => $dir) {
            self::$_namespace[ $prefix ] = $dir;
        }
    }

    /**
     * @param string $class
     * @datetime 2020/6/24 10:15 上午
     * @author   roach
     * @email    jhq0113@163.com
     */
    public static function autoload($class)
    {
        $position = strpos($class,'\\');
        $prefix = substr($class, 0, $position);
        if(!isset(self::$_namespace[ $prefix ])) {
            return;
        }

        $fileName = self::$_namespace[ $prefix ].str_replace('\\','/', substr($class, $position)).'.php';
        if(file_exists($fileName)) {
            require $fileName;
        }
    }
}

在单入口应用当中,在你的入口文件index.php中添加如下代码即可完成自动加载。

<?php
//引入自动加载类文件
require __DIR__.'/Autoload.php';
//注册自动加载函数
spl_autoload_register('Autoload::autoload');
//注册命名空间前缀
Autoload::set('library', dirname(__DIR__).'/library');

PHP依赖管理工具composer会自带一个符合PSR-4规范的类自动加载器,如果我们的项目是使用composer管理依赖的,我们可以直接使用composer的类自动加载器。

学习更多内容: https://404.360tryst.com

我的视频课程: https://edu.csdn.net/course/detail/9933

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

苍穹0113

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

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

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

打赏作者

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

抵扣说明:

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

余额充值