php - 如何通过电子邮件发送所有 PHP 异常/错误的详细信息,包括 mysqli 的?
问题描述
如何获取所有 PHP 异常,包括由 mysqli 生成的和普通的 php 异常通过电子邮件发送给我?
问题环境
我在我的 ISP 处使用共享服务器,并且无权访问任何管理员类型的 PHP 配置文件。在服务器上,我只有大约一百行 PHP 对 MySQL 数据库执行查询,如果返回任何行,它会执行一些 SQL UPDATE 命令。这是每天作为 cron 作业运行的。没有关联的网站(我什至在该服务器上都没有网站)。服务器托管一个用于远程连接的数据库,而 php 只是对其进行一些维护。
由于没有“用户”和“网页”可以提供反馈,我希望所有错误和异常都通过电子邮件发送给我。
我尝试过/研究过的事情
我发现
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
会将通常只会导致返回 FALSE 的 mysqli 错误转换为将写入错误日志的异常。这有帮助。
...我可以使用例如电子邮件发送文本
$email = "my message";
Error_log($email, 1, "myemailaddress@myserver.com", "From: defaultemail@hostingserver.com");
并且我可以通过编写自己的错误处理程序来获取错误的详细信息,例如
function the_error_handler($number, $message, $file, $line, $vars) //putting $vars in shows all the variables the server knows about
{
$email = " An error ($number) occurred on line $line in $file. $message ";
Error_log($email, 1, "myemailaddress@myserver.com", "From: defaultemail@hostingserver.com");
};
并使用
set_error_handler('the_error_handler');
最小的,可重现的例子
在下面的代码中,我将所有这些放在一起并故意引入了两个错误(尝试回显一个不存在的变量并尝试对一个不存在的表执行查询。
<?php
function the_error_handler($number, $message, $file, $line, $vars) //putting $vars in shows all the variables the server knows about(inluding passwords)
{
$email = " An error ($number) occurred on line $line in $file. $message ";
Error_log($email, 1, "myemailaddress@myserver.com", "From: defaultemail@hostingserver.com");
};
set_error_handler('the_error_handler');
echo $NonExsitentVariable; //<--deliberate error
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$servername = "65.78.165.199";
$username = "test_user"; //execute, select, update and create temp files rights
$password = "U7frgh%^yT";
$dbname = "devlopment_db";
$the_sql = "SELECT * FROM non_existent_table;"; //<-- another deliberate error
$conn = mysqli_connect($servername, $username, $password, $dbname); // Create connection
$result = mysqli_query($conn, $the_sql); //run the query and get a pointer to the result
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC); //convert to an associative array of rows to send back
?>
结果
结果是不存在的变量错误会通过电子邮件发送给我,但 mysqli 错误只是被放入服务器上的错误日志中,而不是通过电子邮件发送。
如何通过电子邮件将这两个或所有错误发送给我?(显然,真正的代码有点复杂,如果在这里完整发布会混淆问题,但如果我能理解如何处理这个更简单的例子,原理是一样的)
背景
我从事计算机编程和讲授大约 35 年,直到不久前退休,但从来没有需要(或希望!)用 PHP 编程。这是我的第一个脚本之一,可能是我的最后一个脚本,所以如果你能提供帮助,请合理明确地说明我需要做什么,因为我不太熟悉 PHP 语法或编程环境)
我看过的一些SO帖子
解决方案
首先,我必须警告您,在一个向公众开放的实时站点上,当对站点的每个请求都会导致发送不同的电子邮件时,如果出现某些严重故障,电子邮件错误可能会淹没您的邮箱。我工作的公司不止一次发生这种情况。有时很难在错误的瀑布中找到真正的原因。
监控服务器日志被认为是更安全和准确的解决方案。在我看来,在错误日志上使用 Grep 比浏览电子邮件更有效。但无论哪种方式,这里的问题是如何统一处理所有错误,而在处理程序中采取的操作可以是任何东西。
所以就像我在关于错误报告基础的文章中展示的那样,错误和异常是不同的野兽,每个都有自己的处理程序。因此,要使错误处理统一,您必须首先将错误转换为异常,然后在异常处理程序中进行所需的处理,无论它是什么 - 日志记录、电子邮件或任何东西。
因此,您将需要本文中介绍的两个函数,一个简单地将错误转换为异常的错误处理程序,
set_error_handler(function ($level, $message, $file = '', $line = 0)
{
throw new ErrorException($message, 0, $level, $file, $line);
});
和这样的异常处理程序
set_exception_handler(function ($e)
{
error_log($e);
http_response_code(500);
if (ini_get('display_errors')) {
echo $e;
} else {
error_log($e, 1, "myemailaddress@myserver.com", "From: defaultemail@hostingserver.com");
echo "<h1>500 Internal Server Error</h1>
An internal server error has been occurred.<br>
Please try again later.";
}
});
每次发生错误并且代码在实时站点上运行时,都会向您发送一封电子邮件。
此外,您可能希望添加一个致命错误处理程序,它可能有助于处理同名错误。可以在文章中看到所有三个处理程序组合在一起的完整示例。
关于mysqli,你是绝对正确的,下面这行
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
将告诉 mysqli 抛出异常,这些异常将由上面定义的处理程序处理。
推荐阅读
- javascript - Json 到 csv 动态列 javascript
- python - 将 Google 表格转换为 PDF 并存储在与表格相同的 Google Drive 文件夹中
- android - 使用 localhost Laravel api 测试改造
- c++ - Arduino + ESP8266 发送一次 POST 但每隔一次失败
- time-series - 遗传算法时间序列预测创建初始种群
- vba - 微软访问。VBA。如何仅在不存在的情况下创建具有 1 条记录的临时表
- express - 让 express.js 将任何 html 文件路径的所有子路径重定向到自身
- java - 强化增量扫描:java.lang.ClassCastException
- symfony - Symfony API:测试内容是否有密钥
- pandas - 如何计算列表数据的计数和首次出现?