2009-09-25 99 views
95

现在我开始回到PHP,我开始记住为什么我放弃了它。我现在最讨厌的东西就是我所说的“PHP的死亡白屏”。当PHP由于语法或其他原因而发生致命错误时,似乎在没有实际向浏览器发送任何东西的情况下,它总是会死掉。我已将以下内容添加到我的.htaccess中,并且它似乎在大多数情况下都能正常工作,但在这些情况下不起作用。PHP的死亡白屏

php_value display_errors 1 
php_value display_startup_errors 1 
php_value error_reporting 2147483647 # E_ALL 

我错过了什么吗?目前,我觉得我需要刷新每隔几行我写的代码,以免我犯了一个错误,不得不搜索很多页面,试图追查我犯的一个小错误...

编辑:例如,给定的下面的两行代码:

$foo = array(':language' => $languageId; 
$foo = array(':language' => $languageId); 

第一将表现出死亡的白色屏幕(即,什么都没有印刷到浏览器),而第二个将愉快地执行。

+0

另请参阅http://stackoverflow.com/q/845021/632951 – Pacerier 2014-10-14 09:40:05

回答

45

错误和警告通常出现在....\logs\php_error.log....\logs\apache_error.log,具体取决于您的php.ini设置。

也有用的错误往往是针对浏览器,但因为他们是无效的HTML他们不显示。

所以"tail -f“你的日志文件,当你得到一个空白屏幕使用IE的‘查看’ - >‘源’菜单选项来查看原始输出

+11

不幸的是,查看页面源代码也不显示任何内容。 – 2009-09-25 04:40:13

+2

解析错误应该在Apache的错误日志中可见,无论您在其他地方拥有什么设置。如果您无法控制服务器,那么获取apache错误日志可能会很困难,但我建议您与您的提供者交谈,并且有办法向您公开错误日志。除此之外,我只能建议其他人有什么 - 在部署到生产环境之前,检查您的代码以解析本地开发服务器中的错误。另外,验证IDE(如Eclipse的PDT)可能会有很大的帮助。 – Guss 2009-09-25 06:51:10

+5

回想起来,我最近遇到了一个堆栈溢出问题,即使在日志中也没有产生任何错误,直到我将xdebug安装到服务器中时才表现出来。嘎。 – 2011-05-30 23:44:48

2

尝试设置在实际的PHP文件在您的错误报告级别。 。或者像其他人所说的那样,检查你的服务器设置 - 它可能是php.ini中的一些东西,或者对你的主机有一些限制。不要只依赖.htaccess。而且,在排除故障时,print_r你可能需要的变量认为可疑

+0

我无权访问php.ini。当这些错误弹出时,这是一个语法错误,所以print_r不起作用。 – 2009-09-25 04:36:13

+3

如果您无权访问php.ini,则不应该在该服务器上进行开发。使用共享主机进行生产,使用本地机器进行开发。 – carl 2009-09-25 04:46:25

+0

当生产中发生错误?我们都希望相信这不会发生,但确实如此。 – 2009-09-25 04:48:55

2

您确定PHP实际上是从.htaccess获取'display_errors'设置吗?请检查phpinfo()函数的输出以确保。

此外,您应该检查以确保您没有使用'@',如果您使用了'@include ...'或'@some_function(...)',它可能会使您的错误变得沉默,堆栈跟踪的某处。

+0

是的。 'display_errors'在服务器范围的配置中关闭,但它显示较小的错误,如参数号码不匹配等。我没有在这个项目中使用'@'运算符,并且通常倾向于避免出于这个原因。 – 2009-09-25 04:47:06

+0

您还应该检查display_errors没有被某个PHP脚本更改。 – 2009-09-25 04:56:07

+0

我从头开始构建这个框架,所以不,它不是(除非核心中的某些内容因为某种原因而改变它) – 2009-09-25 05:18:28

-1

如果错误出现在PHP代码中,您可以在代码中使用error_reporting()函数设置为全部报告。

但是,这不处理PHP崩溃的情况。有关信息仅在服务器日志中可用。也许您无法访问这些内容,但许多与我合作的托管提供商都有一些方法可以让您访问它。例如,我最喜欢的方法是在.php所在的当前目录中创建error_log文件。尝试在那里搜索或与您的托管服务提供商联系。

0

某些应用程序处理这些指令本身,通过调用像这样:

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

并由此覆盖你的.htaccess设置。

28

我总是在PHP脚本的最顶端使用这种语法。

ini_set('error_reporting', E_ALL); 
ini_set('display_errors', 'On'); //On or Off 
+2

对不起,但-1没有阅读已发布的其他答案。这已经在多次提到的.htaccess中处理完毕。 – 2009-09-25 07:57:28

+7

通常的“免费托管”忽略.htaccess – FDisk 2009-09-25 08:02:40

+0

让我摆脱束缚。谢谢。 – 2009-11-11 23:23:36

14

不知道是否会有帮助,但这里是我的标准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>"); 
} 
+0

出于好奇,“APPLICATION_LIVE”通常定义在哪里? – 2009-09-25 10:46:17

+0

@Mthethew Scharley - 更新。 – Eli 2009-09-25 21:36:33

+0

@Eli,尽管如此,每个页面请求**都有一个运行时间开销**。 – Pacerier 2014-10-14 09:35:00

0

在代码中使用@inexistent_function_call();将导致intepreter静静地死去,中止脚本解析。您应该检查无效的功能,尽量不要使用错误supressing经营者(@字符)

4

打开你的php.ini, 确保它的设置为:

display_errors = On 

重新启动服务器。

0

当服务器配置中没有正确包含fastcgi_paramsfastcgi.conf配置文件时,我也看到了这样的错误。所以对我来说修复是一个愚蠢的:

include /etc/nginx/fastcgi_params;

花了我一个小时找到了...

140

下面的代码应显示所有错误:

<?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([email protected]_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没有测试它,但我相信它的工作原理。

+3

非常感谢这真的很有用,让我走出了一个巨大的洞:) +1 – 2014-03-24 02:08:24

+7

这应该是接受的答案,它帮助我在一个教条/ symfony2应用程序中。 – 2014-08-01 11:25:55

+1

谢谢你救了我的一天,非常有用! – SuN 2014-09-03 14:54:05

16

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

认识到语法错误或分析错误发生在编译解析一步,这意味着PHP将保释它甚至在这一点很重要有机会执行你的任何代码。所以,如果你在运行时修改PHP的display_errors配置,(这包括在你的代码使用的.htaccess,这是一个运行时配置文件使用ini_set任何东西),那么只有默认加载配置设置在起作用。

如何始终避免发展WSOD

为避免你想确保你的加载的配置文件display_errorserror_reporting设置为-1这相当于E_ALL一个WSOD,因为它确保所有无论你正在运行)的PHP版本的位被打开。不要硬编码E_ALL的恒定值,因为该值是受到不同版本的PHP之间进行切换。

加载的配置是您的加载的php.ini文件或您的apache.confhttpd.conf或虚拟主机文件。这些文件仅在启动阶段(例如,首次启动apache httpd或php-fpm时)仅读取一次,并且仅由运行时配置更改覆盖。确保已加载的配置文件中的display_errors = 1error_reporting = -1可确保您永远不会看到WSOD,而不管发生运行时变化(如ini_set('display_errors', 1);error_reporting(E_ALL);)之前发生的语法或解析错误。

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

要找到您加载配置文件(S)刚刚创建,只有下面的代码一个新的PHP文件...

<?php 
phpinfo(); 

然后将您的浏览器指向加载的配置文件解析的其他.ini文件,它们通常位于您的phpinfo()的顶部,并将包含所有加载的配置文件的绝对路径。

如果您看到(none)而不是该文件,那意味着您没有在配置文件(php.ini)路径中的php.ini。所以你可以download the stock php.ini bundled with PHP from here并将它复制到你的配置文件路径中,如php.ini,然后确保你的php用户有足够的权限来读取该文件。你需要重新启动的httpd或php-fpm的加载它。记住,这是自带的PHP源捆绑发展 php.ini文件。所以请不要在生产中使用它!


只是不这样做在生产

这确实是避免在发展中WSOD的最佳途径。有人建议你把ini_set('display_errors', 1);error_reporting(E_ALL);在你的PHP脚本的顶部或使用的.htaccess像你这样在这里,是不是会帮助你避免WSOD当一个语法或者如果你的加载解析发生错误(比如你的情况在这里)配置文件已关闭display_errors

许多人(和PHP的股票安装)将使用生产ini文件,默认关闭display_errors,这通常会导致您在此遇到的同样的挫折感。由于PHP在启动时已将其关闭,因此遇到语法或解析错误,并且无法输出。您期望您的PHP脚本顶部的ini_set('display_errors',1);应该可以避免这种情况,但如果PHP无法解析代码,那么它将无关紧要,因为它永远不会到达运行时。

+0

辉煌答案@Sherif! – 2016-05-18 11:43:13

16

它可以注册一个钩子,使过去的错误或警告可见。

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

register_shutdown_function('shutdown'); 

将此代码添加到你开始的index.php会帮你调试的问题。

+1

救了我一命人! – webmaster 2017-04-04 17:13:52

+1

这对于那些在虚拟主机中卡住的人来说是纯粹的黄金,它不会显示任何错误,但允许零日志访问 – 2017-04-26 18:34:52

0

您也可以运行在终端(命令行)的文件,像这样:php -f filename.php

这将运行你的代码,让您在你的error.log看到任何错误的情况下相同的输出。它提到了错误和行号。

0

对于那些谁使用nginx的,有一个白色的屏幕甚至对于<?php echo 123;文件。在我来说,我没有对PHP这需要选项nginx的配置文件:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 

此选项是不是在fastcgi_params文件,因此PHP没有工作,有没有在日志中的任何错误。