level-2/axel

具有内置缓存的自动加载器

1.0-RC1 2019-02-19 15:55 UTC

This package is auto-updated.

Last update: 2024-09-14 02:51:47 UTC


README

一个模块化、可扩展、快速、超轻量级的PHP自动加载器,具有内置缓存

设计理念

Axel速度快但灵活。Axel通过自动构建内部类映射(实际上就是一个文件名=>类名的映射,因此require语句变为require $classMap[$className])来缓存路径。这个类映射可以在请求之间缓存,这意味着大多数请求无需寻找文件。

Axel可以通过模块扩展来定位不在类映射中的类。一旦模块提供了给定类的文件位置,该路径就会被缓存,并且模块将不再被加载。除非项目中新增加了类,否则Axel只加载一个类,该类通过数组键查找来读取路径。

这种方法比composer快得多且更灵活,因为可以编写自定义模块,而它们的速度无关紧要。即使基于类名定位文件很慢,也只发生在添加类时一次。之后,Axel存储结果。这种方法允许使用像不区分大小写的PSR-4风格加载器之类的功能。

使用方法

要使用Axel,首先将axel.php包含到您的项目中,并创建一个\Axel\Axel.php的实例。

require_once 'axel/axel.php';
$axel = new \Axel\Axel;

单独的Axel除了注册自动加载器之外什么都不做。一旦初始化,您可以通过向其中添加模块来告诉它文件的位置。

注意:Axel实例是不可变的,添加模块可以通过addModule方法完成。

$axel = $axel->addModule($moduleName);

完全配置自动加载器后,您需要注册它。

require_once 'axel/axel.php';
$axel = new \Axel\Axel;
$axel = $axel->addModule($moduleName);
$axel->register();

模块:PSR4

PSR4模块允许您将命名空间映射到目录,例如,如果您有一个在./lib/mylibrary/的项目,您可以使用以下方法将命名空间MyLibrary映射到目录:

$axel = $axel->addModule(new \Axel\Module\PSR4('./lib/MyLibrary', '\\MyLibrary'));

然后,当自动加载器被触发时

new \MyLibrary\Foo();

Axel现在将尝试加载文件./lib/MyLibrary/Foo.php

PSR4也可以更广泛地应用,因此您不需要为每个使用的库创建一个PSR4实例。如果所有库都在./lib中,您可以映射根命名空间到目录,这样一切都会正常工作

$axel =  $axel->addModule(new \Axel\Module\PSR4('./lib/'));

这将添加./lib作为根目录

new \MyLibrary\Foo();
new \MyOtherLibrary\Bar\Baz();

将加载文件./lib/MyLibrary/Foo.php./lib/MyOtherLibrary/Bar/Baz.php

大小写敏感性

由于通常不推荐使自动加载器区分大小写,Axel在可能的情况下以不区分大小写的方式工作。

$axel = $axel->addModule(new \Axel\Module\PSR4('./lib/'));

new \MyLibrary\Foo();

将在文件./lib/MyLibrary/Foo.php中查找类,但如果该文件不存在,它将检查是否存在小写版本的文件./lib/mylibrary/foo.php并加载该文件。

这是一个两全其美的方法,因为它支持使用广泛而善意但错误的PSR-4标准强制大小写敏感性的库,以及使用小写文件名的库。

与composer不同,这允许您为项目的任何部分注册PSR4自动加载器,而无需编写额外的自动加载器。

$axel = $axel->addModule(new \Axel\Module\PSR4('./Conf', '\\Conf'));
$axel = $axel->addModule(new \Axel\Module\PSR4('./Models', '\\Models'));
$axel = $axel->addModule(new \Axel\Module\PSR4('./Controllers', '\\OnlineShop\\Controllers'));

模块:Composer

Axel包含一个模块,允许读取composer.json,以便可以轻松访问通过composer安装的模块。

这是composer自动加载器的替代品。它速度更快,并允许您使用Axel(注意:目前仅支持PSR-4,不支持classmap!)来加载通过composer安装的库,而不使用composer的autoload.php,为项目中的所有内容提供单个自动加载器。

只需加载模块,并告诉Axel包含您的composer.json的目录路径。这将递归地加载所有供应商的composer.json文件,并将它们与自动加载器注册。

$axel =  $axel->addModule(\Axel\Module\Composer($axel, './project'));

编写自定义模块

您可以通过实现类似于以下所示的通用\Autoload\Module接口来编写自己的自动加载模块

namespace Axel;
interface Module {
	public function locate($className);
}

实现此接口的任何类都必须提供locate方法的实现。自动加载器会调用locate方法,并传递要查找的类名。如果该文件是库的一部分,则应返回文件路径;如果不是,则返回false。在最简单的术语中,模块可能看起来像这样

namespace MyLibrary;
class MyAutoloader implements \Axel\Module {
	public function locate($className) {
		if ($className == 'MyClass') return __DIR__ . DIRECTORY_SEPARATOR . 'MyClass.php';
		else if ($className == 'OtherClass') return __DIR__ . DIRECTORY_SEPARATOR . 'OtherClass.php';
		else return false;
	}

}

缓存

Axel支持缓存。当启用缓存时,如果之前已检索到结果,则不会调用module::locate。当使用autoload.json时,只有在库中的文件之前未进行自动加载之前,才会解析该文件。

要启用缓存,创建一个实现\ArrayAccess的缓存类。或者,可以查看SimpleCache的示例。

要使用axel缓存,初始化缓存类

require_once 'SimpleCache.php';
$simpleCache = new \SimpleCache\SimpleCache('./tmp');

然后,将缓存实例作为Axel构造函数的参数传递

$axel = new \Axel\Axel($simpleCache);

Axel现在将后台缓存任何路径。每次加载类时,都会将其路径缓存起来,这样在脚本下一次运行时就不需要再次定位。

您可以将任何使用\ArrayAccess的实例传递给您的缓存,后台这可能使用memcached、数据库或任何其他缓存格式,例如JSON或XML。