# 自動加載
[上一頁](# "上一頁")[下一頁](# "下一頁")
在3.2中,基本上無需手動加載類庫文件,你可以很方便的完成自動加載。
### 命名空間自動加載
系統可以通過類的命名空間自動定位到類庫文件,例如:
我們定義了一個類 `Org\Util\Auth` 類:
~~~
namespace Org\Util;
class Auth {
}
~~~
保存到 `ThinkPHP/Library/Org/Util/Auth.class.php`。
接下來,我們就可以直接實例化了。
~~~
new \Org\Util\Auth();
~~~
在實例化`Org\Util\Auth`類的時候,系統會自動加載 `ThinkPHP/Library/Org/Util/Auth.class.php` 文件。
框架的Library目錄下面的命名空間都可以自動識別和定位,例如:
~~~
├─Library 框架類庫目錄
│ ├─Think 核心Think類庫包目錄
│ ├─Org Org類庫包目錄
│ ├─ ... 更多類庫目錄
~~~
Library目錄下面的子目錄都是一個根命名空間,也就是說以Think、Org為根命名空間的類都可以自動加載:
~~~
new Think\Cache\Driver\File();
new Org\Util\Auth();
new Org\Io\File();
~~~
都可以自動加載對應的類庫文件。
> 你可以在Library目錄下面任意增加新的目錄,就會自動注冊成為一個新的根命名空間。
### 注冊新的命名空間
除了Library目錄下面的命名空間之外,我們還可以注冊其他的根命名空間,例如:
~~~
'AUTOLOAD_NAMESPACE' => array(
'My' => THINK_PATH.'My',
'One' => THINK_PATH.'One',
)
~~~
配置了上面的`AUTOLOAD_NAMESPACE`后,如果我們實例化下面的類庫
~~~
new My\Net\IpLocation();
new One\Util\Log();
~~~
會自動加載對應的類庫文件
~~~
ThinkPHP/My/Net/IpLocation.class.php
ThinkPHP/One/Util/Log.class.php
~~~
如果命名空間不在Library目錄下面,并且沒有定義對應的`AUTOLOAD_NAMESPACE`參數的話,則會當作模塊的命名空間進行自動加載,例如:
~~~
new Home\Model\UserModel();
new Home\Event\UserEvent();
~~~
由于ThinkPHP/Library目錄下面不存在Home目錄,也沒在`AUTOLOAD_NAMESPACE`參數定義Home命名空間,所以就把Home當成模塊命名空間來識別,所以會自動加載:
~~~
Application/Home/Model/UserModel.class.php
Application/Home/Event/UserEvent.class.php
~~~
> 注意:命名空間的大小寫需要和目錄名的大小寫對應,否則可能會自動加載失敗。
### 類庫映射
遵循我們上面的命名空間定義規范的話,基本上可以完成類庫的自動加載了,但是如果定義了較多的命名空間的話,效率會有所下降,所以,我們可以給常用的類庫定義類庫映射。命名類庫映射相當于給類文件定義了一個別名,效率會比命名空間定位更高效,例如:
~~~
Think\Think::addMap('Think\Log',THINK_PATH.'Think\Log.php');
Think\Think::addMap('Org\Util\Array',THINK_PATH.'Org\Util\Array.php');
~~~
也可以利用addMap方法批量導入類庫映射定義,例如:
~~~
$map = array('Think\Log'=>THINK_PATH.'Think\Log.php','Org\Util\Array'=>THINK_PATH.'Org\Util\Array.php');
Think\Think::addMap($map);
~~~
當然,比較方便的方式是我們可以在模塊配置目錄下面創建alias.php文件用于定義類庫映射,該文件會自動加載,定義方式如下:
~~~
return array(
'Think\Log' => THINK_PATH.'Think\Log.php',
'Org\Util\Array' => THINK_PATH.'Org\Util\Array.php'
);
~~~
### 自動加載的優先級
在實際的應用類庫加載過程中,往往會涉及到自動加載的優先級問題,以`Test\MyClass`類為例,自動加載的優先順序如下:
1. 判斷是否有注冊了Test\MyClass類庫映射,如果有則自動加載類庫映射定義的文件;
1. 判斷是否存在Library/Test目錄,有則以該目錄為初始目錄加載;
1. 判斷是否有注冊Test根命名空間,有則以注冊的目錄為初始目錄加載;
1. 如果以上都不成立,則以Test為模塊目錄進行初始目錄加載;
以上面獲取到的初始目錄加載命名空間對應路徑的文件;
### 手動加載第三方類庫
如果要加載第三方類庫,包括**不符合命名規范和后綴的類庫,以及沒有使用命名空間或者命名空間和路徑不一致的類庫**,或者你就是想手動加載類庫文件,我們都可以通過手動導入的方式加載。
我們可以使用import方法導入任何類庫,用法如下:
~~~
// 導入Org類庫包 Library/Org/Util/Date.class.php類庫
import("Org.Util.Date");
// 導入Home模塊下面的 Application/Home/Util/UserUtil.class.php類庫
import("Home.Util.UserUtil");
// 導入當前模塊下面的類庫
import("@.Util.Array");
// 導入Vendor類庫包 Library/Vendor/Zend/Server.class.php
import('Vendor.Zend.Server');
~~~
對于import方法,系統會自動識別導入類庫文件的位置,ThinkPHP可以自動識別的類庫包包括Think、Org、Com、Behavior和Vendor包,以及Library目錄下面的子目錄,如果你在Library目錄下面創建了一個Test子目錄,并且創建了一個UserTest.class.php類庫,那么可以這樣導入:
~~~
import('Test.UserTest');
~~~
其他的就認為是應用類庫導入。
注意,如果你的類庫沒有使用命名空間定義的話,實例化的時候需要加上根命名空間,例如:
~~~
import('Test.UserTest');
$test = new \UserTest();
~~~
按照系統的規則,import方法是無法導入具有點號的類庫文件的,因為點號會直接轉化成斜線,例如我們定義了一個名稱為User.Info.class.php 的文件的話,采用:
~~~
import("Org.User.Info");
~~~
方式加載的話就會出現錯誤,導致加載的文件不是Org/User.Info.class.php 文件,而是Org/User/Info.class.php 文件,這種情況下,我們可以使用:
~~~
import("Org.User#Info");
~~~
來導入。
大多數情況下,import方法都能夠自動識別導入類庫文件的位置,如果是特殊情況的導入,需要指定import方法的第二個參數作為起始導入路徑。例如,要導入當前文件所在目錄下面的RBAC/AccessDecisionManager.class.php 文件,可以使用:
~~~
import("RBAC.AccessDecisionManager",dirname(__FILE__));
~~~
如果你要導入的類庫文件名的后綴不是class.php而是php,那么可以使用import方法的第三個參數指定后綴:
~~~
import("RBAC.AccessDecisionManager",dirname(__FILE__),".php");
~~~
> 注意:在Unix或者Linux主機下面是區別大小寫的,所以在使用import方法的時候要注意目錄名和類庫名稱的大小寫,否則會導入失敗。
如果你的第三方類庫都放在Vendor目錄下面,并且都以.php為類文件后綴,也沒用采用命名空間的話,那么可以使用系統內置的Vendor函數簡化導入。例如,我們把 Zend 的 Filter\Dir.php 放到 Vendor 目錄下面,這個時候 Dir 文件的路徑就是 Vendor\Zend\Filter\Dir.php,我們使用vendor 方法導入只需要使用:
~~~
Vendor('Zend.Filter.Dir');
~~~
就可以導入Dir類庫了。
Vendor方法也可以支持和import方法一樣的基礎路徑和文件名后綴參數,例如:
~~~
Vendor('Zend.Filter.Dir',dirname(__FILE__),'.class.php');
~~~
[上一頁](# "上一頁")[下一頁](# "下一頁")
- 序言
- 基礎
- 獲取ThinkPHP
- 環境要求
- 目錄結構
- 入口文件
- 自動生成
- 模塊
- 控制器
- 開發規范
- 配置
- 配置格式
- 配置加載
- 讀取配置
- 動態配置
- 擴展配置
- 批量配置
- 架構
- 模塊化設計
- URL模式
- 多層MVC
- CBD模式
- 命名空間
- 自動加載
- 應用模式
- 項目編譯
- 系統流程
- 路由
- 路由定義
- 規則路由
- 正則路由
- 靜態路由
- 閉包支持
- 實例說明
- 控制器
- 控制器定義
- 前置和后置操作
- Action參數綁定
- 偽靜態
- URL大小寫
- URL生成
- AJAX返回
- 跳轉和重定向
- 輸入變量
- 請求類型
- 空操作
- 空控制器
- 操作綁定到類
- 模型
- 模型定義
- 模型實例化
- 字段定義
- 連接數據庫
- 切換數據庫
- 分布式數據庫支持
- 連貫操作
- WHERE
- TABLE
- ALIAS
- DATA
- FIELD
- ORDER
- LIMIT
- PAGE
- GROUP
- HAVING
- JOIN
- UNION
- DISTINCT
- LOCK
- CACHE
- COMMENT
- RELATION
- 命名范圍
- CURD操作
- 數據創建
- 數據寫入
- 數據讀取
- 數據更新
- 數據刪除
- ActiveRecord
- 字段映射
- 查詢語言
- 查詢方式
- 表達式查詢
- 快捷查詢
- 區間查詢
- 組合查詢
- 統計查詢
- SQL查詢
- 動態查詢
- 子查詢
- 自動驗證
- 自動完成
- 參數綁定
- 虛擬模型
- 模型分層
- 視圖模型
- 關聯模型
- 高級模型
- Mongo模型
- 視圖
- 模板定義
- 模板主題
- 模板賦值
- 模板渲染
- 獲取模板地址
- 獲取內容
- 模板引擎
- 模板
- 變量輸出
- 系統變量
- 使用函數
- 默認值輸出
- 使用運算符
- 標簽庫
- 模板繼承
- 修改定界符
- 三元運算
- 包含文件
- 內置標簽
- Volist標簽
- Foreach標簽
- For標簽
- Switch標簽
- 比較標簽
- 范圍判斷標簽
- IF標簽
- Present標簽
- Empty標簽
- Defined標簽
- Assign標簽
- Define標簽
- 標簽嵌套
- import標簽
- 使用PHP代碼
- 原樣輸出
- 模板注釋
- 模板布局
- 模板替換
- 調試
- 調試模式
- 異常處理
- 日志記錄
- 頁面Trace
- Trace方法
- 變量調試
- 性能調試
- 錯誤調試
- 模型調試
- 緩存
- 數據緩存
- 快速緩存
- 查詢緩存
- SQL解析緩存
- 靜態緩存
- 安全
- 輸入過濾
- 表單合法性檢測
- 表單令牌
- 防止SQL注入
- 目錄安全文件
- 保護模板文件
- 上傳安全
- 防止XSS攻擊
- 其他安全建議
- 擴展
- 類庫擴展
- 驅動擴展
- 緩存驅動
- 數據庫驅動
- 日志驅動
- Session驅動
- 存儲驅動
- 模板引擎驅動
- 標簽庫驅動
- 行為擴展
- 標簽擴展
- Widget擴展
- 應用模式
- 部署
- PATH_INFO支持
- URL重寫
- 模塊部署
- 域名部署
- 入口綁定
- 替換入口
- 專題
- SESSION支持
- Cookie支持
- 多語言支持
- 數據分頁
- 文件上傳
- 驗證碼
- 圖像處理
- RESTFul
- RPC
- SAE
- IP獲取和定位
- 附錄
- 常量參考
- 配置參考
- 升級指導
- 更新日志
- 鳴謝
- 關于