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目錄下的命名空間都可以自動識別和定位,如下
Library 框架類庫目錄
│ ├─Think 核心Think類庫包目錄
│ ├─Org Org類庫包目錄
│ ├─ ... 更多類庫目錄
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');
感覺高上大的,這些貌似是對系統進行擴展的時候使用的比較多。