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

如何在PHP中获取有用的错误消息?,php,debugging,error-handling,Php,Debugging,Error Handling,我经常会尝试运行一个PHP脚本,然后返回一个空白屏幕。没有错误信息;只是一个空屏幕。原因可能是一个简单的语法错误(错误的括号,缺少分号),或者函数调用失败,或者完全是其他原因 很难找出哪里出了问题。最后我对代码进行注释,到处输入“echo”语句等等,试图缩小问题的范围。但肯定有更好的办法,对吧 有没有办法让PHP像Java一样生成有用的错误消息?对于语法错误,需要在PHP.ini中启用错误显示。默认情况下,这些选项处于关闭状态,因为您不希望“客户”看到错误消息。在PHP文档中,查看有关两条指令的

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

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


有没有办法让PHP像Java一样生成有用的错误消息?

对于语法错误,需要在PHP.ini中启用错误显示。默认情况下,这些选项处于关闭状态,因为您不希望“客户”看到错误消息。在PHP文档中,查看有关两条指令的信息:
error\u reporting
display\u errors
<代码>显示错误可能是您要更改的错误。如果无法修改php.ini,还可以将以下行添加到.htaccess文件中:

php_flag  display_errors        on
php_value error_reporting       2039

您可能想考虑使用EyALL(如GunbO所提到的)为PHP版本的代码< Error RooRebug < /代码>来获取所有的错误。p> 其他3项:(1)您可以检查错误日志文件,因为它将包含所有错误(除非已禁用日志记录)。(2) 添加以下两行将帮助您调试非语法错误的错误:

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

Cartman的也很好:

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

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|u ALL | E_STRICT

error_reporting = E_ALL | E_STRICT
E_STRICT
将通知您不推荐使用的函数,并为您提供执行某些任务的最佳方法的建议

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

error_reporting = (E_ALL | E_STRICT) & ~E_NOTICE
还要确保在php.ini中启用了
display\u errors
。如果您的PHP版本早于5.2.4,请将其设置为上的

display_errors = "On"
如果您的版本为5.2.4或更新版本,请使用:

display_errors = "stderr"

有一个名为“”的非常有用的扩展,它也会使您的报告更漂亮。

也很有用。

要启用完整的错误报告,请将以下内容添加到脚本中:

error_reporting(E_ALL);
这甚至会导致出现最小的警告。而且,以防万一:

ini_set('display_errors', '1');

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

除了错误报告和显示错误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

错误和警告通常出现在
…\logs\php\u error.log
…\logs\apache\u error.log
中,具体取决于您的php.ini设置

此外,有用的错误通常会指向浏览器,但由于它们不是有效的html,因此不会显示


因此
“tail-f
”您的日志文件,当您得到一个空白屏幕时,使用IEs“view”->“source”菜单选项来查看原始输出。

我总是在php脚本的最顶端使用此语法

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

我不知道这是否有帮助,但这里是我的php项目标准配置文件的一部分。即使在我自己的服务器上,我也不太依赖apache配置

我从来没有消失的错误的问题,所以也许这里的东西会给你一个想法

编辑以实时显示应用程序

/*
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>");
}
/*
应用程序_LIVE将在过程中用于判断我们是否处于开发或生产环境中。它通常在任何配置、url路由等之前尽早设置(通常是第一个运行的代码)。
*/
if(preg_match(“%^(www.)?livedomain.com$%”,$_服务器[“HTTP_主机])){
定义('APPLICATION_LIVE',true);
}elseif(preg_match(“%^(www.)?devdomain.net$%”,$_服务器[“HTTP_主机])){
定义('APPLICATION_LIVE',false);
}否则{
die(“无效的主机请求(“.$”服务器[“HTTP_主机]”));
//记录或采取其他适当的措施。
}
/*
--------------------------------------------------------------------
默认错误处理
--------------------------------------------------------------------
默认错误记录。其中一些可能会在以后根据应用程序进行更改。
*/
错误报告(E_ALL&~E_STRICT);
ini_集(“显示错误”,“0”);
ini_集合(“显示_启动_错误”,“0”);
ini_集(“日志错误”,1);
ini设置(“日志错误最大长度”,0);
ini_set(“error_log”,APPLICATION_ROOT.“logs/php_error_log.txt”);
ini_集(“显示错误”,“0”);
ini_集合(“显示_启动_错误”,“0”);
如果(!应用程序_LIVE){
//对开发中的错误处理进行了一些更改。
//我们希望在开发过程中可以看到错误。
ini_集(“显示错误”,“1”);
ini_集合(“显示_启动_错误”,“1”);
ini_集(“html_错误”,“1”);
ini_集合(“docref_根”http://www.php.net/");
ini\u集合(“错误\u前置\u字符串”,
display_errors = On
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(-1);
$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);
display_errors = stdout
error_reporting(~0); ini_set('display_errors', 1);
error_reporting(E_ERROR | E_WARNING | E_PARSE);
<?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

?>
ini_set('display_errors',1);
 error_reporting(E_ALL);
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;
}
sudo tail -50f /var/log/apache2/error.log
<?php
phpinfo();
function shutdown(){
  var_dump(error_get_last());
}

register_shutdown_function('shutdown');
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);