PHP Conference Japan 2024

error_log

(PHP 4, PHP 5, PHP 7, PHP 8)

error_log傳送錯誤訊息到已定義的錯誤處理常式

說明

error_log(
    字串 $message,
    整數 $message_type = 0,
    ?字串 $destination = null,
    ?字串 $additional_headers = null
): 布林值

將錯誤訊息傳送到網路伺服器的錯誤日誌或檔案。

參數

message

應記錄的錯誤訊息。

message_type

指定錯誤訊息的傳送位置。可能的訊息類型如下:

error_log() 日誌類型
0 message 會被傳送到 PHP 的系統記錄器,使用作業系統的系統記錄機制或檔案,具體取決於 error_log 設定指令的設定。這是預設選項。
1 message 會以電子郵件的形式傳送到 destination 參數指定的地址。這是唯一使用第四個參數 additional_headers 的訊息類型。
2 不再是一個選項。
3 message 會被附加到檔案 destination。系統不會自動在 message 字串的結尾新增換行符號。
4 message 會直接傳送到 SAPI 記錄處理程式。

destination

目的地。其含義取決於 message_type 參數,如上所述。

additional_headers

額外的標頭。當 message_type 參數設定為 1 時使用。此訊息類型使用與 mail() 相同的內部函式。

返回值

成功時返回 true,失敗時返回 false。如果 message_type 為零,則此函式一律返回 true,無論錯誤是否可以記錄。

更新日誌

版本 說明
8.0.0 destinationadditional_headers 現在可以為 null。

範例

範例 #1 error_log() 範例

<?php
// 如果無法連線到資料庫,則透過伺服器日誌發送通知。
if (!Ora_Logon($username, $password)) {
error_log("Oracle 資料庫無法使用!", 0);
}

// 如果 FOO 用盡,則透過電子郵件通知管理員
if (!($foo = allocate_new_foo())) {
error_log("嚴重問題,FOO 已用盡!", 1,
"operator@example.com");
}

// 呼叫 error_log() 的另一種方式:
error_log("您出錯了!", 3, "/var/tmp/my-errors.log");
?>

注意事項

警告

error_log() 不是二進位安全的。 message 將會被空字元截斷。

提示

message 不應包含空字元。請注意,message 可能會被送到檔案、郵件、系統日誌等。在呼叫 error_log() 之前,請使用適當的轉換/跳脫函式,例如 base64_encode()rawurlencode()addslashes()

新增註解

使用者貢獻的註解 19 則註解

kevindougans at gmail dot com
14 年前
給新手的建議:這個函式與「tail」搭配使用效果很好,tail 是一個 Unix 指令,可以即時監看日誌檔。Windows 也有 Tail 的版本,例如 Tail for Win32 或 Kiwi Log Viewer。

同時使用 error_log() 和 tail 來檢視 php_error.log,您就可以在除錯程式碼時不必太擔心除錯訊息會顯示在螢幕上,以及可能會被誰看到。

進一步說明:當您設定了兩個螢幕時,效果會更好。一個用於瀏覽器和 IDE,另一個用於即時檢視日誌檔的更新。
Sion
6 年前
不要嘗試在 error_log() 中輸出過大的文字;

如果您嘗試輸出大量的文字,它會在大約 8000 個字元處截斷文字(對於合理的大量字串,< 32K 個字元),或者(對於極其大量的字串,大約 160 萬個字元)完全當機,甚至不會拋出任何錯誤(我甚至將它放在 try/catch 中,也沒有從 catch 中得到任何結果)。

我在嘗試除錯 `wp_remote_get();` 的回應時遇到了這個問題,我所有的 `error_log()` 都正常運作,除了一個... (-_-)
經過大約一天的除錯,我終於找到了原因,這就是我寫這篇文章的原因。

顯然回應的內容超過 160 萬個字元(或位元組?(無論 `strlen()` 返回什麼))。

如果您有一個長度未知的字串,請使用以下方法
`$start_index = 0;`
`$end_index = 8000;`
`error_log( substr( $output_text , $start_index , $end_index ) );`
roychri at php dot net
14 年前
`$message` 參數的最大長度有限制。

預設值似乎是 1024,但可以透過調整執行時設定值 `'log_errors_max_len'` 來更改。

更多細節請參考這裡
https://php.dev.org.tw/manual/en/errorfunc.configuration.php
frank at booksku dot com
18 年前
注意!如果多個腳本共用同一個日誌檔,但以不同的使用者身分執行,則首先記錄錯誤的腳本將擁有該檔案,而以不同使用者身分執行的 `error_log()` 呼叫將*無聲無息地*失敗!

沒有比試圖找出為什麼所有 `error_log` 呼叫實際上都沒有寫入,結果卻發現是由於*無聲無息的*權限被拒絕錯誤更令人沮喪的事情了!
i dot buttinoni at intandtel dot com
16 年前
小心。當日誌檔達到 2GB 時,PHP 會意外終止(在具有檔案大小上限的系統上)。
一個解決方法是輪替日誌 :)
php at kennel17 dot NOSPAM dot co dot uk
19 年前
如果您從命令列執行 PHP,系統日誌似乎是 stderr,而且 stderr 通常是 stdout。這表示如果您使用自訂錯誤同時顯示錯誤並將其記錄到系統日誌,則命令列使用者將會看到相同的錯誤報告兩次。
Matthew Swift
5 年前
訊息類型 3 接受相對路徑作為目的地,但要注意的是,根目錄是由呼叫 `error_log()` 的上下文決定的,而上下文可能會改變,因此程式碼中的一個 `error_log()` 實例可能會導致在不同位置建立多個日誌檔。

在 WordPress 環境中,根目錄在許多情況下會是網站的根目錄,但在 AJAX 呼叫中會是 `/wp-admin/`,而在其他情況下會是外掛程式的目錄。如果您希望所有輸出都寫入同一個檔案,請使用絕對路徑。
匿名
21 年前
當使用 `error_log` 發送電子郵件時,並非所有 `extra_headers` 字串的元素都以相同的方式處理。「From:」和「Reply-To:」標頭值將會取代預設的標頭值。「Subject:」標頭值則不會:它們會被*新增*到郵件標頭中,但不會取代預設值,導致郵件訊息具有兩個「Subject」欄位。

<?php

error_log
("sometext", 1, "zigzag@my.domain",
"Subject: Foo\nFrom: Rizzlas@my.domain\n");

?>

---------------%<-----------------------
收件者:zigzag@my.domain
信封收件者:zigzag@my.domain
日期:2003 年 3 月 28 日,星期五,13:29:02 -0500
寄件者:Rizzlas@my.domain
主旨:PHP error_log 訊息
主旨:Foo
遞送日期:2003 年 3 月 28 日,星期五,13:29:03 -0500

sometext
---------------%<---------------------

文件說明:「此訊息類型使用與 mail() 相同的內部函式。」

mail() 也無法根據 extra_header 資料設定「主旨」欄位,而是採用單獨的引數來指定「主旨:」字串。

php v.4.2.3, SunOS 5.8
russ at russtanner dot com
5 年前
在 *nix 系統上,您可以使用「tail」和「grep」輕鬆篩選傳送到 error_log() 的訊息。這使得在開發過程中輕鬆查看除錯訊息。

請務必使用唯一字串「標記」您的錯誤訊息,以便您可以使用「grep」進行篩選。

在您的程式碼中:

error_log("DevSys1 - FirstName: $FirstName - LastName: $Lastname");

在您的命令列上:

tail -f /var/log/httpd/error_log | grep DevSys1

在此範例中,我們將 Apache 記錄輸出透過管道傳送到 grep (STDIN),它會為您篩選輸出,僅顯示包含「DevSys1」的訊息。

「-f」選項表示「追蹤」,它會將所有新的記錄項目串流到您的終端機或後續的任何管道命令,在本例中為「grep」。
SJL
16 年前
「如果您從命令列執行 PHP,系統日誌似乎是 stderr。」

實際上,如果 PHP 無法寫入日誌檔,它似乎會記錄到 stderr。命令列 PHP 會回到 stderr,因為日誌檔(通常)只能由網路伺服器寫入。
paul dot chubb at abs dot gov dot au
16 年前
在 Windows 上記錄到 Apache 時,error_log 和 trigger_error 都會在訊息前面產生 Apache 錯誤狀態。如果您只想記錄資訊,這很不好。但是,您可以簡單地記錄到 stderr,但您必須自行組合所有訊息。

LogToApache($Message) {
$stderr = fopen('php://stderr', 'w');
fwrite($stderr,$Message);
fclose($stderr);
}
p dot lhonorey at nospam-laposte dot net
18 年前
嗨!

發佈「HTML」郵件內文的另一個技巧。只需在 extra_header 字串中加入「Content-Type: text/html; charset=ISO-8859-1」。當然,您可以根據您的國家/地區、環境或內容設定字元集。

例如:Error_log("<html><h2>stuff</h2></html>",1,"eat@joe.com","subject :lunch\nContent-Type: text/html; charset=ISO-8859-1");

好好享受吧!
franz at fholzinger dot com
19 年前
如果在 error_log 檔案中找不到您的項目
當您在不產生任何輸出的腳本中使用 error_log 時,這表示您在腳本執行期間看不到任何內容,並且當您想知道為什麼 error_log 檔案中沒有產生任何 error_log 項目時,原因可能是:
- 您沒有在 php.ini 中設定 error_log 輸出
- 腳本有語法錯誤,因此沒有執行
stepheneliotdewey at GmailDotCom
17 年前
請注意,由於典型的電子郵件未加密,使用此函數通過電子郵件發送有關錯誤的數據可能會被視為安全風險。風險程度取決於您發送的信息量和類型,但僅僅在發生錯誤時發送電子郵件(即使無法讀取)本身就可能暗示觀察您網站的資深駭客,他們已成功導致錯誤發生。

當然,大多數開源支持者都會同意,透過隱匿來維護安全性是最薄弱的安全性。這只是您應該記住的事情。

當然,無論您做什麼,請確保此類電子郵件不包含敏感的用戶數據。
eguvenc at gmail dot com
16 年前
<?php
//多行錯誤日誌類別
// ersin güvenç 2008 eguvenc@gmail.com
//斷行請使用 "\n" 而非 '\n'

類別 log {
//
const USER_ERROR_DIR = '/home/site/error_log/Site_User_errors.log';
const
GENERAL_ERROR_DIR = '/home/site/error_log/Site_General_errors.log';

/*
使用者錯誤...
*/
public function user($msg,$username)
{
$date = date('d.m.Y h:i:s');
$log = $msg." | 日期: ".$date." | 使用者: ".$username."\n";
error_log($log, 3, self::USER_ERROR_DIR);
}
/*
一般錯誤...
*/
public function general($msg)
{
$date = date('d.m.Y h:i:s');
$log = $msg." | 日期: ".$date."\n";
error_log($msg." | 日期: ".$date, 3, self::GENERAL_ERROR_DIR);
}

}

$log = new log();
$log->user($msg,$username); //用於使用者錯誤
//$log->general($msg); //用於一般錯誤
?>
daniel dot fukuda at gmail dot com
15 年前
如果您遇到日誌檔案權限問題 *卻沒有任何提示*
最好不要設定 error_log 指令,這樣錯誤就會寫入您目前虛擬主機的 Apache 日誌檔案中。
Robert Chapin
6 年前
當 error_log() 意外使用 stdout 時,您應該檢查 CLI 環境中 php.ini 的 error_log 值是否為空。 這麼簡單的操作或許就能恢復預期的行為。

<?php ini_set('error_log', 'error_log'); ?>
ccb2357 at gmail dot com
1 年前
// 美觀的紀錄資訊函式
<?php
function logger($log, $clear = true){
file_put_contents('/path/log/logger.log', (is_object($log) || is_array($log) || is_resource($log) ? json_encode($log, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) : $log), (!$clear) ? FILE_APPEND : 0);
}
匿名
4 年前
根據錯誤的不同,您可能還需要添加 500 錯誤標頭和使用者訊息

$message = '錯誤描述。';
error_log($message);
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
exit($message);
To Top