[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
<?php
// 基礎自動加載器
spl_autoload_register(
function ($className) {
$filepath = $className . '.php';
if (file_exists($filepath)) {
require $filepath;
}
}
);
```
上面的自動加載器缺乏任何安全性。如果函數錯誤地啟動了自動加載器并且惡意準備的字符串被用作參數,則這將允許執行應用程序可訪問的任何文件:
```php
<?php
// 此變量未經過篩選,來自不安全的來源
$className = '../processes/important-process';
// 檢查類是否存在觸發自動加載器
if (class_exists($className)) {
// ...
}
```
如果 `../processes/important-process.php` 是有效文件,則外部用戶可以在未經授權的情況下執行該文件。
為了避免這些或最復雜的攻擊, `Phalcon\Loader` 會從類名中刪除無效字符,從而降低受到攻擊的可能性。
## 注冊命名空間
如果您使用命名空間或使用外部庫來組織代碼,則`registerNamespaces()`方法提供自動加載機制。它需要一個關聯數組;鍵是名稱空間前綴,它們的值是類所在的目錄。當加載程序嘗試查找類時,名稱空間分隔符將被目錄分隔符替換。
```php
<?php
use Phalcon\Loader;
// 創建自動加載器
$loader = new Loader();
// 注冊命名空間
$loader->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
<?php
use Phalcon\Loader;
// 創建自動加載器
$loader = new Loader();
// 注冊目錄
$loader->registerDirs(
[
'library/MyComponent',
'library/OtherComponent/Other',
'vendor/example/adapters',
'vendor/example',
]
);
// 注冊自動加載器
$loader->register();
// 所需的類將自動包含它所在的第一個目錄中的文件,即 library/OtherComponent/Other/Some.php
$some = new \Some();
```
## 注冊類
最后一個選項是注冊類名及其路徑。當項目的文件夾約定不允許使用路徑和類名稱輕松檢索文件時,此自動裝帶器非常有用。這是最快的自動加載方法。但是,您的應用程序越多,需要向此自動加載器添加的類/文件越多,這將有效地使類列表的維護非常麻煩,不建議這樣做。
```php
<?php
use Phalcon\Loader;
// 創建自動加載器
$loader = new Loader();
// 注冊類
$loader->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
<?php
use Phalcon\Loader;
// 創建自動加載器
$loader = new Loader();
// 注冊文件
$loader->registerFiles(
[
'functions.php',
'arrayFunctions.php',
]
);
// 注冊自動加載器
$loader->register();
```
這些文件自動加載到 `register()` 方法中。
## 其他文件擴展名
一些自動加載策略(如前綴,名稱空間或目錄)會自動將php擴展名附加到選中文件的末尾。如果您使用其他擴展,則可以使用方法`setExtensions`進行設置。按照定義的順序檢查文件:
```php
<?php
use Phalcon\Loader;
// 創建自動加載器
$loader = new Loader();
// 設置要檢查的文件擴展名
$loader->setExtensions(
[
'php',
'inc',
'phb',
]
);
```
## 文件檢查回調
您可以通過使用`setFileCheckingCallback`方法設置不同的文件檢查回調方法來加速加載器。
默認行為使用`is_file`。但是,您也可以使用`null`,在加載文件之前不會檢查文件是否存在,或者您可以使用比`is_file`快得多的`stream_resolve_include_path`,但如果從文件系統中刪除目標文件,則會導致問題。
```php
<?php
// Default behavior.
$loader->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
<?php
// 添加更多目錄
$loader->registerDirs(
[
'../app/library',
'../app/plugins',
],
true
);
```
<a name='events'></a>
## 自動加載事件
在以下示例中,`EventsManager`正在使用類加載器,允許我們獲取有關操作流程的調試信息:
```php
<?php
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Loader;
$eventsManager = new EventsManager();
$loader = new Loader();
$loader->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) 這樣的緩存字節碼,這將用于檢索所請求的文件(執行文件的隱式緩存)
- 常規
- Welcome
- 貢獻
- 生成回溯
- 測試重現
- 單元測試
- 入門
- 安裝
- Web服務器設置
- WAMP
- XAMPP
- 教程
- 基礎教程
- 教程:創建一個簡單的REST API
- 教程:V?kuró
- 提升性能
- 教程:INVO
- 開發環境
- Phalcon Compose (Docker)
- Nanobox
- Phalcon Box (Vagrant)
- 開發工具
- Phalcon開發者工具的安裝
- Phalcon開發者工具的使用
- 調試應用程序
- 核心
- MVC應用
- 微應用
- 創建命令行(CLI)應用程序
- 依賴注入與服務定位
- MVC架構
- 服務
- 使用緩存提高性能
- 讀取配置
- 上下文轉義
- 類加載器
- 使用命名空間
- 日志
- 隊列
- 數據庫
- 數據庫抽象層
- Phalcon查詢語言(PHQL)
- ODM(對象文檔映射器)
- 使用模型
- 模型行為
- ORM緩存
- 模型事件
- 模型元數據
- 模型關系
- 模型事務
- 驗證模型
- 數據庫遷移
- 分頁
- 前端
- Assets管理
- 閃存消息
- 表單
- 圖像
- 視圖助手(標簽)
- 使用視圖
- Volt:模板引擎
- 業務邏輯
- 訪問控制列表(ACL)
- 注解解析器
- 控制器
- 調度控制器
- 事件管理器
- 過濾與清理
- 路由
- 在session中存儲數據
- 生成URL和路徑
- 驗證
- HTTP
- Cookies管理
- 請求環境
- 返回響應
- 安全
- 加密/解密
- 安全
- 國際化
- 國際化
- 多語言支持