以下由我們在信易網絡公司開發項目的時候終結出的一些經驗
使用Yii框架中遇到的三個問題
1、main.php文件中欲引入全局變量的問題
還原一下此問題:在Yii框架中,main.php一般會作為整個應用的配置文件,保存Application的各種參數,直接return數組。在使用的過程中,因為main.php文件一定會被Yii提前加載,所以將一些全局性的操作也放在了此文件,加載一些類操作啥的沒有什麼問題,當有一次加了一個全局變量,並且在其它地方使用global獲取全局變量時,發現無論我如何努力都得到的是NULL。各種嘗試後,終於,把引入的位置放在入口文件index.php,得以解決。什麼原因?我們重現一下Yii的main.php文件加載。如下代碼
index.php文件:
class CApp {
public function __construct($config) {
$config = require($config);
}
}
$path = "main.php";
$app = new CApp($path);
global $global;
var_dump($global);
main.php文件:
<?php
$global = array(1, 2, 3);
return array();
兩個文件放在同一目錄,直接運行index.php,輸出的$global為NULL,如果我們在CApp的構造函數中直接輸出$global,則會有結果輸出。什麼原因?作用域的問題!
當我們在main.php文件中定義了一個變量,雖然是想將其作為全局變量使用,但是當我們在局部的作用域中require時,其僅僅作為一個局部作用域的變量存在。我們在TIPI中有說到函數調用是嵌套的,每個嵌套都會有一個作用域,在這個作用域中的變量僅在當前有效,嵌套結束,變量生命周期結束。
因此,我們如果想把main.php中的全局變量真的作為整個應用的全局變量使用,則需要在入口文件的作用域中require main.php文件。
2、引入第三方擴展時的class_exists問題
Yii框架Yii基於PHP5的autoload機制來提供類的自動加載功能,自動加載器為YiiBase類的靜態方法autoload()。當程序中用new創建對象或訪問到類的靜態成員,PHP將類名傳遞給類加載器,由類加載器完成類文件的include。但是如果我們引入了第三方擴展,而第三方擴展的命名規則和Yii的不一樣,於是我們會經常看到報錯說 require XXX 文件失敗。如果你在google中搜索“yii framework class_exists”,你會發現Yii框架的作用Xue Qiang有回答使用者可以通過使用類似於: class_exists(’MyClass’, false)的方式。
class_exists函數檢查類是否已定義,如果由 class_name 所指的類已經定義,此函數返回 TRUE,否則返回 FALSE。在PHP內核中,此函數會查找當前類表中由 class_name 所指的類是否存在,在查找之前會全部轉化為小寫,所以不會區分大小寫。其第二個參數是指是否使用autoload,默認為使用,此時class_exists函數會先執行autoload,然後再查找執行了autoload後類表中由 class_name 所指的類是否存在。因此我們可以通過設置第二個參數其為FALSE來繞過自動加載。
這可以解決問題,但是如果我們使用的是無法修改的第三方代碼呢?怎麼辦?我自己是簡單的hack了下,在調用第三方的操作之就將需要的類給加載了。
後來又采用了另一種解決方案:直接使用Yii:import的第二個參數,強制加載整個目錄。
3、Yii的錯誤日志
問題就不細述了,只是將生產環境的配置整到了開發環境,於是錯誤看不到了。調整了下日志的規則,就OK了。
Yii對錯誤日志的處理依賴於PHP的set_error_handler函數和set_exception_handler函數。在CApplication的initSystemHandlers方法中有對這兩個函數的處理。
本文由專注於成都網站建設的信易網絡發布,更多關於yii的信息請關注信易網絡隨後的發布,信易網絡的官網http://www.ir58.com