2011-06-16 63 views
16

我想確保沒有使用a custom PHP error handler引入競態條件。爲此,我想知道如果我可以依賴error_log()或者如果我需要使用其他文件鎖定方法來確保錯誤被​​正確記錄。PHP函數error_log()是否安全使用?

默認的PHP錯誤處理程序是如何工作的?比賽條件安全嗎?

例如,我必須鎖定文件(這可能會導致錯誤,在這個簡單的版本丟失)

function log_error($message) 
{ 
    if(! $fp = @fopen('/path/to/error.log', 'a')) 
    { 
     return FALSE; 
    } 

    flock($fp, LOCK_EX); 
    fwrite($fp, $message); 
    flock($fp, LOCK_UN); 
    fclose($fp); 

    return TRUE; 
} 

或者我可以叫的error_log?

error_log($message, 0); 
+1

error_log($ message,0)將使用http://php.net/error-log指令,因此您必須將其設置正確。如果你在那裏使用syslog,那麼你應該沒問題:http://stackoverflow.com/questions/1163194/syslog-r-for-linux,但你應該檢查我們系統上的系統日誌版本(在大多數系統上是安全的)。 – XzKto 2011-06-22 14:36:16

回答

16

您可以在ext/standard/basic_functions.c找到error_log實現的源代碼。你會發現它幾乎只是調用任何已定義的記錄器。如果您擔心由於多個併發呼叫而由error_log本身進行的某種數據傳輸,則無需執行此操作。或者至少,沒有比大多數其他PHP代碼更受關注。如果您的自定義記錄器正在寫入文件,則需要自己實現文件鎖定。併發調用error_log(跨進程)是一種非常常見的情況。

編輯

你幾乎肯定是更好使用內置的通過error_log登錄使用。

PHP flock實現使用建議性鎖定,這使得其他進程可以簡單地忽略鎖定和寫入。另外,在你自己的進程中,當進程等待獲取鎖時,你最終將被綁定爲IO。通過使用error_log,您可以配置系統日誌記錄。系統日誌是異步所以你避免了鎖的獲取,並且它也被內核緩衝區支持(通常),這將允許任何syslog守護進程寫入連續的記錄而沒有問題。

在許多公司實現了高吞吐量日誌記錄之後,我強烈建議配置syslog或使用scribe之類的軟件進行配置。我的2c。

+0

那麼,我可以從我的處理函數中調用error_log(),還是需要創建另一個可以鎖定並使用它的日誌文件?如果默認的PHP處理程序只是調用error_log(),那麼我感覺在我的處理程序中使用它是安全的。 – Xeoncross 2011-06-16 17:46:00

+2

可以通過php.ini(error_log ='/tmp/log.txt')指定的基於文件的記錄器即使併發調用也會被安全地寫入。你可以在你的處理程序中調用error_log()。 – bmatheny 2011-06-16 17:52:52

+0

我認爲這是安全的。 – 2011-06-23 20:32:25

相關問題