关于调试:如何在PHP中获取有用的错误消息?

How to get useful error messages in PHP?

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

很难弄清楚出了什么问题。我最终会注释掉代码,在任何地方输入"echo"语句等,试图缩小问题的范围。但肯定有更好的方法,对吧?.

那么,有没有办法让PHP产生像Java那样有用的错误消息呢?有人能推荐优秀的PHP调试技巧、工具和技术吗?


对于语法错误,需要在php.ini中启用错误显示。默认情况下,由于您不希望"客户"看到错误消息,因此会关闭这些选项。在PHP文档中查看此页,以获取有关2个指令的信息:error_reportingdisplay_errorsdisplay_errors可能是你想要改变的。如果不能修改php.ini,还可以将以下行添加到.htaccess文件中:

1
2
php_flag  display_errors        on
php_value error_reporting       2039

您可能需要考虑将e_All的值(如gumbo所提到的)用于您的版本php for error_reporting,以获取所有错误。更多信息

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

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

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

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


以下选项启用所有错误:

1
2
3
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


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

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

这将覆盖php.ini中的默认设置,使php将错误报告到日志中。


PHP配置

2个固定的位置输出错误:dictate

  • display_errors
  • error_reporting
  • 在生产,通常设置为一个display_errorsOff(这是一件好事,因为错误显示的网站是理想的生产通常需要!)。。。。。。。

    然而,在发展中,应该设置为On这样的错误,得到显示。检查!

    error_reporting(AS PHP 5.3)是一个集E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED(默认是显示所有的意义,除了发出通知,严格的标准和deprecation)。当你在怀疑,它是集E_ALL显示所有的错误。检查!

    哇,哇!没有检查!我不能改变我的设置!

    这是一个耻辱。共享主机通常不允许改变他们的php.ini文件,所以,这是我无法选择。但你的痛苦!我们有其他的选择。

    运行时配置

    在所需的脚本,我们可以在运行时使用的php.ini的年龄!的意义,当它要运行的脚本运行。甜蜜的!

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

    论文要做两线相同的效果作为一个以上的altering为php.ini。真棒!

    我仍然得到一个空白页,500错误!

    这意味着他们甚至运行脚本!这通常发生时,你有一个语法错误!

    一个脚本的语法错误,甚至没有去运行。它没有意义,它在编译时,会使用固定的值,但如果你没用了,可能不允许显示错误。

    错误日志

    此外,默认的PHP错误日志。在共享的主机,它可以在一个专用的文件夹或在同一文件夹作为offending脚本。

    如果您有访问php.ini文件,你可以找到它在error_log入口。


    有一个非常有用的扩展名为"xdebug",它可以使您的报告更加出色。


    为了快速进行实际操作的故障排除,我通常在这里建议这样做:

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

    将放在正在进行故障排除的脚本的开头。这是不完美的,完美的变体是您还可以在php.ini中启用它,并在php中记录错误以捕获语法和启动错误。

    这里概述的设置显示所有错误、通知和警告,包括严格的错误、通知和警告,无论哪个PHP版本。

    接下来要考虑的事情:

    • 安装xdebug并使用您的IDE启用远程调试。

    也可以看到:

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

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

    1
    2
    3
    4
    $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_服务器变量。

    在脚本运行之前发生的任何错误都不会被捕获,但是对于我所犯的99%的错误,这不是问题。


    为了保持这一点并使其舒适,您可以编辑php.ini文件。它通常存储在/etc/php.ini/etc/php/php.ini中,但更多的本地php.ini可能会覆盖它,这取决于宿主提供商的设置指南。检查顶部的Loaded Configuration Filephpinfo()文件,以确定最后加载的是哪个文件。

    在该文件中搜索显示错误。应该只有3个实例,其中2个是注释的。

    将未注释的行更改为:

    1
    display_errors = stdout

    在页面顶部选择一个参数

    1
    error_reporting(E_ERROR | E_WARNING | E_PARSE);


    很不错的一个可视化(特雷西错误和异常:在PHP

    Nette Tracy screenshot


    1
    2
    3
    error_reporting(E_ALL | E_STRICT);
    ini_set('display_errors', 1);
    ini_set('html_errors', 1);

    此外,你可以得到更详细的信息带到。


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

    1
    error_reporting(E_ALL | E_STRICT);

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


    您可以在PHP中注册自己的错误处理程序。例如,将所有错误转储到一个文件可能有助于处理这些不明确的情况。请注意,无论当前的错误报告设置为什么,都将调用函数。非常基本的例子:

    1
    2
    3
    4
    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');


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


    所以你可能想尝试phpstorm AS代码编辑器。它会发现许多PHP语法错误和其他人在你打字和编辑。


    两线你需要得到有用的关键是:从PHP错误

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

    作为替代的其他contributors退房,这是默认的安全开关关闭的原因。作为一个有用的技巧,当你设置你的网站,它为您的手机待办事项a开关不同的环境,这样的错误是在从默认的本地开发环境。这可以实现与下面的代码(在你的index.php文件或配置文件的历史是这样的:从启动Active)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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;
    }

    如果你是一个Ubuntu的用户,然后转到您的终端和运行这个命令

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

    它会显示最近的50个错误。有一个错误的日志文件error.logApache2是所有错误的。


    FireHP也很有用。


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

    1
    error_reporting = E_ALL | E_STRICT

    E_STRICT将通知您不推荐使用的功能,并向您推荐执行某些任务的最佳方法。

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

    1
    error_reporting = (E_ALL | E_STRICT) & ~E_NOTICE

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

    1
    display_errors ="On"

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

    1
    display_errors ="stderr"

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

    这甚至会导致最小的警告出现。以防万一:

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

    将强制显示错误。这应该在生产服务器中关闭,但在开发时不应该关闭。


    除了错误报告和显示错误ini设置之外,您还可以从Web服务器的日志文件中获取语法错误。在开发PHP时,我将开发系统的Web服务器日志加载到编辑器中。每当我测试一个页面并得到一个空白屏幕时,日志文件就会过时,我的编辑器会询问我是否要重新加载它。当我这样做的时候,我会跳到底部,这里有语法错误。例如:

    1
    [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提供了一些更好的方法来了解开发人员为什么以及在哪里获取错误,因此,通过了解这些错误,开发人员可以在许多方面改进代码。

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

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

    在您的IDE中使用类似xdebug的调试器工具的另一种方法。


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

    为了。。。

  • 始终查看与数据库相关的错误,以及
  • 避免检查返回类型中的方法以查看是否出错
  • 最好的选择是配置库以抛出异常。

    米斯利

    将此添加到脚本顶部附近

    1
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

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

    PDO

    在连接实例上将PDO::ATTR_ERRMODE属性设置为PDO::ERRMODE_EXCEPTION。您可以在构造函数中这样做

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

    或者在创造之后

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


    打开错误报告是正确的解决方案,但是它似乎在打开它的程序中不起作用,但只在随后包含的程序中起作用。

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

    执行此调试有两个步骤;

    一个-创建genwrap.php并将此代码放入其中:

    1
    2
    3
    4
    5
    6
    <?php
    error_reporting(-1);
    ini_set('display_errors', 'On');

    include($_REQUEST['page']);
    ?>

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

    Eg:变化:

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

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

    使用的获得。这是调试命令的组合的类固醇。http:/ / / / kint-php.github.io金它非常类似于漂亮的特雷西


    http://todell.com /调试可以是有用的为好。你可以走你的目标值或海上调试错误的场景背后的产品生产模式。


    除了非常多优秀的答案。所以,你可以实现两个功能在您的项目。他们会抓住每一个非语法错误在应用程序/脚本退出。你可以在函数do a回溯和日志或渲染一个愉快的网站维护的消息是在一个公共的。

    致命的错误:

    http://net/手册/恩/ function.register-shutdown-function.php

    错误:

    http://net/手册/恩/ function.set-error-handler.php

    回溯:

    http://net/手册/恩/ function.debug-backtrace.php


    我通常遇到的问题是"小的,愚蠢的"解析器错误,不幸的是,这些错误并没有出现。

    但是,当.php文件包含有语法错误的文件时,就会显示这些错误!所以我想写一个小的"执行者脚本",以错误文件的名字作为论据,即example.com/sx.php?sc=buggy.php

    它已经让我从很多头痛中解脱出来了,也许它对其他人也会有帮助。

    PHP

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $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);
    }
    ?>