【小(xiǎo)編推薦】ThinkPHP3.2——自(λ₩↓zì)動加載

2014-06-26   |&∏♣★nbsp;  發布者:梁國(guó)芳 Ω<β;  |   查看(k‌≈↓àn):3320次

Thinkphp

在3.2中,基本上(shàng)無需手動加載類庫✔'文(wén)件(jiàn),你(nǐ)可(kě)≠∏™π以很(hěn)方便的(de)完成自(zì)動加載。

命名空(kōng)間(jiān)自(zì)動加載α₹

系統可(kě)以通(tōng)過類的(de)命名空(kōng)間∞↓λ(jiān)自(zì)動定位到(dào)類庫文₽ε∏(wén)件(jiàn),例如(rú):

我們定義了(le)一(yī)個(gè)類 Org\Util\Auth 類:

  1. namespace Org\Util;
  2. class Auth {
  3. }

保存到(dào) ThinkPHP/Library/Org/Util®₹λ/Auth.class.php

接下(xià)來(lái),我們就(jiù)可(kě)以直接實例<₽γσ化(huà)了(le)。

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

在實例化(huà)Org\Util\Auth類的(de)時(shí)候,系統會(huì)π↓&自(zì)動加載 ThinkPHP/Library/Org/Util/Auth.class.p↔♠↔¶hp 文(wén)件(jiàn)。

框架的(de)Library目錄下(xià)面的(<↔de)命名空(kōng)間(jiān)都(dōu)可(kě)以自(zì)≤γ♦α動識别和(hé)定位,例如(rú):

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

Library目錄下(xià)面的(de)子(zǐ)目錄都(dōuΩ©)是(shì)一(yī)個(gè)根命名空(kōng)間(jiān),也(y↕♦↑ě)就(jiù)是(shì)說(shuō)以Think、Org為(w₩£≈®èi)根命名空(kōng)間(jiān)的(de)類都(dōu→≈"β)可(kě)以自(zì)動加載:

  1. new Think\Cache\Driver\File();
  2. new Org\Util\Auth();
  3. new Org\Io\File();

都(dōu)可(kě)以自(zì)動加載對(duì) ♥ 應的(de)類庫文(wén)件(jiàn)。

你(nǐ)可(kě)以在Library目錄下(x₹₩•γià)面任意增加新的(de)目錄,就(jiù)會(h₹₩uì)自(zì)動注冊成為(wèi)一(yī)£✔個(gè)新的(de)根命名空(kōng)間(jiān)。

注冊新的(de)命名空(kōng)間(jiān)

除了(le)Library目錄下(xià)面的(de)命名空★λ♦(kōng)間(jiān)之外(wài),我們還(hái)可(kě)以注冊其"∑εσ他(tā)的(de)根命名空(kōng)間(jiān),例如(rú):

  1. 'AUTOLOAD_NAMESPACE' => array(
  2. 'My' => THINK_PATH.'My',
  3. 'One' => THINK_PATH.'One',
  4. )

配置了(le)上(shàng)面的(de)AUTOLOAD_NAMESPACE後,如(rú)果我們實例化(huà)下(xià)面的(de)類庫

  1. new My\Net\IpLocation();
  2. new One\Util\Log();

會(huì)自(zì)動加載對(duì)φ₩應的(de)類庫文(wén)件(jiàn)

  1. ThinkPHP/My/Net/IpLocation.class.php
  2. ThinkPHP/One/Util/Log.class.php

如(rú)果命名空(kōng)間(jiān)不(bù)在Libε★rary目錄下(xià)面,并且沒有(y≤ε $ǒu)定義對(duì)應的(de)AUTOLOAD_NAMESPACE參數(shù)的(de)話(huà),則會(huì)當作÷←(zuò)模塊的(de)命名空(kōng)間(j✘↓★iān)進行(xíng)自(zì)動加載,例如(rú):<←± 

  1. new Home\Model\UserModel();
  2. new Home\Event\UserEvent();

由于ThinkPHP/Library目錄下(xià)面不(bù)‍←存在Home目錄,也(yě)沒在AUTOLOAD_NAMESPACE參數(shù)定義Home命名空(kōng"☆★≥)間(jiān),所以就(jiù)把Home當成模塊α÷命名空(kōng)間(jiān)來(lái)識别,所以會(huì)自(zì)÷‌動加載:

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

注意:命名空(kōng)間(jiān)的(★Ωε♦de)大(dà)小(xiǎo)寫需要(yào)♠‌Ω和(hé)目錄名的(de)大(dà)小(xiǎo≥♥)寫對(duì)應,否則可(kě)能(nσ♦éng)會(huì)自(zì)動加載失敗。

類庫映射

遵循我們上(shàng)面的(de)命名空(kōng)間(j ÷iān)定義規範的(de)話(huà),基本上(∞<€shàng)可(kě)以完成類庫的(de)自(zì)γλ↓動加載了(le),但(dàn)是(shì)如(rú)果定義了(lβ☆©e)較多(duō)的(de)命名空(kōng)間(jiā≠÷±n)的(de)話(huà),效率會(huì)有(yǒu)所下(xλ♠Ω→ià)降,所以,我們可(kě)以給常用(yòng)的™∏∏∞(de)類庫定義類庫映射。命名類庫映射相(xiàng)當于給類文(∑←↑wén)件(jiàn)定義了(le)一(yī)個(gè)♣₹≈别名,效率會(huì)比命名空(kōng)間(jiā¥₹←✘n)定位更高(gāo)效,例如(rú):

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

也(yě)可(kě)以利用(yòng)a≈>§£ddMap方法批量導入類庫映射定義,例如(rú):

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

當然,比較方便的(de)方式是(shì)我們可(k₽®→ě)以在模塊配置目錄下(xià)面創建aliaε↔s.php文(wén)件(jiàn)用(yò&↕↕→ng)于定義類庫映射,該文(wén)件(jiàn)會(huì)自(z‍≈ ì)動加載,定義方式如(rú)下(xià):

  1. return array(
  2. 'Think\Log' => THINK_PATH.'Think\Log.php',
  3. 'Org\Util\Array' => THINK_PATH.'Org\Util\Array.php'
  4. );

自(zì)動加載的(de)優先級

在實際的(de)應用(yòng)類庫加載過程₩↕中,往往會(huì)涉及到(dào)自(z☆$<∞ì)動加載的(de)優先級問(wèn)題,以Test\MyClass類為(wèi)例,自(zì)動加載的(dΩ€'e)優先順序如(rú)下(xià):

  1. 判斷是(shì)否有(yǒu)注冊了(le)Test\MyC☆€lass類庫映射,如(rú)果有(yǒu)則自(zì)動加載類庫映射定義←≠的(de)文(wén)件(jiàn);
  2. 判斷是(shì)否存在Library/Test目錄,有(yǒu)則以該目錄為↕∏♠(wèi)初始目錄加載;
  3. 判斷是(shì)否有(yǒu)注冊Test根命♥©名空(kōng)間(jiān),有(yǒu)則以注冊的(deφ₩)目錄為(wèi)初始目錄加載;
  4. 如(rú)果以上(shàng)都(dōu)不(bù)成立,則以Tesε t為(wèi)模塊目錄進行(xíng)初始目錄加£δ ★載;

以上(shàng)面獲取到(dào)的(de)初始目錄加載命名空(ε≠ kōng)間(jiān)對(duì)應路(≠&βlù)徑的(de)文(wén)件(jiàn);

手動加載第三方類庫

如(rú)果要(yào)加載第三方類庫,包括不(bù)符合命名規範和(hé)後綴的(de)類庫,以及沒有( ✘ ∑yǒu)使用(yòng)命名空(kōng)πγ∏∏間(jiān)或者命名空(kōng)間(jiān)和(h ↔≥é)路(lù)徑不(bù)一(yī)緻的(de)類庫,或者你(nǐ)就(jiù)是(shì)想手動加載類庫文(γ>∏≈wén)件(jiàn),我們都(dōu)可(kě)以通(tō±≤£₹ng)過手動導入的(de)方式加載。

我們可(kě)以使用(yòng)import方法導入任何≈↓類庫,用(yòng)法如(rú)下(xià):

  1. // 導入Org類庫包 Library/Org/Util/D≥↔πate.class.php類庫
  2. import("Org.Util.Date&quoσβ¥πt;);
  3. // 導入Home模塊下(xià)面的(de) Application/H≤∞ome/Util/UserUtil.class.p₹£§∏hp類庫
  4. import("Home.Util.UserUti★βl");
  5. // 導入當前模塊下(xià)面的(de)πΩ類庫
  6. import("@.Util.Array");
  7. // 導入Vendor類庫包 Libra¶∞★←ry/Vendor/Zend/Server.class.ph♥©™εp
  8. import('Vendor.Zend.Server');

對(duì)于import方法,系統會(huì)自(zì&∏☆)動識别導入類庫文(wén)件(jiàn↓₽∑)的(de)位置,ThinkPHP可(kě‌₹∞)以自(zì)動識别的(de)類庫包包括Think、Or€±₽εg、Com、 Behavior和(hé)Vendor包,以及↑€☆→Library目錄下(xià)面的(de)子(zǐ)目錄,如(rú)♠™‍果你(nǐ)在Library目錄下(xià)面創建了(le)一(γ™yī)個(gè)Test子(zǐ)目錄,并且創建了(™αle)一(yī)個(gè) UserTest.class.php類≠<÷≥庫,那(nà)麽可(kě)以這(zhè)樣導入:

  1. import('Test.UserTest');

其他(tā)的(de)就(jiù)認為(wèi)是(shì)應用(yònπ±g)類庫導入。

注意,如(rú)果你(nǐ)的(de)類庫沒有(yǒu)使用(yòng)命名 ♦₹空(kōng)間(jiān)定義的(de)話(huà),實例化(huà≠±)的(de)時(shí)候需要(yào)加上(shàng)根命名空(k‍↓₽®ōng)間(jiān),例如(rú):

  1. import('Test.UserTest');
  2. $test = new \UserTest();

按照(zhào)系統的(de)規則,import方法是(shì)無法導入具有<→(yǒu)點号的(de)類庫文(wén)件(jiàσ←n)的(de),因為(wèi)點号會(huì)直接轉化(huà)成斜線,♠δ例如(rú)我們定義了(le)一(yī)個(Ω↓gè)名稱為(wèi)User.Info↕γ₩.class.php 的(de)文(wén ∑)件(jiàn)的(de)話(huà),采用(yòng):

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

方式加載的(de)話(huà)就(jiù)會(hu×γì)出現(xiàn)錯(cuò)誤,導緻加載的(de)文( Ω§wén)件(jiàn)不(bù)是(shì)Org/User.↕Ω •Info.class.php 文(wén₽★)件(jiàn),而是(shì)Org/Use>≠r/Info.class.php 文(wéΩ♥λ>n)件(jiàn),這(zhè)種情況下(xià),我們可(kěε<✘♠)以使用(yòng):

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

來(lái)導入。

大(dà)多(duō)數(shù)情況下(x©δαià),import方法都(dōu)能(néng"∑∑☆)夠自(zì)動識别導入類庫文(wén)件(✘ βjiàn)的(de)位置,如(rú)果是(shì)特殊→↕±σ情況的(de)導入,需要(yào)指定import方法的(d ↓♣​e)第二個(gè)參數(shù)作(zuò)為(wèi)↕∑βε起始導入路(lù)徑。例如(rú),要(yào)導入當前文(wén)件(j₩€§iàn)所在目錄下(xià)面的(de) RBAC/Accessγ≠DecisionManager.class↑↓♦β.php 文(wén)件(jiàn),可≤ ≤♦(kě)以使用(yòng):

  1. import("RBAC.AccessDecisionManag​↕er",dirname(__FILE__));

如(rú)果你(nǐ)要(yào)導入的€>β(de)類庫文(wén)件(jiàn)名的(de)後綴不(bù)是(shì)c↕¥×lass.php而是(shì)php,那(nà)麽可(kě)以使用(yò&♣≥ng)import方法的(de)第三個(gè)參數(sh¶¥ εù)指定後綴:

  1. import("RBAC.AccessDecisionManager&qu£¥ot;,dirname(__FILE__),".php");

注意:在Unix或者Linux主機(jī)下(xià)面是(shìλ ✔‌)區(qū)别大(dà)小(xiǎo)寫的(de),所以在使用(yòng)im≥♣>port方法的(de)時(shí)候要(yào)注意¶™目錄名和(hé)類庫名稱的(de)大(dà)小(xiǎo)寫,否則會 σ(huì)導入失敗。

如(rú)果你(nǐ)的(de)第三方類庫都(dōu)放(fàng)在Vend ↑or目錄下(xià)面,并且都(dōu)以.php為(wèi)類∑γ文(wén)件(jiàn)後綴,也(yě)沒用(y₹♥òng)采用(yòng)命名空(kōng)間(jiān)的(de)話(huà)λφ₹,那(nà)麽可(kě)以使用(yòng)系≠∞統內(nèi)置的(de)Vendor函數(φ""shù)簡化(huà)導入。 例如(rú),我÷×≥♥們把 Zend 的(de) Filter\Dir™₹↓.php 放(fàng)到(dào) Vend∑γ or 目錄下(xià)面,這(zhè)個(gè)∏'時(shí)候 Dir 文(wén)件(jiàn)的₹‍¥★(de)路(lù)徑就(jiù)是(shì) Vendor\Zend\Fi♠φεlter\Dir.php,我們使用(yòng)vendo∞®∏r 方法導入隻需要(yào)使用(yòng):

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

就(jiù)可(kě)以導入Dir類庫了(le)。

Vendor方法也(yě)可(kě)以支持和(hé  ≈)import方法一(yī)樣的(de)基礎路(lù)徑和(hé)文($★​ wén)件(jiàn)名後綴參數(shù),例如(rú):

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