2008-10-09 127 views
1

我正在使用trigger_error在自定義類中「拋出」錯誤。我的問題是,trigger_error輸出trigger_error被調用的行號。例如,假設下面的代碼:如何在PHP中使用trigger_error時獲取正確的行號?

01 <?php 
02  class Test { 
03   function doAction() { 
04    $this->doSubAction(); 
05   } 
06    
07   function doSubAction() { 
08    if(true) 
09     trigger_error('Custom error', E_USER_WARNING); 
10   } 
11  } 
12   
13  $var = new Test(); 
14  $var->doAction(); 
15 ?> 

PHP將打印出以下幾點:

警告:自定義錯誤test.php的上線

如何讓PHP返回doAction()函數被調用的行(在類外調用的方法,忽略在內部進行的調用)如下所示?

警告:自定義錯誤test.php的上線

編輯:修改我的例子是東西有點接近我想要實現。

回答

0

好的,對於那些對我的最終解決方案感興趣的人,我在我們的框架中集成了下面的一段代碼,它在我們可以測試的所有情況下返回正確的行號。我們正在生產中使用它。

ErrorHandler class

它惹人捕獲的PHP異常,PHP錯誤和PEAR::Error秒。你需要稍微修改它,代碼有一些框架特定的功能,但它們不應該難以追蹤。請享用!

2

最好的辦法是設置一個顯示完整堆棧跟蹤的錯誤處理程序。

設置自定義錯誤處理程序,並在其中調用debug_print_backtrace()。一般而言,您會發現這一點很有用,在這種情況下也是如此。

0

兩個選項,沒有一個特別可口:

  • 覆蓋有測試()提供的參數__LINE__(例如 「test(__LINE__)」,並給出了參數trigger_error)。設置錯誤處理程序以打印自定義錯誤消息。 注意:這是非常醜陋的。 :-)

  • 設置一個錯誤處理程序,讓它調用並處理debug_backtrace()的巨大輸出。這個功能在調試時很有用......但是對於你想要做的事情來說,這是過分的。請不要將此功能用作系統正常操作的一部分。

簡答:太難了,不要試試。 : - |

+1

大概,對行號的需求會表明某種*非常差*的錯誤,其中開發人員需要進行一些嚴肅的調試。在這種情況下,我不會想到解析debug_backtrace()的輸出會消耗多少成本。 – 2008-10-09 08:50:35

0

我通常還會在那裏放一個trigger_error()。這確保我確切知道它在哪裏被調用,以及確切發生實際錯誤的位置。然後,我在生產中通過電子郵件將所有錯誤發送給自己。我知道這不是自動的,但至少你可以追蹤發生的事情。

0

我以爲我會把我的兩美分投入鍋中,並討論我通常使用的方法,無論是按原樣還是小定製,我爲其他開發人員經常使用的PHP庫進行了討論。

我將程序執行過程中可能出現的錯誤細分爲兩類:錯誤編程的結果以及由於用戶錯誤或某些外部因素導致的錯誤。對於前者,我將trigger_error與E_USER_ERROR結合使用,後者使用Exception,特別是一個程序包Exception,然後由庫中的所有其他異常繼承。

開發錯誤的一個示例是將參數中的整數傳遞給預期爲字符串的參數(V7之前)或訪問不存在的類的方法或屬性。 (您可以在這裏使用您自己的開發人員想象力。)顯然,另一個開發人員不會在意這個錯誤是在__get或__set語句或其他一些魔法構造的深處產生的,而是他們想知道特別是他們的錯誤所在。讓我們面對它吧......開發者不喜歡通過回溯來回應。

因此,我採用本地化與錯誤消息的方法是簡單地:

function localize_error_msg($msg, $level) { 
    $level = (int)$level; 
    $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $level + 1)[$level]; 
    return $msg . " in " . $backtrace['file'] . " on line " . $backtrace['line']; 
} 

我通過以依賴於所使用的構建體,其通常爲1或2,且其餘的是自我解釋性的回溯水平。

以防止重複序列「在第n行的文件」,我添加這個錯誤處理程序:

set_error_handler(function($errno, $errstr, $errfile, $errline) { 
    if (preg_match('/on line \d+$/', $errstr) === 1) 
     die($errstr); 
    else return false; 
}, E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE); 

同樣,我喜歡保持簡單。人們可以爭辯說,錯誤信息的本地化應該發生在處理程序中,但是,你必須能夠傳入深度,這在處理程序內部現在是深層2層,並且,那。

Happy Trails!

相關問題