爲了更深入地理解MVC範例,我正在試驗構建自己的框架。捕獲自定義spl_autloader函數錯誤的最佳方法
我沒有依賴於由於包含失敗而導致的PHP醜陋錯誤/警告,而是設置了一個通用的異常類,以一種更易讀的格式顯示數據以及一個堆棧跟蹤。
這裏是我到目前爲止的代碼...
spl_autoload_register(__NAMESPACE__.'\Autoloader::coreLoader');
spl_autoload_register(__NAMESPACE__.'\Autoloader::appLoader');
spl_autoload_register(__NAMESPACE__.'\Autoloader::throwException');
class Autoloader
{
private static $isError = false;
private static function loadHelper($className)
{
//Relevant code here
}
public static function coreLoader($className)
{
$classPath = static::loadHelper($className);
if ([email protected] PRIVATE_ROOT.DIRECTORY_SEPARATOR.$classPath.PHPEXT)
{
static::$isError = true;
}
else
{
static::$isError = false;
}
}
public static function appLoader($className)
{
$classPath = static::loadHelper($className);
if ([email protected] SYSTEM_PATH.DIRECTORY_SEPARATOR.$classPath.PHPEXT)
{
static::$isError = true;
}
else
{
static::$isError = false;
}
}
public static function throwException($className)
{
if (static::$isError)
{
throw new Exception_General('Attempted to load file: '.$className);
}
}
}
鑑於include
不會產生一個異常時,未找到文件,我不能使用try/catch塊的事實。
代替try/catch塊,我發現可以使用上面代碼中的if statement
來檢查include
語句是否成功加載所需的文件。
我的Exception_General
類負責生成和顯示開發人員友好的錯誤輸出/消息。但我在這裏遇到的問題是,如果我在合法的自動加載方法中拋出一個Exception,該腳本將正確地停止。
這當然是不理想的,因爲雖然第一個自動加載方法可能找不到請求的類,但spl_autoload隊列中的第二個或第三個自動加載方法MIGHT能夠找到請求的文件/類。
爲了適應這種行爲,我發現我必須創建第三個「僞」自動加載方法,它是隊列中最後一個被調用的方法 - 此方法檢查錯誤標誌,如果設置了,拋出異常。
在一個漫長的問題中,我真正要問的是 - 是否有更好的方法來捕獲失敗的包含,並且一旦所有的自動加載函數都運行正常,行爲恰當?
我選擇走多個自動加載機的路線的原因之一是性能/速度。如果只使用單個自動加載函數的路由,並且在該函數內解析/匹配類名稱字符串,那麼拋出異常就沒有問題,因爲您只有一個包含要與之競爭。這種方法的缺點是你爲簡單的加載類發揮了很大的處理能力。對於多個自動加載器,由於每個自動加載器都負責特定的類/路徑段,所以沒有太多處理髮生。 – cgons
當然,你是對的。我不認爲這是我在生產環境中使用的東西,因爲如你所說,找到每個班級的開銷很大。這或多或少受到確保只有在所有回調失敗時才拋出異常的想法的驅動(甚至是在Autoloader之後添加的異常)我可能稍後再看看它,看看我能否改進它(已當我發佈它時,已經過去了我的睡覺時間)。 – connec