在本文中,我们将讨论 php 中自动加载的基础知识以及如何使用 Composer 自动加载 PHP 类。我将解释为什么自动加载如此重要,并逐步向您展示如何使用 Composer 进行自动加载。我还将解释 Composer 中不同类型的自动加载之间的区别。
为什么我们需要自动加载?
当您构建 PHP 应用程序时,您可能需要使用第三方库。如您所知,如果您想在您的应用程序中使用这些库,您需要通过 usingrequire或include语句将它们包含在您的源文件中。
只要您正在开发小型应用程序,这些 require或语句就可以了。include但是随着你的应用程序的增长,requireorinclude语句的列表变得越来越长,这有点烦人并且难以维护。这种方法的另一个问题是您在应用程序中加载了整个库,包括您甚至没有使用的部分。这会导致您的应用程序占用更大的内存。
为了克服这个问题,理想的做法是仅在实际需要时才加载类。这就是自动加载的用武之地。基本上,当您在应用程序中使用一个类时,自动加载器会检查它是否已经加载,如果没有,自动加载器会将必要的类加载到内存中。因此,类会在需要的地方即时加载——这称为自动加载。当您使用自动加载时,您不需要手动包含所有库文件;您只需要包含包含自动加载逻辑的自动加载器文件,必要的类将被动态包含。
在本文后面,我们将介绍使用 Composer 进行自动加载。但首先,我将解释如何在没有Composer 的情况下在 PHP 中实现自动加载。
没有 Composer 的自动加载如何工作
您可能没有意识到这一点,但是可以在没有 Composer 的情况下在 PHP 中实现自动加载。该 spl_autoload_register()功能使这成为可能。该spl_autoload_register()函数允许您注册将放入队列中的函数,以便在 PHP 尝试加载尚未加载的类时按顺序触发。
让我们快速通过以下示例来了解它是如何工作的。
<?php function custom_autoloader($class) { include 'lib/' . $class . '.php'; } spl_autoload_register('custom_autoloader'); $objFooBar = new FooBar(); ?>
在上面的示例中,我们custom_autoloader()使用该函数将该函数注册为我们的自定义自动加载器spl_autoload_register()。接下来,当您尝试实例化FooBar该类但它尚不可用时,PHP 将依次执行所有已注册的自动加载器函数。因此该custom_autoloader函数被调用——它包含必要的类文件,最后实例化了对象。对于这个例子,我们假设 FooBar类是在lib/FooBar.php文件中定义的。
如果没有自动加载,您将需要使用require orinclude语句来包含FooBar类文件。在上面的示例中,自动加载器的实现非常简单,但是您可以通过为不同类型的类注册多个自动加载器来构建它。
但实际上,您不会经常编写自己的自动加载器。这就是 Composer 的用途!在下一节中,我们将讨论如何在 PHP 中使用 Composer 进行自动加载。
自动加载如何与 Composer 一起工作
首先,如果您想按照示例进行操作,请确保在您的系统上安装 Composer 。在使用 Composer 进行自动加载时,您可以选择不同的方法。
具体来说,Composer 提供了四种不同的自动加载文件方法:
文件自动加载
类图自动加载
PSR-0 自动加载
PSR-4 自动装弹
根据官方 Composer 文档,PSR-4 是推荐的自动加载方式,我们将在下一节中详细介绍。在本节中,我们将简要讨论其他三个选项。
在我们继续之前,让我们快速浏览一下您想要使用 Composer 自动加载时需要执行的步骤。
在项目或库的根目录中定义composer.json文件。它应该包含基于自动加载类型的指令。
运行composer dump-autoload命令以生成 Composer 将用于自动加载的必要文件。
require 'vendor/autoload.php'在要使用自动加载的文件顶部包含语句。
自动加载:files指令
文件自动加载的工作方式类似于include或require允许您加载整个源文件的语句。files每次运行应用程序时都会加载该指令引用的所有源文件。这对于加载不使用类的源文件很有用。
要使用文件自动加载,请在composer.jsonfiles文件的指令中提供文件列表,如以下代码段所示。
{ "autoload": { "files": ["lib/Foo.php", "lib/Bar.php"] } }
如您所见,我们可以在files指令中提供我们希望使用 Composer 自动加载的文件列表。使用上述内容在项目根目录中创建composer.json文件后,您只需运行composer dump-autoload 命令即可创建必要的自动加载器文件。这些将在供应商目录下创建。最后,您需要require 'vendor/autoload.php' 在要使用 Composer 自动加载文件的文件顶部包含该语句,如以下代码段所示。
<?php require 'vendor/autoload.php'; // code which uses things declared in the "lib/Foo.php" or "lib/Bar.php" file ?>
该require 'vendor/autoload.php'语句确保动态加载必要的文件。
自动加载:classmap指令
Classmap 自动加载是文件自动加载的改进版本。您只需要提供目录列表,Composer 就会扫描这些目录中的所有文件。对于每个文件,Composer 将列出该文件中包含的类,并且每当需要这些类中的一个时,Composer 将自动加载相应的文件。
让我们快速修改composer.json文件来演示类映射自动加载器。
{ "autoload": { "classmap": ["lib"] } }
运行该composer dump-autoload命令,Composer 将读取lib目录中的文件以创建可自动加载的类映射。
自动装弹:PSR-0
PSR-0 是 PHP-FIG 组推荐的自动加载标准。在 PSR-0 标准中,您必须使用命名空间来定义您的库。完全限定的类名必须反映\<Vendor Name>\(<Namespace>\)*<Class Name>结构。此外,您的类必须保存在遵循与命名空间相同的目录结构的文件中。
我们来看看下面的composer.json文件。
{ "autoload": { "psr-0": { "Tutsplus\\Library": "src" } } }
在 PSR-0 自动加载中,您需要将命名空间映射到目录。在上面的示例中,我们告诉 Composer 以Tutsplus\Library命名空间开头的任何内容都应该在src\Tutsplus\Library目录中可用。
例如,如果要在src\Tutsplus\LibraryFoo目录中定义类,则需要创建src\Tutsplus\Library\Foo.php 文件,如以下代码段所示:
<?php namespace Tutsplus\Library; class Foo { //... } ?>
如您所见,这个类是在Tutsplus\Library命名空间中定义的。此外,文件名对应于类名。让我们快速看看如何自动加载Foo类。
<?php require 'vendor/autoload.php'; $objFoo = new Tutsplus\Library\Foo(); ?>
Composer 将从src\Tutsplus\Library目录中自动加载Foo类。
以上就是 Composer 中文件、类映射和 PSR-0 自动加载的简要说明。在下一节中,我们将了解 PSR-4 自动加载的工作原理。
PSR-4 自动加载如何与 Composer 配合使用
在上一节中,我们讨论了 PSR-0 自动加载的工作原理。PSR-4 类似于 PSR-0 自动加载,因为您需要使用命名空间,但您不需要使用命名空间来模仿目录结构。
在 PSR-0 自动加载中,您必须将命名空间映射到目录结构。正如我们在上一节中讨论的,如果你想自动加载Tutsplus\Library\Foo类,它必须位于src\Tutsplus\Library\Foo.php。在 PSR-4 自动加载中,您可以缩短目录结构,与 PSR-0 自动加载相比,目录结构要简单得多。
我们将修改上面的例子——看看你是否能发现差异。
这是 composer.json文件在 PSR-4 自动加载时的样子。
{ "autoload": { "psr-4": { "Tutsplus\\Library\\": "src" } } }
需要注意的是,我们在命名空间末尾添加了尾部反斜杠。上面的映射告诉 Composer 以命名空间开头的任何东西都Tutsplus\Library应该在src目录中可用。所以你不需要创建Tutsplus和Library目录。例如,如果您请求Tutsplus\Library\Foo类,Composer 将尝试加载src\Foo.php文件。
重要的是要理解Foo类仍然定义在Tutsplus\Library命名空间下;只是您不需要创建模仿名称空间的目录。src\Foo.php文件的内容将与上一节中的 src \Tutsplus\Library\Foo.php文件的内容相同 。
如您所见,PSR-4 产生了更简单的目录结构,因为您可以省略创建嵌套目录,同时仍使用完整的命名空间。
PSR-4 是推荐的自动加载方式,在 PHP 社区中被广泛接受。如果您还没有这样做,您应该开始在您的应用程序中使用它!
结论
今天,我们讨论了 PHP 中的自动加载。从介绍不同种类的 Composer 自动加载技术开始,我们在文章后半部分详细讨论了 PSR-0 和 PSR-4 自动加载标准。
- 自动加载:files指令
- 自动加载:classmap指令
- 自动装弹:PSR-0