thinkphp學習筆記9—自動加載


1.命名空間自動加載

在3.2版本中不需要手動加載類庫文件,可以很方便的完成自動加載。

系統可以根據類的命名空間自動定位到類庫文件,例如定義了一個類Org\Util\Auth類:

namespace Org\Util;
class Auth {
}

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

這樣我們就可以直接實例化了,

new \Org\Util\Auth();

實例化之后系統會自動加載

ThinkPHP/Library/Org/Util/Auth.class.php 

框架Liberary目錄下的命名空間都可以自動識別和定位,如下

  1. Library 框架類庫目錄
  2. ├─Think 核心Think類庫包目錄
  3. ├─Org Org類庫包目錄
  4. ├─ ... 更多類庫目錄

Library目錄下的子目錄都是一個根命名空間,就是說Think,Org下的類都可以自動加載

new Think\Cache\Driver\File();
new Org\Util\Auth();
new Org\Io\File();

都可以自動加載對應的類庫文件。

我們還可以在Liberary目錄下面任意增加新的目錄,就會自動注冊成為一個新的根命名空間,如下:

'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目錄下面,並且沒有定義對應的AUTO_LOADNAMESPACE參數的話則會當做模塊的命名空間自動加載,例如

new Home\Model\UserModel();
new Home\Event\UserEvent();

這跳躍有點大,剛才講的還是Liberary下的命名空間,現在又扯到Application下的。

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

Application/Home/Model/UserModel.class.php
Application/Home/Event/UserEvent.class.php

這些命名空間貌似都是ThinkPHP\Liberary目錄下的,這個目錄下的東西一般不會修改的啊,不明白為什么沒有說Application目錄下的命名空間。

2.類庫映射

定義了較多的命名空間效率會有所影響,可以給常用的類庫定義類庫映射,命名空間映射相當於給類文件定義了一個別名,例如:

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);

文檔中依舊沒有說明這段應該寫在什么地方,是config.php還是入口文件里呢,捉急啊。

3.類庫加載的優先級

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

1.判斷是否注冊了Test\MyClass類庫映射,如果有則自動加載類庫映射定義的文件,

2.判斷是否存在Liberary\Test目錄,有則以該目錄為初始目錄加載

3.判斷是否注冊了Test根命名空間,有則以注冊的目錄為初始目錄加載

4.以上都不成立則以Test模塊模塊經行初始目錄加載,

 

4.手動加載第三方類庫

使用第三方類庫的時候可能出現以下情況,不符合ThinkPHP命名空間和后綴,沒有使用命名空間或者命名空間和路徑不一致,我們可以使用手動導入的方式加載。

我們使用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,以及Liberary目錄下的子目錄,這不扯犢子啊,Think,Org,Com,Behavior,Vendor就在ThinkPHP\Liberary下,文檔中所說的Liberary目錄是指那個目錄呢?哦,有可能文檔中所說的是Liberary目錄下自己新建的目錄,有可能。

如果在Liberary目錄下新建了一個Test目錄,並創建了一個UserTest.class.php文件可以這樣導入:

import('Test.UserTest');

注意如果沒有使用namespace來定義命名空間的話,實例化的時候需要使用根命名空間,如下:

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可以自動識別導入類庫文件的位置,特殊情況下需要第二個參數來指定起始導入的路徑,例如:要導入當前文件所在目錄下的RBAC/AccessDecisionManager.class.php 文件,可以使用import("RBAC.AccessDecisionManager",dirname(__FILE__)); 。 如果要導入的文件后綴不是class.php而是.php,可以使用第三個參數import("RBAC.AccessDecisionManager",dirname(__FILE__),".php");

 

如果第三方的類庫放在Vendor目錄下,以.php為文件后綴,也沒有采用命名空間可以采用系統內部的Vendor函數簡化導入,例如我們要把Zend的Filter\Dir.php放到Vendor目錄下面,這個時候Dir文件的路徑就是Vendor\Zend\Filter\Dir.php,使用Vendor方法導入如下:

Vendor('Zend.Filter.Dir');

Vendor方法也可以支持和import一樣的基礎路徑和文件后綴參數,如下:

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

 

感覺高上大的,這些貌似是對系統進行擴展的時候使用的比較多。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM