自动加载

每次使用类或继承时,没有人想要 requireinclude。因为它可能很痛苦并且容易忘记,所以 PHP 提供了所谓的自动加载。如果你已经在使用 Composer,请阅读使用 Composer 进行自动加载的内容

什么是自动加载?

这个名字基本上都说明了一切。你没有得到所请求的类存储在文件中,但 PHP 自动 matically 负荷这样。

如何在没有第三方代码的基本 PHP 中执行此操作?

__autoload 的功能,但使用 spl_autoload_register 被认为是更好的做法。每次在给定空间内未定义类时,PHP 都会考虑这些函数。因此,将 autoload 添加到现有项目是没有问题的,因为定义的类(通过 require ie)将像以前一样工作。为了准确起见,以下示例将使用匿名函数,如果使用 PHP <5.3,则可以定义函数并将其名称作为参数传递给 spl_autoload_register

例子

spl_autoload_register(function ($className) {
    $path = sprintf('%s.php', $className);
    if (file_exists($path)) {
        include $path;
    } else {
        // file not found
    }
});

上面的代码只是尝试使用 sprintf 包含一个带有类名的文件名和附加的扩展名“.php” 。如果需要加载 FooBar,它看起来是否存在 FooBar.php,如果包含它。

当然,这可以扩展到适合项目的个人需求。如果类名中的 _ 用于分组,例如 User_PostUser_Image 都引用 User,则两个类都可以保存在名为 User 的文件夹中,如下所示:

spl_autoload_register(function ($className) {
    //                        replace _ by / or \ (depending on OS)
    $path = sprintf('%s.php', str_replace('_', DIRECTORY_SEPARATOR, $className) );
    if (file_exists($path)) {
        include $path;
    } else {
        // file not found
    }
});

User_Post 现在将从“User / Post.php”等加载。

spl_autoload_register 可根据不同需求量身定制。所有带有类的文件都被命名为“class.CLASSNAME.php”?没问题。各种嵌套(User_Post_Content =>“User / Post / Content.php”)?没问题。

如果你想要更复杂的自动加载机制 - 并且仍然不想包含 Composer - 你可以在不添加第三方库的情况下工作。

spl_autoload_register(function ($className) {
    $path = sprintf('%1$s%2$s%3$s.php',
        // %1$s: get absolute path
        realpath(dirname(__FILE__)),
        // %2$s: / or \ (depending on OS)
        DIRECTORY_SEPARATOR,
        // %3$s: don't wory about caps or not when creating the files
        strtolower(
            // replace _ by / or \ (depending on OS)
            str_replace('_', DIRECTORY_SEPARATOR, $className)
        )
    );

    if (file_exists($path)) {
        include $path;
    } else {
        throw new Exception(
            sprintf('Class with name %1$s not found. Looked in %2$s.',
                $className,
                $path
            )
        );
    }
});

使用这样的自动加载器,你可以愉快地编写如下代码:

require_once './autoload.php'; // where spl_autoload_register is defined

$foo = new Foo_Bar(new Hello_World());

使用类:

class Foo_Bar extends Foo {}
class Hello_World implements Demo_Classes {}

这些例子将包括 foo/bar.phpfoo.phphello/world.phpdemo/classes.php 的类。