1. 程式人生 > >thinkphp3.2【自動載入】

thinkphp3.2【自動載入】

在3.2中,基本上無需手動載入類庫檔案,你可以很方便的完成自動載入。

名稱空間自動載入

系統可以通過類的名稱空間自動定位到類庫檔案,例如:

我們定義了一個類 Org\Util\Auth 類:

1. namespace Org\Util;

2. class Auth {

3. }

儲存到 ThinkPHP/Library/Org/Util/Auth.class.php

接下來,我們就可以直接例項化了。

1. new \Org\Util\Auth();

在例項化Org\Util\Auth類的時候,系統會自動載入 ThinkPHP/Library/Org/Util/Auth.class.php 檔案。

框架的Library目錄下面的名稱空間都可以自動識別和定位,例如:

1. ├─Library 框架類庫目錄

2.  ├─Think 核心Think類庫包目錄

3.  ├─Org Org類庫包目錄

4.  ├─ ... 更多類庫目錄

Library目錄下面的子目錄都是一個根名稱空間,也就是說以Think、Org為根名稱空間的類都可以自動載入:

1. new Think\Cache\Driver\File();

2. new Org\Util\Auth();

3. new Org\Io\File();

都可以自動載入對應的類庫檔案。

你可以在Library目錄下面任意增加新的目錄,就會自動註冊成為一個新的根名稱空間。

註冊新的名稱空間

除了Library目錄下面的名稱空間之外,我們還可以註冊其他的根名稱空間,例如:

1. 'AUTOLOAD_NAMESPACE' => array(

2. 'My' => THINK_PATH.'My',

3. 'One' => THINK_PATH.'One',

4. )

配置了上面的AUTOLOAD_NAMESPACE後,如果我們例項化下面的類庫

1. new My\Net\IpLocation();

2. new One\Util\Log();

會自動載入對應的類庫檔案

1. ThinkPHP/My/Net/IpLocation.class.php

2. ThinkPHP/One/Util/Log.class.php

如果名稱空間不在Library目錄下面,並且沒有定義對應的

AUTOLOAD_NAMESPACE引數的話,則會當作模組的名稱空間進行自動載入,例如:

1. new Home\Model\UserModel();

2. new Home\Event\UserEvent();

由於ThinkPHP/Library目錄下面不存在Home目錄,也沒在AUTOLOAD_NAMESPACE引數定義Home名稱空間,所以就把Home當成模組名稱空間來識別,所以會自動載入:

1. Application/Home/Model/UserModel.class.php

2. Application/Home/Event/UserEvent.class.php

注意:名稱空間的大小寫需要和目錄名的大小寫對應,否則可能會自動載入失敗。

類庫對映

遵循我們上面的名稱空間定義規範的話,基本上可以完成類庫的自動載入了,但是如果定義了較多的名稱空間的話,效率會有所下降,所以,我們可以給常用的類庫定義類庫對映。命名類庫對映相當於給類檔案定義了一個別名,效率會比名稱空間定位更高效,例如:

1. Think\Think::addMap('Think\Log',THINK_PATH.'Think\Log.php');

2. Think\Think::addMap('Org\Util\Array',THINK_PATH.'Org\Util\Array.php');

也可以利用addMap方法批量匯入類庫對映定義,例如:

1. $map = array('Think\Log'=>THINK_PATH.'Think\Log.php','Org\Util\Array'=>THINK_PATH.'Org\Util\Array.php');

2. Think\Think::addMap($map);

當然,比較方便的方式是我們可以在模組配置目錄下面建立alias.php檔案用於定義類庫對映,該檔案會自動載入,定義方式如下:

1. return array(

2. 'Think\Log' => THINK_PATH.'Think\Log.php',

3. 'Org\Util\Array' => THINK_PATH.'Org\Util\Array.php'

4. );

自動載入的優先順序

在實際的應用類庫載入過程中,往往會涉及到自動載入的優先順序問題,以Test\MyClass類為例,自動載入的優先順序如下:

1. 判斷是否有註冊了Test\MyClass類庫對映,如果有則自動載入類庫對映定義的檔案;

2. 判斷是否存在Library/Test目錄,有則以該目錄為初始目錄載入;

3. 判斷是否有註冊Test根名稱空間,有則以註冊的目錄為初始目錄載入;

4. 如果以上都不成立,則以Test為模組目錄進行初始目錄載入;

以上面獲取到的初始目錄載入名稱空間對應路徑的檔案;

手動載入第三方類庫

如果要載入第三方類庫,包括不符合命名規範和字尾的類庫,以及沒有使用名稱空間或者名稱空間和路徑不一致的類庫,或者你就是想手動載入類庫檔案,我們都可以通過手動匯入的方式載入。

我們可以使用import方法匯入任何類庫,用法如下:

1. // 匯入Org類庫包 Library/Org/Util/Date.class.php類庫

2. import("Org.Util.Date");

3. // 匯入Home模組下面的 Application/Home/Util/UserUtil.class.php類庫

4. import("Home.Util.UserUtil");

5. // 匯入當前模組下面的類庫

6. import("@.Util.Array");

7. // 匯入Vendor類庫包 Library/Vendor/Zend/Server.class.php

8. import('Vendor.Zend.Server');

對於import方法,系統會自動識別匯入類庫檔案的位置,ThinkPHP可以自動識別的類庫包包括Think、Org、Com、Behavior和Vendor包,以及Library目錄下面的子目錄,如果你在Library目錄下面建立了一個Test子目錄,並且建立了一個UserTest.class.php類庫,那麼可以這樣匯入:

1. import('Test.UserTest');

其他的就認為是應用類庫匯入。

注意,如果你的類庫沒有使用名稱空間定義的話,例項化的時候需要加上根名稱空間,例如:

1. import('Test.UserTest');

2. $test = new \UserTest();

按照系統的規則,import方法是無法匯入具有點號的類庫檔案的,因為點號會直接轉化成斜線,例如我們定義了一個名稱為User.Info.class.php 的檔案的話,採用:

1. import("Org.User.Info");

方式載入的話就會出現錯誤,導致載入的檔案不是Org/User.Info.class.php 檔案,而是Org/User/Info.class.php 檔案,這種情況下,我們可以使用:

1. import("Org.User#Info");

來匯入。

大多數情況下,import方法都能夠自動識別匯入類庫檔案的位置,如果是特殊情況的匯入,需要指定import方法的第二個引數作為起始匯入路徑。例如,要匯入當前檔案所在目錄下面的 RBAC/AccessDecisionManager.class.php 檔案,可以使用:

1. import("RBAC.AccessDecisionManager",dirname(__FILE__));

如果你要匯入的類庫檔名的字尾不是class.php而是php,那麼可以使用import方法的第三個引數指定字尾:

1. import("RBAC.AccessDecisionManager",dirname(__FILE__),".php");

注意:在Unix或者Linux主機下面是區別大小寫的,所以在使用import方法的時候要注意目錄名和類庫名稱的大小寫,否則會匯入失敗。

如果你的第三方類庫都放在Vendor目錄下面,並且都以.php為類檔案字尾,也沒用採用名稱空間的話,那麼可以使用系統內建的Vendor函式簡化匯入。 例如,我們把 Zend 的 Filter\Dir.php 放到 Vendor 目錄下面,這個時候 Dir 檔案的路徑就是 Vendor\Zend\Filter\Dir.php,我們使用vendor 方法匯入只需要使用:

1. Vendor('Zend.Filter.Dir');

就可以匯入Dir類庫了。

Vendor方法也可以支援和import方法一樣的基礎路徑和檔名字尾引數,例如:

1. Vendor('Zend.Filter.Dir',dirname(__FILE__),'.class.php');