當前位置: 首頁> 最新文章列表> 怎麼用mysqli::$error 和error_log() 把數據庫錯誤記錄到日誌文件中?

怎麼用mysqli::$error 和error_log() 把數據庫錯誤記錄到日誌文件中?

M66 2025-07-01

怎麼用mysqli::$error 和error_log() 把數據庫錯誤記錄到日誌文件中?

在開發PHP 應用程序時,數據庫錯誤處理是不可避免的一部分。為了更好地排查和調試問題,及時記錄數據庫錯誤是非常必要的。 PHP 中的mysqli擴展提供了一個非常實用的屬性mysqli::$error ,它可以讓你獲取數據庫連接中的最後一個錯誤信息。結合PHP 內置的error_log()函數,可以將錯誤信息記錄到日誌文件中,幫助開發者在生產環境中追踪問題。

本文將介紹如何使用mysqli::$errorerror_log()來記錄MySQL 數據庫的錯誤信息,並且將錯誤日誌保存在指定的文件中,確保開發者能夠及時發現並修復問題。

1. 獲取MySQL 錯誤信息

在使用mysqli擴展連接MySQL 數據庫時,發生任何SQL 執行錯誤時,錯誤信息都會通過mysqli::$error屬性提供。這個屬性會返回上一個數據庫操作(如查詢、更新、插入等)的錯誤信息。需要注意的是, mysqli::$error只會返回最近一個操作的錯誤消息,如果沒有錯誤,它會返回一個空字符串。

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">"localhost"</span></span><span>, </span><span><span class="hljs-string">"root"</span></span><span>, </span><span><span class="hljs-string">"password"</span></span><span>, </span><span><span class="hljs-string">"test_db"</span></span><span>);

</span><span><span class="hljs-comment">// 檢查連接是否成功</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error) {
    </span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"連接失敗: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error);
}

</span><span><span class="hljs-comment">// 執行一條故意出錯的 SQL 查詢</span></span><span>
</span><span><span class="hljs-variable">$query</span></span><span> = </span><span><span class="hljs-string">"SELECT * FROM non_existing_table"</span></span><span>;
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-variable">$query</span></span><span>);

</span><span><span class="hljs-comment">// 检查查詢是否执行成功</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$result</span></span><span>) {
    </span><span><span class="hljs-comment">// 獲取並輸出錯誤信息</span></span><span>
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"錯誤訊息: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;error;
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

在上面的代碼中,當查詢不存在的表時, $mysqli->error會返回MySQL 的錯誤信息,例如“Table 'test_db.non_existing_table' doesn't exist”。

2. 使用error_log()記錄錯誤到日誌文件

error_log()函數是PHP 提供的一個非常方便的工具,用於將錯誤信息寫入日誌文件或發送到指定的錯誤日誌處理程序。通過結合mysqli::$errorerror_log() ,我們可以將數據庫錯誤記錄到一個日誌文件中,供日後排查和分析。

error_log()函數的基本用法是:

 <span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$message</span></span><span>, </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$message_type</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$destination</span></span><span> = ?, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$extra_headers</span></span><span> = ?)
</span></span>
  • $message : 要記錄的錯誤信息。

  • $message_type : 錯誤日誌類型。 0 表示記錄到PHP 的錯誤日誌文件,1 表示發送郵件,2 表示發送到某個文件。

  • $destination : 如果$message_type為1 或2,則指定接收郵件的地址或日誌文件路徑。

下面是一個示例,展示如何將mysqli::$error中的錯誤信息寫入到一個日誌文件:

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-variable">$mysqli</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-string">"localhost"</span></span><span>, </span><span><span class="hljs-string">"root"</span></span><span>, </span><span><span class="hljs-string">"password"</span></span><span>, </span><span><span class="hljs-string">"test_db"</span></span><span>);

</span><span><span class="hljs-comment">// 檢查連接是否成功</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error) {
    </span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"連接失敗: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;connect_error);
}

</span><span><span class="hljs-comment">// 執行一條故意出錯的 SQL 查詢</span></span><span>
</span><span><span class="hljs-variable">$query</span></span><span> = </span><span><span class="hljs-string">"SELECT * FROM non_existing_table"</span></span><span>;
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;</span><span><span class="hljs-title function_ invoke__">query</span></span><span>(</span><span><span class="hljs-variable">$query</span></span><span>);

</span><span><span class="hljs-comment">// 如果查詢失败,記錄錯誤到日誌文件</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$result</span></span><span>) {
    </span><span><span class="hljs-variable">$error_message</span></span><span> = </span><span><span class="hljs-string">"MySQL 錯誤: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;error . </span><span><span class="hljs-string">" | 查詢: "</span></span><span> . </span><span><span class="hljs-variable">$query</span></span><span>;
    </span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-variable">$error_message</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-string">"/var/log/php_error.log"</span></span><span>);
}
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

在這段代碼中,當SQL 查詢出錯時, mysqli::$error的錯誤信息與SQL 查詢語句一起被記錄到/var/log/php_error.log文件中。 error_log()的第一個參數是錯誤信息,第二個參數設置為3 ,表示將錯誤寫入到指定的日誌文件。

3. 日誌文件權限

為了確保PHP 可以將錯誤寫入到日誌文件,日誌文件必須具有適當的寫權限。以Linux 為例,確保日誌文件的目錄和文件本身對PHP 進程可寫:

 <span><span>sudo </span><span><span class="hljs-built_in">chmod</span></span><span> 777 /var/log/php_error.log
</span></span>

或者,如果你不希望設置全局可寫權限,也可以通過調整文件所屬用戶和用戶組來賦予PHP 進程寫權限:

 <span><span>sudo </span><span><span class="hljs-built_in">chown</span></span><span> www-data:www-data /var/log/php_error.log
</span></span>

4. 優化日誌記錄

雖然將錯誤記錄到日誌文件非常有用,但你可能希望進一步優化日誌的記錄方式。以下是一些優化建議:

4.1. 添加時間戳

將時間戳添加到錯誤日誌中,可以更方便地追踪錯誤發生的時間。

 <span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$result</span></span><span>) {
    </span><span><span class="hljs-variable">$error_message</span></span><span> = </span><span><span class="hljs-string">"["</span></span><span> . </span><span><span class="hljs-title function_ invoke__">date</span></span><span>(</span><span><span class="hljs-string">'Y-m-d H:i:s'</span></span><span>) . </span><span><span class="hljs-string">"] MySQL 錯誤: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;error . </span><span><span class="hljs-string">" | 查詢: "</span></span><span> . </span><span><span class="hljs-variable">$query</span></span><span>;
    </span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-variable">$error_message</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-string">"/var/log/php_error.log"</span></span><span>);
}
</span></span>

4.2. 記錄客戶端IP 和用戶信息

如果你的應用程序是一個多用戶系統,記錄客戶端的IP 地址和當前用戶的ID 會非常有助於問題定位。

 <span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$result</span></span><span>) {
    </span><span><span class="hljs-variable">$error_message</span></span><span> = </span><span><span class="hljs-string">"["</span></span><span> . </span><span><span class="hljs-title function_ invoke__">date</span></span><span>(</span><span><span class="hljs-string">'Y-m-d H:i:s'</span></span><span>) . </span><span><span class="hljs-string">"] IP: "</span></span><span> . </span><span><span class="hljs-variable">$_SERVER</span></span><span>[</span><span><span class="hljs-string">'REMOTE_ADDR'</span></span><span>] . </span><span><span class="hljs-string">" 用戶ID: "</span></span><span> . </span><span><span class="hljs-variable">$_SESSION</span></span><span>[</span><span><span class="hljs-string">'user_id'</span></span><span>] . </span><span><span class="hljs-string">" MySQL 錯誤: "</span></span><span> . </span><span><span class="hljs-variable">$mysqli</span></span><span>-&gt;error . </span><span><span class="hljs-string">" | 查詢: "</span></span><span> . </span><span><span class="hljs-variable">$query</span></span><span>;
    </span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-variable">$error_message</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-string">"/var/log/php_error.log"</span></span><span>);
}
</span></span>

4.3. 限制錯誤記錄

如果你的日誌文件已經變得非常龐大,可以考慮只記錄特定類型的錯誤,或者使用日誌輪換工具(如logrotate )來管理日誌文件。

總結

通過結合mysqli::$errorerror_log() ,我們可以高效地將數據庫錯誤記錄到日誌文件中。這不僅有助於在開發過程中快速定位問題,在生產環境中也能幫助開發者及時發現潛在的數據庫錯誤。通過合理使用時間戳、用戶信息和客戶端IP,可以進一步提高日誌的可追溯性和實用性。

記得在部署到生產環境時,要確保錯誤日誌文件的權限設置得當,以避免安全風險。