如何在PHP中获取有用的错误消息?

我觉得用PHP编程非常令人沮丧。 我经常尝试运行脚本,然后再回一个空白屏幕。 没有错误信息,只是空屏幕。 原因可能是一个简单的语法错误(错误的括号,缺少分号),或者函数调用失败,或者其他完全错误。

弄清楚出了什么问题是非常困难的。 我最终评论出代码,在所有地方输入“echo”语句,等等。试图缩小问题范围。 但肯定有一个更好的方法,对吗?

那么,有没有办法让PHP产生像Java那样有用的错误信息呢? 任何人都可以推荐良好的PHP调试技巧,工具和技术?

对于语法错误,您需要在php.ini中启用错误显示。 默认情况下,这些是关闭的,因为您不希望“客户”看到错误消息。 有关2指令的信息, 请查看 PHP文档中的此页面 : error_reportingdisplay_errorsdisplay_errors可能是您要更改的那个。 如果无法修改php.ini,还可以将以下行添加到.htaccess文件中:

 php_flag display_errors on php_value error_reporting 2039 

您可能需要考虑使用E_ALL的值(如Gumbo所述)为您的PHP版本进行error_reporting以获取所有错误。 更多信息

3其他项目:(1)您可以检查错误日志文件,因为它将包含所有错误(除非已禁用日志记录)。 (2)添加以下2行将帮助您调试非语法错误的错误:

 error_reporting(-1); ini_set('display_errors', 'On'); 

(3)另一种选择是使用编辑器在键入时检查错误,例如PhpEd 。 PhpEd还带有一个调试器,可以提供更详细的信息。 (PhpEd调试器与xdebug非常相似,可直接集成到编辑器中,因此您可以使用1个程序来完成所有操作。)

Cartman的链接也非常好: http : //www.ibm.com/developerworks/library/os-debug/

以下内容可启用所有错误:

 ini_set('display_startup_errors', 1); ini_set('display_errors', 1); error_reporting(-1); 

另请参阅以下链接

您可以在要调试的文件中包含以下行:

 error_reporting(E_ALL); ini_set('display_errors', '1'); 

这会覆盖php.ini中的默认设置,这只会让PHP向日志报告错误。

PHP配置

php.ini中的 2个条目指示错误输出:

  1. display_errors
  2. error_reporting

生产中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条目下找到它。

有一个非常有用的扩展名为“ xdebug ”,它可以使您的报告更好。

对于快速的动手故障排除,我通常建议在SO:

 error_reporting(~0); ini_set('display_errors', 1); 

放在故障排除脚本的开头。 这不是完美的,完美的变体是你也在php.ini启用它,并在PHP中记录错误以捕获语法和启动错误。

此处列出的设置显示所有错误,通知和警告,包括严格的错误,无论哪个PHP版本。

接下来要考虑的事情:

  • 安装Xdebug并使用IDE启用远程调试。

另见:

  • 错误报告(PHP正确的方法。)
  • 预定义常量文档
  • error_reporting() 文档
  • display_errors 文件

如果你很酷,你可以试试:

 $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%的错误,这不是问题。

在页面顶部选择一个参数

 error_reporting(E_ERROR | E_WARNING | E_PARSE); 

要坚持这个并使其变得舒适,您可以编辑php.ini文件。 它通常存储在/etc/php.ini/etc/php/php.ini ,但更多本地php.ini可能会覆盖它,具体取决于您的托管服务提供商的设置准则。 检查顶部的Loaded Configuration Filephpinfo()文件,以确定最后加载哪个Loaded Configuration File

在该文件中搜索display_errors。 应该只有3个实例,其中2个被评论。

将未注释的行更改为:

 display_errors = stdout 
 error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 1); ini_set('html_errors', 1); 

此外,您可以使用xdebug获取更多详细信息。

我建议使用Nette Tracy更好地可视化PHP中的错误和exception:

Nette Tracy截图

 error_reporting(E_ALL | E_STRICT); 

并打开php.ini中的显示错误

您可以在PHP中注册自己的error handling程序 。 例如,将所有错误转储到文件可能会帮助您处理这些模糊的情况。 请注意,无论您当前的error_reporting设置为什么,都会调用您的函数。 很基本的例子:

 function dump_error_to_file($errno, $errstr) { file_put_contents('/tmp/php-errors', date('Ymd H:i:s - ') . $errstr, FILE_APPEND); } set_error_handler('dump_error_to_file'); 

试试这个PHP错误报告参考工具 。 这是一个非常好的视觉参考,帮助我理解复杂的错误报告机制。

您可能还想尝试使用PHPStorm作为代码编辑器。 当您在编辑器中输入时,它会发现许多PHP和其他语法错误。

从PHP中获取有用错误所需的两个关键行是:

 ini_set('display_errors',1); error_reporting(E_ALL); 

正如其他贡献者所指出的,出于安全原因,这些默认情况下会被关闭。 作为一个有用的提示 – 当您设置站点时,可以方便地为不同的环境进行切换,以便在本地和开发环境中默认启用这些错误。 这可以通过以下代码实现(理想情况下,在index.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; } 

FirePHP也很有用。

如果您是ubuntu用户,请转到终端并运行此命令

 sudo tail -50f /var/log/apache2/error.log 

它将显示最近50个错误。 apache2有一个错误文件error.log ,它记录了所有错误。

 ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); 

您可以启用完整错误报告(包括通知和严格消息)。 有些人觉得这个太冗长了,但值得一试。 将error_reporting设置为E_ALL | E_STRICT 你的php.ini中有E_ALL | E_STRICT

 error_reporting = E_ALL | E_STRICT 

E_STRICT将通知您有关已弃用的function,并为您提供有关执行某些任务的最佳方法的建议。

如果您不想要通知,但是您发现其他消息类型有用,请尝试排除通知:

 error_reporting = (E_ALL | E_STRICT) & ~E_NOTICE 

还要确保在php.ini中启用了display_errors 。 如果您的PHP版本早于5.2.4,请将其设置为On

 display_errors = "On" 

如果您的版本是5.2.4或更高版本,请使用:

 display_errors = "stderr" 

要打开完整错误报告,请将其添加到您的脚本中:

 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提供了一些更好的方法来了解开发人员为什么以及他们的代码片段在哪里获得错误,因此通过了解这些错误,开发人员可以通过多种方式使代码更好。

在脚本顶部写下以下两行以获取所有错误消息的最佳方法:

 error_reporting(E_ALL); ini_set("display_errors", 1); 

在IDE中使用调试工具(如xdebug)的另一种方法。

打开错误报告是正确的解决方案,但它似乎没有在打开它的程序中生效,但仅在随后包含的程序中生效。

因此,我总是创建一个文件/程序(我通常称之为“genwrap.php”),它与此处的流行解决方案具有基本相同的代码(即打开错误报告),然后它还包含我实际想要的页面呼叫。

实现此调试有两个步骤;

– 创建genwrap.php并将此代码放入其中:

  

– 通过genwrap.php更改要调试的程序/页面的链接,

例如:改变:

 $.ajax('dir/pgm.php?param=val').done(function(data) { /* ... */ 

 $.ajax('dir/genwrap.php?page=pgm.php&param=val').done(function(data) { /* ... */ 

http://todell.com/debug也很有用。 即使在生产模式下,您也可以在场景后面看到对象值或抛出调试错误。

除了上面的许多优秀答案,您还可以在项目中实现以下两个function。 它们将在应用程序/脚本退出之前捕获每个非语法错误。 在function内部,您可以进行回溯并记录或呈现令人愉快的“网站正在维护”消息给公众。

致命错误:

 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

使用Kint。 它是类固醇调试命令的组合。 https://kint-php.github.io/kint/它与Nette Tracy非常相似

除了这里的所有精彩答案之外,我还想特别提到MySQLi和PDO库。

为了…

  1. 总是看到数据库相关的错误,和
  2. 避免检查方法的返回类型以查看是否出错

最好的选择是配置库以引发exception 。

库MySQLi

将其添加到脚本顶部附近

 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 

在使用new mysqli()mysqli_connect()之前,最好先放置它。

PDO

在连接实例PDO::ERRMODE_EXCEPTION PDO::ATTR_ERRMODE属性设置为PDO::ATTR_ERRMODE 。 您可以在构造函数中执行此操作

 $pdo = new PDO('driver:host=localhost;...', 'username', 'password', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]); 

或者在创作之后

 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

我常见的问题是“小,愚蠢”的解析器错误,遗憾的是这些错误没有显示出来。

但是,当.PHP文件包含具有解析器错误的文件时,会显示它们! 所以我想写一个小的“执行器脚本”,它以buggy文件的名称作为参数启动,例如: example.com/sx.php?sc=buggy.php

它已经让我免于很多头痛,也许它对其他人也有帮助:)

sx.php

 $sc = $_GET["sc"]; if ((!isset($_GET["sc"]) && empty($_GET["sc"]))) { echo "Please select file to execute using ?sc= (you may omit the .PHP-extension)"; } else { $sc = $_GET["sc"]; if (false==stripos('.php',$sc)) $sc.='.php'; // adjust this if your preferred extension is php5! require($sc); } ?>