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

很难找出哪里出了问题。我最终注释掉了代码,到处输入“echo”语句,等等,试图缩小问题的范围。但肯定有更好的办法,对吧?

是否有一种方法可以让PHP像Java那样产生有用的错误消息?


当前回答

一些应用程序确实自己处理这些指令,通过调用这样的命令:

error_reporting(E_ALL & ~E_DEPRECATED); or error_reporting(0);

从而覆盖你的。htaccess设置。

其他回答

除了error_reporting和display_errors ini设置外,您还可以从web服务器的日志文件中获得语法错误。当我在开发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_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;
}

这是一个加载配置与运行时配置的问题

重要的是要认识到在编译或解析步骤中会发生语法错误或解析错误,这意味着PHP甚至在有机会执行任何代码之前就会退出。因此,如果你在运行时修改PHP的display_errors配置(这包括在代码中使用ini_set到使用.htaccess,这是一个运行时配置文件),那么只有默认加载的配置设置在起作用。

如何在开发中始终避免WSOD

为了避免WSOD,您需要确保加载的配置文件具有display_errors,并将error_reporting设置为-1(这相当于E_ALL,因为它确保无论您运行的是哪个版本的PHP,所有位都是打开的)。不要硬编码E_ALL的常量值,因为该值在不同版本的PHP之间可能会发生变化。

Loaded configuration is either your loaded php.ini file or your apache.conf or httpd.conf or virtualhost file. Those files are only read once during the startup stage (when you first start apache httpd or php-fpm, for example) and only overridden by runtime configuration changes. Making sure that display_errors = 1 and error_reporting = -1 in your loaded configuration file ensures that you will never see a WSOD regardless of syntax or parse error that occur before a runtime change like ini_set('display_errors', 1); or error_reporting(E_ALL); can take place.

如何找到你(php.ini)加载的配置文件

要定位您加载的配置文件,只需用以下代码创建一个新的PHP文件…

<?php
phpinfo();

然后将浏览器指向那里,查看已加载配置文件和已解析的附加.ini文件,它们通常位于phpinfo()的顶部,并将包括所有已加载配置文件的绝对路径。

如果你看到(none)而不是文件,这意味着你在配置文件(php.ini)路径中没有php.ini。因此,您可以从这里下载与PHP捆绑的库存PHP .ini,并将其复制到您的配置文件路径作为PHP .ini,然后确保您的PHP用户有足够的权限从该文件读取。您需要重新启动httpd或php-fpm来加载它。记住,这是PHP源代码附带的开发PHP .ini文件。所以请不要在生产中使用它!


只是不要在生产中这样做

这确实是在开发过程中避免WSOD的最佳方法。有人建议你把ini_set('display_errors', 1);或error_reporting (E_ALL);在你的PHP脚本顶部或使用.htaccess,就像你在这里所做的,不会帮助你避免WSOD当语法或解析错误发生时(就像你在这里的情况),如果你加载的配置文件已经display_errors关闭。

Many people (and stock installations of PHP) will use a production-ini file that has display_errors turned off by default, which typically results in this same frustration you've experienced here. Because PHP already has it turned off when it starts up, then encounters a syntax or parse error, and bails with nothing to output. You expect that your ini_set('display_errors',1); at the top of your PHP script should have avoided that, but it won't matter if PHP can't parse your code because it will never have reached the runtime.

可以通过注册钩子来显示最后一个错误或警告。

function shutdown(){
  var_dump(error_get_last());
}

register_shutdown_function('shutdown');

将此代码添加到index.php的开头将有助于调试问题。

我推荐Nette Tracy来更好地可视化PHP中的错误和异常: