如何通过电子邮件发送所有 PHP exceptions/errors 的详细信息,包括 mysqli 的?
How to email details of all PHP exceptions/errors, including mysqli ones?
如何获取所有 PHP 异常,包括 mysqli 生成的异常和正常 php 异常,并通过电子邮件发送给我?
问题环境
我在我的 ISP 处使用共享服务器,无法访问任何管理类型 PHP 配置文件。在服务器上,我只有大约一百行 PHP 对 MySQL 数据库执行查询,如果返回任何行,它会执行一些 SQL UPDATE 命令。这是每天 运行 的 cron 作业。没有关联的网站(我在该服务器上什至没有网站)。服务器托管一个用于远程连接的数据库,php 只是对其进行一些维护。
因为没有 'user' 也没有 'web page' 可以提供反馈,所以我希望所有错误和异常都通过电子邮件发送给我。
我尝试/研究过的东西
我发现
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
会将通常导致返回 FALSE 的 mysqli 错误转换为将写入错误日志的异常。这有帮助。
...我可以使用 eg
通过电子邮件发送文本
$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');
最小、可重现的示例
在下面的代码中,我将所有这些放在一起并故意引入了两个错误(尝试回显不存在的变量并尝试对不存在的 table 执行查询。
<?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 帖子
With PHP and mysqli, is it possible to catch all mysqli errors in one place across all PHP scripts?
Good Way to Email Exceptions
PHP exceptions error messages
PHP exception inside catch: how to handle it?
首先,我必须警告您,在对 public 开放的实时网站上,电子邮件错误可能会淹没您的邮箱,以防万一出现严重故障,因为每次对网站的请求都会导致一封不同的电子邮件发送至被发送。在我工作的公司中,这种情况不止一次发生过。有时很难在错误的瀑布中找到真正的原因。
监控服务器日志被认为是更安全和准确的解决方案。事实证明,在错误日志上使用 Grep 比浏览电子邮件更有效。但无论哪种方式,这里的问题是如何统一处理所有错误,而处理程序中采取的操作可以是任何操作。
所以就像我在 error reporting basics 上的文章中显示的那样,错误和异常是不同的野兽,每个都有自己的处理程序。因此,要使错误处理统一,您必须首先将错误转换为异常,然后在异常处理程序中执行所需的处理,无论它是什么——日志记录、电子邮件或任何东西。
因此,您将需要本文中介绍的两个函数,即简单地将错误转换为异常的错误处理程序,
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 抛出异常,这些异常将由上面定义的处理程序处理。
如何获取所有 PHP 异常,包括 mysqli 生成的异常和正常 php 异常,并通过电子邮件发送给我?
问题环境
我在我的 ISP 处使用共享服务器,无法访问任何管理类型 PHP 配置文件。在服务器上,我只有大约一百行 PHP 对 MySQL 数据库执行查询,如果返回任何行,它会执行一些 SQL UPDATE 命令。这是每天 运行 的 cron 作业。没有关联的网站(我在该服务器上什至没有网站)。服务器托管一个用于远程连接的数据库,php 只是对其进行一些维护。
因为没有 'user' 也没有 'web page' 可以提供反馈,所以我希望所有错误和异常都通过电子邮件发送给我。
我尝试/研究过的东西
我发现
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
会将通常导致返回 FALSE 的 mysqli 错误转换为将写入错误日志的异常。这有帮助。
...我可以使用 eg
通过电子邮件发送文本$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');
最小、可重现的示例
在下面的代码中,我将所有这些放在一起并故意引入了两个错误(尝试回显不存在的变量并尝试对不存在的 table 执行查询。
<?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 帖子
With PHP and mysqli, is it possible to catch all mysqli errors in one place across all PHP scripts?
Good Way to Email Exceptions
PHP exceptions error messages
PHP exception inside catch: how to handle it?
首先,我必须警告您,在对 public 开放的实时网站上,电子邮件错误可能会淹没您的邮箱,以防万一出现严重故障,因为每次对网站的请求都会导致一封不同的电子邮件发送至被发送。在我工作的公司中,这种情况不止一次发生过。有时很难在错误的瀑布中找到真正的原因。
监控服务器日志被认为是更安全和准确的解决方案。事实证明,在错误日志上使用 Grep 比浏览电子邮件更有效。但无论哪种方式,这里的问题是如何统一处理所有错误,而处理程序中采取的操作可以是任何操作。
所以就像我在 error reporting basics 上的文章中显示的那样,错误和异常是不同的野兽,每个都有自己的处理程序。因此,要使错误处理统一,您必须首先将错误转换为异常,然后在异常处理程序中执行所需的处理,无论它是什么——日志记录、电子邮件或任何东西。
因此,您将需要本文中介绍的两个函数,即简单地将错误转换为异常的错误处理程序,
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 抛出异常,这些异常将由上面定义的处理程序处理。