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

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

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


当前回答

PHP错误处理

有时,您的应用程序不会按预期的方式运行,从而导致错误。有许多原因可能导致错误,例如:

The Web server might run out of disk space A user might have entered an invalid value in a form field The file or database record that you were trying to access may not exist The application might not have permission to write to a file on the disk A service that the application needs to access might be temporarily unavailable These types of errors are known as run-time errors, because they occur at the time the script runs. They are distinct from syntax errors that need to be fixed before the script will run.

专业的应用程序必须能够优雅地处理此类运行时错误。通常,这意味着要更清楚、更准确地告知用户问题。

理解错误级别

通常,当出现阻止脚本正常运行的问题时,PHP引擎会触发一个错误。每个错误都由一个整数值和一个相关常数表示。下表列出了一些常见的错误级别:

PHP引擎在遇到脚本问题时触发错误,但是您也可以自己触发错误,以生成更用户友好的错误消息。这样可以使应用程序更加复杂。下面介绍PHP中处理错误的一些常用方法:

基本错误处理使用die()函数

<?php // Try to open a non-existent file
     $file = fopen("sample.txt", "r");
?>

如果文件不存在,你可能会得到这样的错误: 警告:fopen(sample.txt)[函数。在C:\wamp\www\project\test.php第2行中没有这样的文件或目录

如果我们遵循一些简单的步骤,我们可以防止用户得到这样的错误消息:

<?php
if(file_exists("sample.txt")){
    $file = fopen("sample.txt", "r");
} else{
    die("Error: The file you are trying to access doesn't exist.");
}
?>

现在如果你运行上面的脚本,你会得到这样的错误消息:错误:你试图访问的文件不存在。

正如您所看到的,通过在尝试访问文件之前实现一个简单的检查文件是否存在,我们可以生成一个对用户更有意义的错误消息。

上面使用的die()函数只是显示自定义错误消息,如果没有找到'sample.txt'文件,则终止当前脚本。

创建自定义错误处理程序

您可以创建自己的错误处理函数来处理PHP引擎生成的运行时错误。自定义错误处理程序为您提供了更大的灵活性和对错误的更好控制,它可以检查错误并决定如何处理错误,它可以向用户显示消息,将错误记录在文件或数据库中或通过电子邮件发送,尝试修复问题并继续执行,退出脚本执行或完全忽略错误。

自定义错误处理函数必须能够处理至少两个参数(errno和errstr),但是它可以选择接受额外的三个参数(errfile, errline和errcontext),如下所述:

下面是一个简单的自定义错误处理函数示例。这个处理程序customError()在发生错误时被触发,无论错误多么小。然后,它将错误的详细信息输出到浏览器,并停止脚本的执行。

<?php
// Error handler function
function customError($errno, $errstr){
    echo "<b>Error:</b> [$errno] $errstr";
}
?>

您需要告诉PHP使用您的自定义错误处理函数—只需调用内置的set_error_handler()函数,并传入函数名。

<?php
// Error handler function
function customError($errno, $errstr){
    echo "<b>Error:</b> [$errno] $errstr";
}
 
// Set error handler
set_error_handler("customError");
 
// Trigger error
echo($test);
?>

错误日志

在文本文件中记录错误消息

你也可以在日志文件中记录错误的详细信息,就像这样:

<?php
function calcDivision($dividend, $divisor){
    if($divisor == 0){
        trigger_error("calcDivision(): The divisor cannot be zero", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
function customError($errno, $errstr, $errfile, $errline, $errcontext){
    $message = date("Y-m-d H:i:s - ");
    $message .= "Error: [" . $errno ."], " . "$errstr in $errfile on line $errline, ";
    $message .= "Variables:" . print_r($errcontext, true) . "\r\n";
    
    error_log($message, 3, "logs/app_errors.log");
    die("There was a problem, please try again.");
}
set_error_handler("customError");
echo calcDivision(10, 0);
echo "This will never be printed.";
?>

触发错误

尽管PHP引擎在遇到脚本问题时会触发错误,但是您自己也可以触发错误。这有助于使您的应用程序更加健壮,因为它可以在潜在的问题变成严重错误之前标记出来。

要在你的脚本中触发一个错误,调用trigger_error()函数,传入你想要生成的错误消息:

trigger_error("There was a problem.");

考虑下面的函数,它计算两个数的除法。

<?php
function calcDivision($dividend, $divisor){
    return($dividend / $divisor);
}
 
// Calling the function
echo calcDivision(10, 0);
?>

如果将一个0(0)值作为$除数参数传递,PHP引擎生成的错误将看起来像这样:警告:在C:\wamp\www\project\test.php第3行中除以0

这条消息看起来信息量不大。考虑以下示例,该示例使用trigger_error()函数生成错误。

<?php
function calcDivision($dividend, $divisor){
    if($divisor == 0){
        trigger_error("The divisor cannot be zero", E_USER_WARNING);
        return false;
    } else{
        return($dividend / $divisor);
    }
}
 
// Calling the function
echo calcDivision(10, 0);
?>

现在,脚本在第4行生成以下错误消息:警告:在C:\wamp\www\project\error.php中,除数不能为零

正如您所看到的,与前一个示例相比,第二个示例生成的错误消息更清楚地解释了问题。

参考:https://www.tutorialrepublic.com/php-tutorial/php-error-handling.php

其他回答

对于语法错误,您需要在php.ini中启用错误显示。默认情况下,这些是关闭的,因为您不希望“客户”看到错误消息。查看PHP文档中关于error_reporting和display_errors这两个指令的信息。Display_errors可能是您想要更改的。如果你不能修改php.ini,你也可以在。htaccess文件中添加以下代码:

php_flag  display_errors        on
php_value error_reporting       2039

您可以考虑在您的PHP版本中使用E_ALL的值(如Gumbo所提到的)用于error_reporting以获取所有错误。更多信息

(1)您可以检查错误日志文件,因为它将有所有的错误(除非日志记录已被禁用)。(2)添加以下两行代码将帮助您调试非语法错误:

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

另一种选择是使用编辑器,当你打字时检查错误,如PhpEd。PhpEd还提供了一个调试器,可以提供更详细的信息。(PhpEd调试器与xdebug非常相似,并直接集成到编辑器中,因此您可以使用一个程序来完成所有工作。)

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

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

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

register_shutdown_function('shutdown');

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

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

<?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

?>

使用此代码生成空白页的唯一方法是在关闭处理程序中出现错误时。我复制并粘贴了这个从我自己的cms没有测试,但我相信它工作。

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

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

从而覆盖你的。htaccess设置。

如果你是一个ubuntu用户,那么在你的终端上运行这个命令

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

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