首先,Composer的主要优势在于处理依赖关系(以及你的依赖关系的依赖关系等)。自动加载器只是锦上添花。
问题最好表述为include与自动加载器的比较,这样会更加有趣。
首先,简洁性。使用一种方法,你将不得不在每个文件中使用两个声明:use和include,而使用自动加载器,你只需要声明use语句,然后让自动加载器完成实际加载文件的工作。
此外,性能方面。如果在文件顶部包含或要求需求,那么你将始终加载该文件。使用自动加载器,只有在尝试使用所需类时才会这样做。在尝试实例化或使用任何所需类之前,自动加载器不会访问文件系统并尝试查找所需类,使其更加高效,并且只在实际需要时才执行工作。
以下是一个相当粗略的例子:
use Namespace\Package\Service\ServiceProvider
use Namespace\Package\Exception\ServiceProviderException
if (isset($options['service_id'])) {
try {
$service = ServiceProvider::getService($options['service_id']);
}
catch (ServiceProviderException $e) {
// do your exception handling
}
}
else {
// and now for something entirely different
}
通过这种方式,只有在实际满足要求时才会加载声明
ServiceProvider
的文件,只有在需要捕获异常时才会加载声明
ServiceProviderException
的文件(尽管公平地说,当
ServiceProvider
需要
throw
该异常时,自动加载程序会将其包含进来,而不是之前)。
此外,你还可以更好地分离关注点。需要使用
NameSpace\Package\ClassB
的 ClassA 不需要知道你实际上存储该文件的位置。这不是它的工作,也不应关心文件系统的实际结构,使代码更具可移植性。如果其他人拥有与你不同的
vendor
结构,仍然可以轻松使用你的代码,只需使用自动加载程序,而不是在
require
语句中硬编码文件路径。
这应该足以向您展示,相对于手动“包含”要求,自动加载是一种更现代、更高效、更具可移植性的工作方式。
既然你已经使用 composer 来处理你的依赖关系,这真是太棒了,你免费享受到了自动加载程序的好处!