提问人:Candidasa 提问时间:5/10/2009 最后编辑:TylerHCandidasa 更新时间:8/16/2023 访问量:696144
如何在PHP中获得有用的错误消息?
How can I get useful error messages in PHP?
问:
很多时候,我会尝试运行一个PHP脚本,然后得到一个空白屏幕。无错误消息;只是一个空屏幕。原因可能是简单的语法错误(括号错误、缺少分号)、函数调用失败,或者完全是其他原因。
很难弄清楚出了什么问题。我最终注释掉了代码,到处输入“echo”语句等,试图缩小问题范围。但肯定有更好的方法,对吧?
有没有办法让PHP像Java一样产生有用的错误消息?
答:
默认情况下,显示错误处于关闭状态,因为您不希望“客户”看到错误消息。
请查看 PHP 文档中的此页面,以获取有关 2 个指令的信息: 和 . 可能是你想改变的那个。error_reporting
display_errors
display_errors
因此,您有 3 个选择:
(1) 您可以检查错误日志文件,因为它将包含所有错误(除非已禁用日志记录)。要启用错误日志记录,请确保将配置指令设置为 。当错误不是在 PHP 中发生,而是由 Web 服务器发出时,日志也很有用。log_errors
On
(2)您可以添加以下2行,以帮助您调试不是同一文件中发生的语法错误的错误:
error_reporting(E_ALL);
ini_set('display_errors', 'On');
请注意,在实时服务器上,后者应设置为(但只能设置为后者,因为您仍然需要从日志文件中了解发生的所有错误)。Off
但是,对于同一文件中发生的语法错误,上述命令将不起作用,您需要在 php.ini 中启用它们。如果您无法修改 php.ini,您也可以尝试将以下行添加到 .htaccess 文件中,尽管现在很少支持它:
php_flag display_errors on
php_value error_reporting -1
(3) 另一种选择是使用在键入时检查错误的编辑器,例如 PhpEd、VSCode 或 PHPStorm。它们都带有一个调试器,可以提供更详细的信息。(PhpEd 调试器与 xdebug 非常相似,直接集成到编辑器中,因此您可以使用 1 个程序来完成所有操作。
评论
E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE
您可以在 PHP 中注册自己的错误处理程序。例如,在这些晦涩难懂的情况下,将所有错误转储到文件中可能会对您有所帮助。请注意,无论您的当前error_reporting设置为什么,您的函数都会被调用。非常基本的例子:
function dump_error_to_file($errno, $errstr) {
file_put_contents('/tmp/php-errors', date('Y-m-d H:i:s - ') . $errstr, FILE_APPEND);
}
set_error_handler('dump_error_to_file');
可以在要调试的文件中包含以下行:
error_reporting(E_ALL);
ini_set('display_errors', '1');
这覆盖了 php.ini 中的默认设置,这些设置只是使 PHP 将错误报告到日志中。
评论
error_reporting(E_ALL | E_STRICT);
并在php.ini中打开显示错误
您可以启用完整的错误报告(包括通知和严格消息)。有些人觉得这太冗长了,但值得一试。在 php.ini 中设置为。error_reporting
E_ALL | E_STRICT
error_reporting = E_ALL | E_STRICT
E_STRICT
将通知您有关已弃用的功能,并为您提供有关执行某些任务的最佳方法的建议。
如果您不想接收通知,但发现其他消息类型有帮助,请尝试排除通知:
error_reporting = (E_ALL | E_STRICT) & ~E_NOTICE
还要确保在 php.ini 中启用了它。如果您的 PHP 版本低于 5.2.4,请将其设置为:display_errors
On
display_errors = "On"
如果您的版本是 5.2.4 或更高版本,请使用:
display_errors = "stderr"
有一个非常有用的扩展,称为“xdebug”,它也可以使您的报告更好。
评论
若要启用完整的错误报告,请将以下内容添加到脚本中:
error_reporting(E_ALL);
这会导致出现最少的警告。而且,以防万一:
ini_set('display_errors', '1');
将强制显示错误。这应该在生产服务器中关闭,但在开发时则不然。
评论
除了 error_reporting 和 display_errors ini 设置之外,您还可以从 Web 服务器的日志文件中获取 SYNTAX 错误。当我开发PHP时,我会将开发系统的Web服务器日志加载到我的编辑器中。每当我测试一个页面并得到一个空白屏幕时,日志文件就会过时,我的编辑器会问我是否要重新加载它。当我这样做时,我跳到底部,并且存在语法错误。例如:
[Sun Apr 19 19:09:11 2009] [error] [client 127.0.0.1] PHP Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in D:\\webroot\\test\\test.php on line 9
错误和警告通常出现在 php.ini 设置中或取决于您的。....\logs\php_error.log
....\logs\apache_error.log
此外,有用的错误通常被定向到浏览器,但由于它们不是有效的 html,因此不会显示。
所以“你的日志文件,当你得到一个空白屏幕时,使用IEs的”视图“->”源“菜单选项来查看原始输出。"tail -f
评论
php_flag display_errors 1
尝试在实际的 php 文件中设置错误报告级别。或者,正如其他人建议的那样,检查您的服务器设置 - 它可能是 php.ini 中的某些内容,或者与您的主机有关的某些限制。不要只依赖 .htaccess。此外,在进行故障排除时,print_r您可能认为可疑的任何变量。
评论
你确定PHP实际上是从.htaccess中获取''设置吗?检查函数的输出以确保。display_errors
phpinfo()
此外,您应该检查以确保您没有使用“”,如果您使用了“@include...”,它可能会使您的错误静音或“@some_function(...)”,位于堆栈跟踪的某个位置。@
评论
display_errors
@
如果错误出现在 PHP 代码中,则可以在代码中使用 error_reporting() 函数设置为全部报告。
但是,这并不能处理 PHP 崩溃的情况。有关此内容的信息仅在服务器日志中可用。也许您无法访问这些,但是与我合作过的许多托管服务提供商都有某种方法可以让您访问它。例如,我最喜欢的方法是在.php所在的当前目录中创建error_log文件。尝试在那里搜索或联系您的托管服务提供商。
某些应用程序确实通过调用如下内容来自行处理这些指令:
error_reporting(E_ALL & ~E_DEPRECATED); or error_reporting(0);
从而覆盖您的 .htaccess 设置。
我总是在 php 脚本的最顶端使用这种语法。
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'On'); //On or Off
评论
我不知道它是否会有所帮助,但这是我为 php 项目提供的标准配置文件的一部分。即使在我自己的服务器上,我也倾向于不太依赖 apache 配置。
我从来没有消失的错误问题,所以也许这里的东西会给你一个想法。
已编辑以显示APPLICATON_LIVE
/*
APPLICATION_LIVE will be used in process to tell if we are in a development or production environment. It's generally set as early as possible (often the first code to run), before any config, url routing, etc.
*/
if ( preg_match( "%^(www.)?livedomain.com$%", $_SERVER["HTTP_HOST"]) ) {
define('APPLICATION_LIVE', true);
} elseif ( preg_match( "%^(www.)?devdomain.net$%", $_SERVER["HTTP_HOST"]) ) {
define('APPLICATION_LIVE', false);
} else {
die("INVALID HOST REQUEST (".$_SERVER["HTTP_HOST"].")");
// Log or take other appropriate action.
}
/*
--------------------------------------------------------------------
DEFAULT ERROR HANDLING
--------------------------------------------------------------------
Default error logging. Some of these may be changed later based on APPLICATION_LIVE.
*/
error_reporting(E_ALL & ~E_STRICT);
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
ini_set ( "log_errors", 1);
ini_set ( "log_errors_max_len", 0);
ini_set ( "error_log", APPLICATION_ROOT."logs/php_error_log.txt");
ini_set ( "display_errors", "0");
ini_set ( "display_startup_errors", "0");
if ( ! APPLICATION_LIVE ) {
// A few changes to error handling for development.
// We will want errors to be visible during development.
ini_set ( "display_errors", "1");
ini_set ( "display_startup_errors", "1");
ini_set ( "html_errors", "1");
ini_set ( "docref_root", "http://www.php.net/");
ini_set ( "error_prepend_string", "<div style='color:red; font-family:verdana; border:1px solid red; padding:5px;'>");
ini_set ( "error_append_string", "</div>");
}
评论
在代码中使用将导致 intepreter 悄悄地死亡并中止脚本解析。您应该检查无效函数,并尽量不要使用错误压缩运算符(@ char )@inexistent_function_call();
打开你的 php.ini, 确保它设置为:
display_errors = On
重新启动服务器。
以下选项将启用所有错误:
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(-1);
另请参阅以下链接
- http://php.net/manual/en/errorfunc.configuration.php#ini.display-errors
- http://php.net/manual/en/errorfunc.configuration.php#ini.display-startup-errors
- http://php.net/manual/en/function.error-reporting.php
评论
ini_set
如果你超级酷,你可以尝试:
$test_server = $_SERVER['SERVER_NAME'] == "127.0.0.1" || $_SERVER['SERVER_NAME'] == "localhost" || substr($_SERVER['SERVER_NAME'],0,3) == "192";
ini_set('display_errors',$test_server);
error_reporting(E_ALL|E_STRICT);
这只会在本地运行时显示错误。它还为您提供了test_server变量,以便在适当的其他地方使用。
在脚本运行之前发生的任何错误都不会被捕获,但对于我犯的 99% 的错误,这不是问题。
评论
$_SERVER['REMOTE_HOST']
要保持它并使其更舒适,您可以编辑您的 php.ini 文件。它通常存储在 或 中,但更多的本地 可能会覆盖它,具体取决于您的托管服务提供商的设置指南。检查顶部的文件,以确保最后加载哪个文件。/etc/php.ini
/etc/php/php.ini
php.ini
phpinfo()
Loaded Configuration File
在该文件中搜索display_errors。应该只有 3 个实例,其中 2 个被注释。
将未注释的行更改为:
display_errors = stdout
为了快速、动手地进行故障排除,我通常建议在 SO 上:
error_reporting(~0); ini_set('display_errors', 1);
放在正在进行故障排除的脚本的开头。这并不完美,完美的变体是你也在 和 你在 PHP 中记录错误以捕获语法和启动错误。php.ini
此处概述的设置显示所有错误、通知和警告,包括严格的错误、通知和警告,无论哪个 PHP 版本。
接下来要考虑的事项:
- 安装 Xdebug 并使用 IDE 启用远程调试。
另请参阅:
在页面顶部,选择一个参数
error_reporting(E_ERROR | E_WARNING | E_PARSE);
打开错误报告是正确的解决方案,但是它似乎不会在打开它的程序中生效,而只会在随后包含的程序中生效。
因此,我总是创建一个文件/程序(我通常称之为“genwrap.php”),其代码与这里的流行解决方案(即打开错误报告)基本相同,然后它还包含我实际想要调用的页面。
实现此调试有 2 个步骤;
一 - 创建genwrap.php并将以下代码放入其中:
<?php
error_reporting(-1);
ini_set('display_errors', 'On');
include($_REQUEST['page']);
?>
二 - 将要调试的程序/页面的链接更改为通过 genwrap.php,
例如:更改:
$.ajax('dir/pgm.php?param=val').done(function(data) { /* ... */
自
$.ajax('dir/genwrap.php?page=pgm.php¶m=val').done(function(data) { /* ... */
以下代码应显示所有错误:
<?php
// ----------------------------------------------------------------------------------------------------
// - Display Errors
// ----------------------------------------------------------------------------------------------------
ini_set('display_errors', 'On');
ini_set('html_errors', 0);
// ----------------------------------------------------------------------------------------------------
// - Error Reporting
// ----------------------------------------------------------------------------------------------------
error_reporting(-1);
// ----------------------------------------------------------------------------------------------------
// - Shutdown Handler
// ----------------------------------------------------------------------------------------------------
function ShutdownHandler()
{
if(@is_array($error = @error_get_last()))
{
return(@call_user_func_array('ErrorHandler', $error));
};
return(TRUE);
};
register_shutdown_function('ShutdownHandler');
// ----------------------------------------------------------------------------------------------------
// - Error Handler
// ----------------------------------------------------------------------------------------------------
function ErrorHandler($type, $message, $file, $line)
{
$_ERRORS = Array(
0x0001 => 'E_ERROR',
0x0002 => 'E_WARNING',
0x0004 => 'E_PARSE',
0x0008 => 'E_NOTICE',
0x0010 => 'E_CORE_ERROR',
0x0020 => 'E_CORE_WARNING',
0x0040 => 'E_COMPILE_ERROR',
0x0080 => 'E_COMPILE_WARNING',
0x0100 => 'E_USER_ERROR',
0x0200 => 'E_USER_WARNING',
0x0400 => 'E_USER_NOTICE',
0x0800 => 'E_STRICT',
0x1000 => 'E_RECOVERABLE_ERROR',
0x2000 => 'E_DEPRECATED',
0x4000 => 'E_USER_DEPRECATED'
);
if(!@is_string($name = @array_search($type, @array_flip($_ERRORS))))
{
$name = 'E_UNKNOWN';
};
return(print(@sprintf("%s Error in file \xBB%s\xAB at line %d: %s\n", $name, @basename($file), $line, $message)));
};
$old_error_handler = set_error_handler("ErrorHandler");
// other php code
?>
使用此代码生成空白页的唯一方法是在关闭处理程序中出现错误时。我从我自己的 cms 复制并粘贴了它而没有对其进行测试,但我确信它有效。
评论
ShutdownHandler
E_NOTICE
“错误”是开发人员了解错误并解决它们以使系统完美运行的最有用的东西。
PHP 提供了一些更好的方法来了解开发人员为什么以及他们的代码段在哪里出现错误,因此通过了解这些错误,开发人员可以在许多方面改进他们的代码。
在脚本顶部编写以下两行以获取所有错误消息的最佳方法:
error_reporting(E_ALL);
ini_set("display_errors", 1);
在 IDE 中使用调试器工具(如 xdebug)的另一种方法。
PHP配置
php.ini 中的 2 个条目决定了错误的输出:
在生产中,通常设置为 (这是一件好事,因为在生产站点中显示错误通常是不可取的!display_errors
Off
但是,在开发中,应将其设置为 ,以便显示错误。检查!On
error_reporting
(从 PHP 5.3 开始)默认设置为 (这意味着,除了通知、严格标准和弃用通知之外,所有内容都会显示)。如有疑问,请将其设置为显示所有错误。检查!E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
E_ALL
哇哇!没有检查!我无法更改我的php.ini!
那真是太可惜了。通常共享主机不允许更改其php.ini文件,因此,该选项很遗憾不可用。但不要害怕!我们还有其他选择!
运行时配置
在所需的脚本中,我们可以在运行时更改 php.ini 条目!这意味着,它将在脚本运行时运行!甜!
error_reporting(E_ALL);
ini_set("display_errors", "On");
这两行将产生与更改上述 php.ini 条目相同的效果!棒!
我仍然收到空白页/500 错误!
这意味着脚本甚至还没有运行!这通常发生在语法错误时!
由于语法错误,脚本甚至无法进入运行时。它在编译时失败,这意味着它将使用 php.ini 中的值,如果您没有更改,则可能不允许显示错误。
错误日志
此外,PHP 默认记录错误。在共享主机中,它可能位于专用文件夹中,也可能与违规脚本位于同一文件夹中。
如果您有权访问 php.ini,则可以在error_log
条目下找到它。
评论
include
从 PHP 中获取有用错误所需的两个关键行是:
ini_set('display_errors',1);
error_reporting(E_ALL);
正如其他贡献者所指出的,出于安全原因,这些默认是关闭的。作为一个有用的提示 - 当您设置站点时,可以方便地为不同的环境进行切换,以便这些错误在本地和开发环境中默认处于打开状态。这可以通过以下代码来实现(最好在索引.php或配置文件中,因此从一开始就处于活动状态):
switch($_SERVER['SERVER_NAME'])
{
// local
case 'yourdomain.dev':
// dev
case 'dev.yourdomain.com':
ini_set('display_errors',1);
error_reporting(E_ALL);
break;
//live
case 'yourdomain.com':
//...
break;
}
您可能还想尝试使用 PHPStorm 作为您的代码编辑器。当您在编辑器中键入时,它会发现许多 PHP 和其他语法错误。
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
ini_set('html_errors', 1);
此外,您还可以使用 xdebug 获取更详细的信息。
评论
如果您是 Ubuntu 用户,请转到您的终端并运行此命令
sudo tail -50f /var/log/apache2/error.log
它将显示最近的 50 个错误。
apache2 有一个错误文件,它记录了所有错误。error.log
除了上面很多很好的答案之外,您还可以在项目中实现以下两个功能。他们将在应用程序/脚本退出之前捕获每个非语法错误。 在函数中,您可以进行回溯并记录或向公众呈现令人愉快的“网站正在维护中”消息。
致命错误:
register_shutdown_function
http://php.net/manual/en/function.register-shutdown-function.php
错误:
set_error_handler
http://php.net/manual/en/function.set-error-handler.php
回溯:
debug_backtrace
http://php.net/manual/en/function.debug-backtrace.php
我推荐 Nette Tracy 来更好地可视化 PHP 中的错误和异常:
评论
这是加载配置与运行时配置的问题
重要的是要认识到,在编译或解析步骤中会发生语法错误或解析错误,这意味着 PHP 甚至在有机会执行您的任何代码之前就会保释。因此,如果你在运行时修改PHP的配置(这包括从在代码中使用到使用.htaccess,这是一个运行时配置文件)的任何内容,那么只有默认的加载配置设置在起作用。display_errors
ini_set
如何在开发中始终避免 WSOD
为了避免 WSOD,您需要确保加载的配置文件已打开并设置为(这是等效E_ALL,因为它确保无论您运行哪个版本的 PHP,所有位都已打开)。不要对 E_ALL 的常量值进行硬编码,因为该值在不同版本的 PHP 之间可能会发生变化。display_errors
error_reporting
-1
加载的配置是加载的文件或 or 或 virtualhost 文件。这些文件仅在启动阶段读取一次(例如,当您首次启动 apache httpd 或 php-fpm 时),并且仅被运行时配置更改覆盖。确保在加载的配置文件中,确保永远不会看到 WSOD,无论在运行时更改之前发生的语法或分析错误如何,例如或可能发生。php.ini
apache.conf
httpd.conf
display_errors = 1
error_reporting = -1
ini_set('display_errors', 1);
error_reporting(E_ALL);
如何找到(php.ini)加载的配置文件
要找到加载的配置文件,只需使用以下代码创建一个新的 PHP 文件...
<?php
phpinfo();
然后将浏览器指向那里,查看已加载的配置文件和解析的其他 .ini 文件,它们通常位于 your 的顶部,将包含所有已加载配置文件的绝对路径。phpinfo()
如果您看到的不是文件,则表示配置文件 (php.ini) 路径中没有 php.ini。因此,您可以从此处下载与PHP捆绑在一起的php.ini,并将其作为php.ini复制到配置文件路径中,然后确保您的php用户有足够的权限从该文件中读取。您需要重新启动 httpd 或 php-fpm 才能将其加载。请记住,这是与 PHP 源代码捆绑在一起的开发 php.ini 文件。所以请不要在生产中使用它!(none)
只是不要在生产中这样做
这确实是避免开发中 WSOD 的最佳方法。任何建议你把 或放在你的 PHP 脚本的顶部或使用 .htaccess 的人,就像你在这里所做的那样,如果你加载的配置文件已经关闭,当发生语法或解析错误时(就像你在这里的情况一样),不会帮助你避免 WSOD。ini_set('display_errors', 1);
error_reporting(E_ALL);
display_errors
许多人(以及 PHP 的库存安装)会使用默认关闭的 production-ini 文件,这通常会导致您在这里遇到的同样挫败感。因为 PHP 在启动时已经关闭了它,然后遇到语法或解析错误,并且没有任何输出。你希望你的 PHP 脚本顶部应该避免这种情况,但如果 PHP 无法解析你的代码也没关系,因为它永远不会到达运行时。display_errors
ini_set('display_errors',1);
可以注册一个钩子,使最后一个错误或警告可见。
function shutdown(){
var_dump(error_get_last());
}
register_shutdown_function('shutdown');
将此代码添加到索引 .php 的开头将帮助您调试问题。
评论
您也可以在终端(命令行)中运行该文件,如下所示:.php -f filename.php
这将运行您的代码,并在出现任何错误时为您提供相同的输出。它提到了错误和行号。error.log
对于那些使用 nginx 并且即使文件也有白屏的人。就我而言,我在nginx配置文件中没有PHP所需的选项:<?php echo 123;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
此选项不fastcgi_params文件中,因此 PHP 不起作用,日志中没有任何错误。
评论
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
除了这里所有精彩的答案之外,我还想特别提到MySQLi和PDO库。
为了...
- 始终看到与数据库相关的错误,以及
- 避免检查方法的返回类型以查看是否出错
最好的选择是将库配置为引发异常。
MySQLi的
将此项添加到脚本顶部附近
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
最好在使用或 之前将其放置。new mysqli()
mysqli_connect()
PDO的
将属性设置为 on your connection instance。您可以在构造函数中执行此操作PDO::ATTR_ERRMODE
PDO::ERRMODE_EXCEPTION
$pdo = new PDO('driver:host=localhost;...', 'username', 'password', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
或创建后
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
这个答案是由裁员部门带给大家的。
ini_set()
/ php.ini / .htaccess / .user.ini这些设置现在已经足够覆盖了。但只是回顾一下何时使用哪个选项:
display_errors
error_reporting
ini_set(
) 和error_reporting()
仅适用于运行时错误。php.ini
应该主要针对开发设置进行编辑。(Web服务器和CLI版本通常具有不同的php.ini).htaccess
标志仅适用于过时的设置(寻找新的托管商!管理良好的服务器更便宜。.user.ini
是用于现代设置 (FCGI/FPM) 的部分 php.ini
作为运行时错误的粗略替代方法,您通常可以使用:
set_error_handler("var_dump"); // ignores error_reporting and `@` suppression
-
可用于在禁用 error_display 时检索上次运行时通知/警告/错误。
-
是一个超局部变量,它还包含最后的 PHP 运行时消息。
isset()
消失了!我知道这会让很多人不高兴,但新人不应该使用
isset
和empty
。您可以在验证代码正常工作后添加通知禁止显示。但从未有过。我们最近遇到的很多“有些东西不起作用”的问题都是错别字的结果,例如:
if(isset($_POST['sumbit'])) # ↑↑
如果你的代码中充斥着 //,你不会收到任何有用的通知。有时使用
@
更明智,因此至少会将通知和警告发送到日志中。isset
empty
array_keys_exists
assert_options(ASSERT_ACTIVE|ASSERT_WARNING);
获取分区的警告。(非常不常见,但更熟练的代码可能包含一些。
assert()
PHP7 在 php.ini 中也需要
zend.assertions=1
。-
将 PHP 转换为严格类型化的语言不会修复很多逻辑错误,但它绝对是调试目的的一个选项。
PDO / MySQLi的
@Phil已经提到了 PDO/MySQLi 错误报告选项。当然,其他数据库 API 也存在类似的选项。
json_last_error()
+json_last_error_msg
用于 JSON 解析。
-
对于正则表达式。
-
要调试 curl 请求,您至少需要CURLOPT_VERBOSE。
-
同样,shell 命令执行本身也不会产生错误。你总是需要并偷看$errno。
2>&1
PHP 错误处理
有时,应用程序将无法按预期运行,从而导致错误。有许多原因可能导致错误,例如:
Web 服务器可能磁盘空间不足 用户可能在表单字段中输入了无效值 您尝试访问的文件或数据库记录可能不存在 应用程序可能没有写入磁盘上的文件的权限 应用程序需要访问的服务可能暂时不可用 这些类型的错误称为运行时错误,因为它们在脚本运行时发生。它们与脚本运行之前需要修复的语法错误不同。
专业应用程序必须具备优雅地处理此类运行时错误的能力。通常,这意味着更清晰、更准确地告知用户问题。
了解错误级别
通常,当出现阻止脚本正常运行的问题时,PHP 引擎会触发错误。每个错误都由一个整数值和一个关联的常量表示。下表列出了一些常见的错误级别:
每当 PHP 引擎遇到脚本问题时,它都会触发错误,但您也可以自己触发错误以生成更用户友好的错误消息。这样,您可以使您的应用程序更加安全。以下部分描述了一些用于处理 PHP 中的错误的常用方法:
使用 die() 函数的基本错误处理
<?php // Try to open a non-existent file
$file = fopen("sample.txt", "r");
?>
如果该文件不存在,您可能会收到如下错误: 警告:fopen(sample.txt) [function.fopen]:无法打开流:第 2 行 C:\wamp\www\project\test.php 中没有这样的文件或目录
如果我们遵循一些简单的步骤,我们可以防止用户收到这样的错误消息:
<?php
if(file_exists("sample.txt")){
$file = fopen("sample.txt", "r");
} else{
die("Error: The file you are trying to access doesn't exist.");
}
?>
现在,如果您运行上述脚本,您将收到如下错误消息:错误:您尝试访问的文件不存在。
正如你所看到的,通过在尝试访问文件之前实现一个简单的检查文件是否存在,我们可以生成一个对用户更有意义的错误消息。
上面使用的 die() 函数只是显示自定义错误消息,并在未找到“sample.txt”文件时终止当前脚本。
创建自定义错误处理程序
您可以创建自己的错误处理函数来处理 PHP 引擎生成的运行时错误。自定义错误处理程序为您提供了更大的灵活性和更好的错误控制,它可以检查错误并决定如何处理错误,它可能会向用户显示消息,将错误记录在文件或数据库中或通过电子邮件发送,尝试解决问题并继续,退出脚本的执行或完全忽略错误。
自定义错误处理程序函数必须能够处理至少两个参数(errno 和 errstr),但它可以选择接受另外三个参数(errfile、errline 和 errcontext),如下所述:
下面是一个简单的自定义错误处理函数的示例。每当发生错误时,都会触发此处理程序 customError(),无论多么微不足道。然后,它将错误的详细信息输出到浏览器并停止脚本的执行。
<?php
// Error handler function
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
?>
你需要告诉 PHP 使用你的自定义错误处理函数——只需调用内置的 set_error_handler() 函数,传入函数的名称。
<?php
// Error handler function
function customError($errno, $errstr){
echo "<b>Error:</b> [$errno] $errstr";
}
// Set error handler
set_error_handler("customError");
// Trigger error
echo($test);
?>
错误记录
在文本文件中记录错误消息
您还可以将错误的详细信息记录到日志文件中,如下所示:
<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
$message = date("Y-m-d H:i:s - ");
$message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
$message .= "Variables:" . print_r($errcontext, true) . "\r\n";
error_log($message, 3, "logs/app_errors.log");
die("There was a problem, please try again.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>
触发错误
尽管 PHP 引擎在遇到脚本问题时会触发错误,但您也可以自己触发错误。这有助于使应用程序更加可靠,因为它可以在潜在问题变成严重错误之前将其标记出来。
若要从脚本中触发错误,请调用 trigger_error() 函数,并传入要生成的错误消息:
trigger_error("There was a problem.");
请考虑以下计算两个数字除法的函数。
<?php
function calcDivision($dividend, $divisor){
return($dividend / $divisor);
}
// Calling the function
echo calcDivision(10, 0);
?>
如果将零 (0) 的值作为 $divisor 参数传递,则 PHP 引擎生成的错误将如下所示: 警告:在第 3 行的 C:\wamp\www\project\test.php 中除以零
此消息看起来信息量不大。请考虑以下示例,该示例使用 trigger_error() 函数生成错误。
<?php
function calcDivision($dividend, $divisor){
if($divisor == 0){
trigger_error("The divisor cannot be zero", E_USER_WARNING);
return false;
} else{
return($dividend / $divisor);
}
}
// Calling the function
echo calcDivision(10, 0);
?>
现在,脚本生成以下错误消息:警告:第 4 行的 C:\wamp\www\project\error.php 中的除数不能为零
如您所见,与上一个示例相比,第二个示例生成的错误消息更清楚地解释了问题。
参考: https://www.tutorialrepublic.com/php-tutorial/php-error-handling.php
评论
我像这样解决了整个 500 个问题:
A. 检查 php.ini 参数
- 菲律宾比索.ini >> error_reporting = E_ALL |E_STRICT
- php.ini >> display_errors = 开
- php.ini >> display_startup_errors = 关闭
B. 更新 IIS 管理器参数
- IIS 管理器 >>错误页 >> 500 >> 编辑功能设置>>详细错误
在此步骤中,您将收到 500 个这样的错误,并且没有加载 HTML。
- IIS 管理器>> FastCGI 设置 >> php-cgi.exe >> 标准错误模式>> IgnoreAndReurn200
在此步骤中,您可以看到包含此类 PHP 错误的 HTML 页面。
并完成:)
评论
T_PAAMAYIM_NEKUDOTAYIM
php.exe -l <your file name>