什么是自动加载; 你如何使用spl_autoload,__ autoload和spl_autoload_register?

diE*_*cho 192 php spl autoload

我正在学习高级PHP标准并尝试实现新的有用方法.早些时候我__autoload只是用来逃避包括每页上的多个文件,但最近我看到了一个提示__autoload manual

spl_autoload_register()为自动加载类提供了更灵活的替代方法.因此,不鼓励使用__autoload(),将来可能会弃用或删除.

但我真的无法弄清楚如何实施spl_autoloadspl_autoload_register

Bro*_*bay 315

spl_autoload_register() 允许您注册PHP将放入堆栈/队列的多个函数(或来自您自己的Autoload类的静态方法),并在声明"new Class"时按顺序调用.

例如:

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class/';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,"MyClass"是您尝试实例化的类的名称,PHP将此名称作为字符串传递给spl_autoload_register(),这允许您获取变量并使用它来"包含"相应的类/文件.因此,您不需要通过include/require语句包含该类...

只需简单地调用您想要实例化的类,就像上面的示例一样,并且由于您注册了spl_autoload_register()自己的函数(via ),它将找出所有类所在的位置,因此PHP将使用该函数.

使用的好处spl_autoload_register()是,与__autoload()您不需要在您创建的每个文件中实现自动加载功能.spl_autoload_register()还允许您注册多个自动加载功能,以加快自动加载速度并使其更加轻松.

例:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }
Run Code Online (Sandbox Code Playgroud)

关于spl_autoload,手册说明:

此函数旨在用作默认实现__autoload().如果没有指定任何其他内容并且spl_autoload_register()在没有任何参数的情况下调用,则此函数将用于以后的任何调用__autoload().

更实际的是,如果您的所有文件都位于单个目录中,并且您的应用程序不仅使用.php文件,而且使用.inc扩展名的自定义配置文件,那么您可以使用的一种策略是添加包含所有文件的目录.文件到PHP的包含路径(via set_include_path()).
由于您还需要配置文件,因此您将使用spl_autoload_extensions()列出希望PHP查找的扩展名.

例:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();
Run Code Online (Sandbox Code Playgroud)

由于spl_autoload是__autoload()魔术方法的默认实现,因此当您尝试实例化新类时,PHP将调用spl_autoload.

希望这可以帮助...

  • 这可能是有史以来答案史上最好的答案之一.尊重.我有一个"OMG!现在一切都有意义!" 因为你,我的好人.我想我可能会成立一个粉丝俱乐部. (31认同)
  • @Just Plain High我没有遇到这个问题,我的所有课程文件都来了.顺便说一句,这是一个很好的答案.它帮助我了解了一个简单的概念,直到我读完这篇文章之后我才能理解!我的85(和不断增长的)行包含包含我所有类文件的文件现在是7行! (6认同)
  • 为了使它成为所有答案中的最佳答案,即使在备用宇宙中,请添加 spl_autoload 非常,嗯,“有用”(?)将所有文件名转换为小写(请参阅下面我对@user 的评论)。如果您喜欢 CapitalLettersAndStuff,则不能使用 spl_autoload_register() vanilla。 (2认同)
  • 这确实是一个很好的答案,但我缺少一件事.什么是实际的默认功能?对于我知道的类,它使用命名空间作为路径和类名作为文件名.虽然我无法弄清楚它是如何与函数一起工作的. (2认同)
  • 使用`spl_autoload_register()`(以及`__autoload()`一般来说)延迟加载包含文件/类不是一个很大的好处吗?答案暗示了这一点,但没有明确说明.对我来说,这是关键信息,非常适合包含在你的答案中!:) (2认同)

小智 12

从PHP 5.3开始,您可以使用spl_autoload_register()命名空间,这意味着您可以组织项目并自动加载您的php类,而无需任何要求或包含,也无需重新定义__autoload()函数.

要演示此行为,只需创建一个名为index.php的文件:

<?php
spl_autoload_register();
var_dump(new Main\Application);
Run Code Online (Sandbox Code Playgroud)

然后在index.php文件旁边创建一个名为Main的文件夹.最后,创建一个名为Application.php的文件,该文件位于Main中,并将以下代码粘贴到其中:

<?php namespace Main;
class Application{}
Run Code Online (Sandbox Code Playgroud)

  • 我摆弄所有这些的注释:spl_autoload() - 因此spl_autoload_register() - 将文件名转换为*小写*(尽管有bug报告,请求和激烈的投票).这意味着*你*可能正在寻找"Main\Application"但是spl_autoload正在寻找"main\application".如果你像我一样喜欢骆驼,你将不得不编写自己的功能.这里有一个很好的入门示例:https://github.com/ircmaxell/PHP-CryptLib/blob/37febc046ad23beec1a728f950903b8c3f5aa383/lib/CryptLib/bootstrap.php (9认同)