用PHP變成最惱人的事情是用include和require加載額外的代碼。幸運的是你可以用SPL類加載器自動完成。
Yii緊緊依靠的就是自加載,當我們使用一個類,譬如,CDbCriteria,我們沒有明確的包含它,所以PHP起初不能找到它,PHP試着依靠自加載特性。準確來說,就是SPL自加載器。在大部分情況下,Yii默認的加載器(YiiBase::autoload)將被用到。
爲了速度和簡單,幾乎所有的核心框架類都是在必要的時候被加載的,而沒有明確的包含或導入它們。它是通過YiiBase::$_coreClasses完成的,所以加載核心類是非常迅速的。Zii類像CMenu,擴展類或者你自己寫的類都不是自動加載的,因此我們需要先導入它們。
使用Yii::import導入類是相當的明智:
- 默認的,導入不是立即包含一個類。
- 沒被使用的類不會被包含。
- 它不會再三的加載一個類,因此你可以放心的導入同一個類很多次。
怎麼做…
- 假設我們有一個自定義的類LyricsFinder,它負責爲給定歌曲找到歌詞。我們已經將它放在protected/apis/lyrics/目錄下了,在我們的TestController 中,我們打算這樣用:
class TestController extends CController
{
public function actionIndex($song)
{
$lyric = 'Nothing was found.';
$finder = new LyricsFinder();
if(!empty($song))
$lyric = $finder->getText($song);
echo $lyric;
}
}
2.當我們執行它時,它報出了一個PHP錯誤,因爲Yii找不到我們的類。我們來修改下代碼:
class TestController extends CController
{
public function actionIndex($song)
{
$lyric = 'Nothing was found.';
// 導入一個類
<span style="color:#FF0000;">Yii::import('application.apis.lyrics.LyricsFinder');</span>
$finder = new LyricsFinder();
if(!empty($song))
$lyric = $finder->getText($song);
echo $lyric;
}
}
3.現在我們的代碼就能正常工作了。
————————————————注:內置的Yii類加載器需要每個類放置在單獨的文件中,這些文件和類名稱一樣。————————————————————————————————————————
我們再來看看上面的application.apis.lyrics.LyricsFinder是怎麼工作的。
application是一個標準別名,指向你應用程序的protected文件夾,它被翻譯成文件系統路徑。下表顯示了更多的標準的別名:
Alias | Path |
---|---|
application | path_to_webroot/protected |
system | path_to_webroot/framework |
zii | path_to_webroot/framework/zii |
webroot | path_to_webroot |
ext | path_to_webroot/protected/extensions |
————————————————注:你可以用Yii::setPathOfAlias方法自己定義你的小應用程序。————————————————————————————————————————————————
apis.lyrics 被轉義成apis/lyrics 並且被附加到從application中獲取的路徑;LyricsFinder是我們想要導入的類名。
我們可以使用Yii::import(‘application.apis.lyrics.*’)來導入整個目錄。 注意* 並不包含子文件夾,因此如果你需要lyrics/includes, 你應該添加另外一條導入語句Yii::import(‘application.apis.lyrics.includes.*).
爲了性能,當你使用一個單獨的類時,使用明確的路徑而不是*比較好。延伸…
如果你想你的類像Yii核心類那樣自動被導入,你可以在配置文件main.php中配置全局導入:
return array(
// ...
// global imports
'import'=>array(
'application.models.*',
'application.components.*',
'application.apis.lyrics.*',
'application.apis.lyrics.includes.*',
'application.apis.albums.AlbumFinder',
),
——————注意,跟使用*一樣,使用大量的全局導入會減慢你的應用執行速度的。——————————
————————————————————————————————————————
________________________________________