类加载器

最后更新于:2022-04-02 05:14:05

[TOC] # 类加载器 `Phalcon\Loader` 允许您根据某些预定义规则自动加载项目类。由于此组件是用C语言编写的,因此它在读取和解释外部PHP文件时提供的开销最低。 此组件的行为基于PHP的[自动加载类](http://www.php.net/manual/en/language.oop5.autoload.php)的功能。 如果在代码的任何部分中使用了尚不存在的类,则特殊处理程序将尝试加载它。 `Phalcon\Loader` 充当此操作的特殊处理程序。 通过在需要加载的基础上加载类,整体性能得以提高,因为发生的唯一文件读取是针对所需的文件。这种技术称为[延迟初始化](http://en.wikipedia.org/wiki/Lazy_initialization)。 使用此组件,您可以从其他项目或供应商加载文件,此自动加载器符合[PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)和[PSR-4](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4.md)标准。 `Phalcon\Loader` 提供四种自动加载类选项。您可以一次使用一个或组合它们。 ## 安全层 `Phalcon\Loader` 提供默认类名称的安全层清理,避免包含未经授权的文件。请考虑以下示例: ```php registerNamespaces( [ 'Example\Base' => 'vendor/example/base', 'Example\Adapter' => 'vendor/example/adapter', 'Example' => 'vendor/example', ] ); // 注册自动加载器 $loader->register(); // 所需的类将自动包含文件 vendor/example/adapter/Some.php $some = new \Example\Adapter\Some(); ``` ## 注册目录 第三种选择是注册可以找到类的目录。在性能方面不建议使用此选项,因为Phalcon需要在每个文件夹上执行大量文件统计信息,查找与该类名称相同的文件。按相关顺序注册目录很重要。 ```php registerDirs( [ 'library/MyComponent', 'library/OtherComponent/Other', 'vendor/example/adapters', 'vendor/example', ] ); // 注册自动加载器 $loader->register(); // 所需的类将自动包含它所在的第一个目录中的文件,即 library/OtherComponent/Other/Some.php $some = new \Some(); ``` ## 注册类 最后一个选项是注册类名及其路径。当项目的文件夹约定不允许使用路径和类名称轻松检索文件时,此自动装带器非常有用。这是最快的自动加载方法。但是,您的应用程序越多,需要向此自动加载器添加的类/文件越多,这将有效地使类列表的维护非常麻烦,不建议这样做。 ```php registerClasses( [ 'Some' => 'library/OtherComponent/Other/Some.php', 'Example\Base' => 'vendor/example/adapters/Example/BaseClass.php', ] ); // 注册自动加载器 $loader->register(); // 要求类将自动包含它在关联数组中引用的文件,即 library/OtherComponent/Other/Some.php $some = new \Some(); ``` ## 注册文件 您还可以注册`non-classes` 的文件,因此需要一个`require`。这对于包含仅具有以下功能的文件非常有用: ```php registerFiles( [ 'functions.php', 'arrayFunctions.php', ] ); // 注册自动加载器 $loader->register(); ``` 这些文件自动加载到 `register()` 方法中。 ## 其他文件扩展名 一些自动加载策略(如前缀,名称空间或目录)会自动将php扩展名附加到选中文件的末尾。如果您使用其他扩展,则可以使用方法`setExtensions`进行设置。按照定义的顺序检查文件: ```php setExtensions( [ 'php', 'inc', 'phb', ] ); ``` ## 文件检查回调 您可以通过使用`setFileCheckingCallback`方法设置不同的文件检查回调方法来加速加载器。 默认行为使用`is_file`。但是,您也可以使用`null`,在加载文件之前不会检查文件是否存在,或者您可以使用比`is_file`快得多的`stream_resolve_include_path`,但如果从文件系统中删除目标文件,则会导致问题。 ```php setFileCheckingCallback("is_file"); // Faster than `is_file()`, but implies some issues if // the file is removed from the filesystem. $loader->setFileCheckingCallback("stream_resolve_include_path"); // Do not check file existence. $loader->setFileCheckingCallback(null); ``` ## 修改当前策略 通过将true作为第二个参数传递,可以将其他自动加载数据添加到现有值: ```php registerDirs( [ '../app/library', '../app/plugins', ], true ); ``` ## 自动加载事件 在以下示例中,`EventsManager`正在使用类加载器,允许我们获取有关操作流程的调试信息: ```php registerNamespaces( [ 'Example\Base' => 'vendor/example/base', 'Example\Adapter' => 'vendor/example/adapter', 'Example' => 'vendor/example', ] ); // 听取所有加载的events $eventsManager->attach( 'loader:beforeCheckPath', function (Event $event, Loader $loader) { echo $loader->getCheckedPath(); } ); $loader->setEventsManager($eventsManager); $loader->register(); ``` 返回布尔值false时的某些事件可能会停止活动操作。支持以下事件: | 事件名称 | Triggered | Can stop operation? | | ------------------ | ------------------------------------------------------------------------------------------------------------------- | ------------------- | | `beforeCheckClass` | 在开始自动加载过程之前触发 | Yes | | `pathFound` | 当加载程序找到一个类时触发 | No | | `afterCheckClass` | 完成自动加载过程后触发。如果启动此事件,则自动装带器未找到类文件 | No | ## 故障排除 使用通用自动加载器时要记住的一些事项: * 自动加载过程区分大小写,类将在代码中写入时加载 * 基于名称空间/前缀的策略比目录策略更快 * 如果安装了像[APC](http://php.net/manual/en/book.apc.php) 这样的缓存字节码,这将用于检索所请求的文件(执行文件的隐式缓存)
';