刘泉皓

没有最强的法术,只有最强的法师。

php的自动加载

17 Aug 2018 » memory

每次做开发的时候,为了免去一堆require_once之类的代码,可以使用php的autoload功能,这样可以直接使用类,如果php没有找到类定义,就会自动加载该类的定义文件。php自动加载有两个方法,一个是不再建议使用的__autoload()方法,一个是推荐使用的spl_autoload_register()

一、__autoload()使用方法。

先定义一个类MyClass.php

<?php
class MyClass
{
    public function __construct()
    {
        echo __CLASS__ . "\n";
    }
}

然后直接使用它autoload_test1.php

<?php
$myClass = new MyClass();

function __autoload($classname) // 根据上面的new代码,传进来的$classname = 'MyClass'
{
    include './' . $classname . '.php'; // 引入类定义文件 './MyClass.php'
}

可以看见,这里没有使用任何require_once命令,一般$myClass = new MyClass();会直接报错,但这里定义了__autoload()方法,php找不到类的时候会调用它,所以就不会报错了。

liuxu:autoload_test$ tree
.
├── autoload_test1.php
└── MyClass.php

0 directories, 2 files
liuxu:autoload_test$ php autoload_test1.php
MyClass

二、spl_autoload_register()的使用方法。

MyClass.php还是上面的代码,新建一个autoload_test2.php:

<?php
spl_autoload_register(function ($classname) { // 根据上面的new代码,$classname = 'MyClass'
    include './' . $classname . '.php'; // 引入类定义文件 './MyClass.php'
});

$myClass = new MyClass();
liuxu:autoload_test$ tree
.
├── autoload_test1.php
├── autoload_test2.php
└── MyClass.php

0 directories, 3 files
liuxu:autoload_test$ php autoload_test2.php
MyClass

三、PSR-4下的autoload。

首先写一个autoload类,用于直接被spl_autoload_register,这里文件名为MyAutoloader.php

<?php
namespace AutoloadTest;

class MyAutoLoader
{
    public static function loadClass($name)
    {
        $classPath = str_replace('\\', DIRECTORY_SEPARATOR, $name);
        $classFile = '';
        if (strpos($name, 'AutoloadTest\\') === 0) {
            $classFile = __DIR__ . substr($classPath, strlen('AutoloadTest')) . '.php';
        }
        if (is_file($classFile)) {
            require_once($classFile);
            if (class_exists($name)) {
                return true;
            }
        }
        return false;
    }
}

spl_autoload_register('\AutoloadTest\MyAutoLoader::loadClass');

然后我新写一个类NewClass.php

<?php
namespace AutoloadTest;

class NewClass
{
    public function __construct()
    {
        echo __CLASS__ . "\n";
    }
}

然后我用autoload_test3.php测试:

<?php

use AutoloadTest\NewClass;

require_once __DIR__ . '/' . 'MyAutoLoader.php';

$newClass = new NewClass();

可以看到输出:

liuxu:autoload_test$ tree
.
├── autoload_test1.php
├── autoload_test2.php
├── autoload_test3.php
├── MyAutoLoader.php
├── MyClass.php
└── NewClass.php

0 directories, 6 files
liuxu:autoload_test$ php autoload_test3.php
AutoloadTest\NewClass

知识共享许可协议    鄂ICP备 15002452号-5    鄂公网安备 42088102000048号