在PHP中,错误有轻重之分。严重的错误会中断脚本的继续执行,这是致命的错误,有点像Java中的Error和Exception,但Java中的Error源于JVM错误,无法被coder处理;而轻微的错误不中断脚本的继续执行,但产生一些错误信息(可以设置不显示这些警告信息),这是非致命的错误,有点像Java中的RuntimeException,不强求coder对之处理。
在PHP中,错误与异常是两种不同的东西。错误由系统抛出,也可以由coder手动抛出,并且都可以被coder捕获并处理。与Java等强类型语言不同,PHP不会自动抛出异常,而必须全部由coder手动抛出。异常一旦被抛出就必须有相应的代码对它处理,否则将会造成脚本执行的中断。
ini_set('display_errors', 'On'); ini_set('error_reporting', E_ALL | E_STRICT); try { $foo++; } catch (Exception $e) { echo 'I catch you!';//try catch能捕获异常,而不能捕获错误 } echo 'go on ...';输出:
Notice: Undefined variable: foo in ****** on line 3
go on …
可见对未初始化的$foo进行加法运算会产生E_NOTICE错误,从而输出了一行警告信息。但不影响脚本后续部分的执行。
如果开启了日志功能(log_errors=On),则在php日志文件中可以同样看到:
[03-Sep-2009 14:02:31] PHP Notice: Undefined variable: foo in ****** on line 3
可见对未初始化的$foo进行加法运算会产生E_NOTICE错误,从而输出了一行警告信息。但不影响脚本后续部分的执行。
如果开启了日志功能(log_errors=On),则在php日志文件中可以同样看到:
[03-Sep-2009 14:02:31] PHP Notice: Undefined variable: foo in ****** on line 3
PHP中有哪些错误?
PHP使用常量标记了以下几种常见的错误类型:
E_NOTICE:run-time通知。脚本发现可能有错误发生,但也可能在脚本正常运行时发生。如使用了未定义或未初始化的变量等。
E_WARNING:run-time警告。不暂停脚本执行。如mysql_connect()()连接失败。
E_ERROR:run-time错误,脚本执行被中断。如使用了未定义的class。
E_USER_NOTICE:由coder使用trigger_error(‘error’, E_USER_NOTICE)手动抛出的run-time通知,脚本执行不被中断。
E_USER_WARNING:由coder使用trigger_error(‘error’, E_USER_WARNING)手动抛出的run-time警告,脚本执行不被中断。
E_USER_ERROR:由coder使用trigger_error(‘error’, E_USER_ERROR)手动抛出的run-time错误,脚本执行被中断。
E_PARSE:致命的parse错误。
E_COMPILE_ERROR:致命的compile错误。
E_COMPILE_WARNING:非致命的compile警告,脚本执行不被中断。
E_CORE_ERROR:致命的内核错误。
E_CORE_WARNING:非致命的内核警告,脚本执行不被中断。
如何配置错误报告?
PHP根据错误的类型,用常量标记了不同的错误报告级别,顾名思义地处理相应类型的错误。在配置中合理配置错误报告级别,可以控制哪些类型的错误显示、哪些不显示。
E_ERROR
E_WARNING
E_PARSE
E_NOTICE
E_CORE_ERROR
E_CORE_WARNING
E_COMPILE_ERROR
E_COMPILE_WARNING
E_USER_ERROR
E_USER_WARNING
E_USER_NOTICE
E_ALL:显示所有的警告、通知和错误,但不包括E_STRICT定义的部分。在PHP6.0中,E_STRICT是E_ALL的一部分。
E_STRICT:显示向后兼容性的建议。
E_RECOVERABLE_ERROR:显示可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。
E_NOTICE级别会产生巨大且重复的日志,建议在生产环境中不报告E_NOTICE,而在开发环境中报告E_NOTICE。
最佳实践:
1)、在开发环境中为保持健壮性而配置php.ini为display_errors = On、error_reporting = E_ALL | E_STRICT、log_errors = On;
2)、而在生产环境中为保持安全性而配置php.ini为display_errors = Off、error_reporting = E_ALL & ~E_NOTICE、log_errors = On。
如果你使用的是共享主机而无法修改php.ini,可以使用ini_set()函数进行配置。
您可能感兴趣的文章:
PHP 异常处理相关知识
使用php异常处理类Exception的例子
PHP5 的异常处理、错误的抛出及回调函数等
php中的异常处理、错误的抛出及错误回调函数
一个简单的php自定义异常类
如果php.ini中关闭了错误显示,想开启错误信息提示的话,如下配置:
display_errors =on就好了。
当PHP启动的时候,它将在Web服务器标准头信息中添加PHP版本号信息。
如果希望关闭此功能,可以将expose_php设置为false。这项功能非常有用,例如,可以在Web服务器上屏蔽此信息以防范潜在的黑客攻击。
expose_php = On
不过不显示错误倒安全点,建议调试时打开,然后提供服务时关闭。
相关资料:
display_errors = On
php缺省是打开错误信息显示的,我们把它改为:
display_errors = Off
关闭错误显示后,php函数执行错误的信息将不会再显示给用户,这样能在一定程度上防止攻击者从错误信息得知脚本的物理位置,以及一些其它有用的信息,起码给攻击者的黑箱检测造成一定的障碍。
这些错误信息可能对我们自己有用,可以让它写到指定文件中去,那么修改以下:
log_errors = Off
改为:
log_errors = On
指定文件,找到下面这行:
;error_log = filename
去掉前面的;注释,把filename改为指定文件,如/usr/local/apache/logs/php_error.log
error_log = /usr/local/apache/logs/php_error.log
这样所有的错误都会写到php_error.log文件里。
语法
int error_reporting ( [int level] )
如果参数 level 未指定,当前报错级别将被返回。下面几项是 level 可能的值:
如下表所示:
1 E_ERROR 报告运行时的致命错误
2 E_WARNING 报告运行的非致命错误
4 E_PARSE 报告解析错误
8 E_NOTICE 报告通告,注意,表示所做的事情可能是错误的.
16 E_CORE_ERROR 报告PHP引擎启动失败
32 E_CORE_WARNING 报告PHP引擎启动时非致命错误
64 E_COMPILE_ERROR 报告编译错误
128 E_COMPILE_WARNING 报告编译时出现的非致命错误
256 E_USER_ERROR 报告用户触发的错误
512 E_USER_WARNING 报告用户触发的警告
1024 E_USER_NOTICE 报告用户触发的通告
2047 E_ALL 报告所有的错误和警告
2048 E_STRICT 报告不赞成的用法和不推荐的行为
在php.ini文件中,默认的报告是除了通知之外的所有错误,如下语句设定:
error_reporting = E_ALL & ~ (E_NOTICE)
在上面的表达式中,符号"&"表示几个条件这间的并列,而"~"表示否定,即NOT的含义.
如果想忽略警告信息,可以设定如下语句:
error_reporting = E_ALL & ~(E_NOTICE) & ~(E_WARNING)
在php.ini文件中,和错误有关的设置有如下几个:
(1)error_reporting,设定错误级别
(2)display_errors,是否显示错误报告,设置为ON则打开,设置为OFF则关闭所有错误提示
(3)log_errors,默认设置为OFF,是否记录错误日志;
(4)track_errors,默认设置为OFF,该选项可以帮助解决代码中的错误,而不是让PHP提供其默认的功能。
E_NOTICE 表示一般情形不记录,只有程式有错误情形时才用到,例如企图存取一个不存在的变数,或是呼叫 stat() 函式检视不存在的档案。
E_WARNING 通常都会显示出来,但不会中断程式的执行。这对除错很有效。例如:用有问题的常规表示法呼叫 ereg()。
E_ERROR 通常会显示出来,亦会中断程式执行。意即用这个遮罩无法追查到记忆体配置或其它的错误。
E_PARSE 从语法中剖析错误。
E_CORE_ERROR 类似 E_ERROR,但不包括 PHP 核心造成的错误。
E_CORE_WARNING 类似 E_WARNING,但不包括 PHP 核心错误警告。
PHP 的错误报告
php.ini 文件中有许多配置设置。您应当已经设置好自己的 php.ini 文件并把它放在合适的目录中,就像在 Linux 上安装 PHP 和 Apache 2 的文档说明中所示的那样。在调试 PHP 应用程序时,应当知道两个配置变量。下面是这两个变量及其默认值:
display_errors = Off
error_reporting = E_ALL
通过在 php.ini 文件中搜索它们,可以发现这两个变量当前的默认值。display_errors 变量的目的很明显 —— 它告诉 PHP 是否显示错误。默认值是 Off。但是,要让开发过程更加轻松,请把这个值设为 On:
display_errors = On
error_reporting 变量的默认值是 E_ALL。这个设置会显示从不良编码实践到无害提示到出错的所有信息。E_ALL 对于开发过程来说有点太细,因为它在屏幕上为一些小事(例如变量未初始化)也显示提示,会搞糟浏览器的输出。我只想看到错误和不良编码实践,但是不想看到无害的提示。所以,请用以下值代替 error_reporting 的默认值:
error_reporting = E_ALL & ~E_NOTICE
重新启动 Apache,就全部设置好了。接下来,将学习如何在 Apache 上做同样的事。
服务器上的错误报告
依赖于 Apache 正在做的工作,在 PHP 中打开错误报告可能没法工作,因为在计算机上可能有多个 PHP 版本。有时很难区分 Apache 正在使用哪个 PHP 版本,因为 Apache 只能查看一个 php.ini 文件。不知道 Apache 正在使用哪个 php.ini 文件配置自己是一个安全问题。但是,有一种方法可以在 Apache 中配置 PHP 变量,从而保证设置了正确的出错级别。
而且,最好知道如何在服务器端设置这些配置变量,以否决或抢占 php.ini 文件,从而提供更高级别的安全性。
在配置 Apache 时,应该已经接触过 <apache2-install-dir>/conf/httpd.conf 中 http.conf 文件中的基本配置。
要做在 php.ini 文件中已经做过的事,请把下列各行添加到 httpd.conf,覆盖任何 php.ini 文件:
php_flag display_errors on
php_value error_reporting 2039
这会覆盖在 php.ini 文件中为 display_errors 已经设置的标志,以及 error_reporting 的值。值 2039 代表 E_ALL & ~E_NOTICE。如果愿意采用 E_ALL,请把值设为 2047。同样,还是要重启 Apache。
接下来,要在服务器上测试错误报告。
关于error_reporting()这个函数,它是可以屏蔽到一些错误信息,但是PHP 核心造成的错误,是无法屏蔽的,因为PHP 核心造成的错误会直接导致PHP文件编译失败,因为书写格式没有按照PHP的编码规则写而造成的错误,是无法屏蔽的
* (this must be done before function definitions)
*/
if (defined(’E_STRICT’)) {
$old_error_reporting = error_reporting(0);
if ($old_error_reporting & E_STRICT) {
error_reporting($old_error_reporting ^ E_STRICT);
} else {
error_reporting($old_error_reporting);
}
unset($old_error_reporting);
常见的如下:
// Turn off all error reporting;关闭所有的错误
error_reporting(0);
// Report simple running errors;报告一个简单的运行错误
error_reporting(E_ERROR | E_WARNING | E_PARSE);
// Reporting E_NOTICE can be good too (to report uninitialized
// variables or catch variable name misspellings …);包括报告一些未初始化的变量或捕捉变量名的拼写错误
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
// Report all errors except E_NOTICE
// This is the default value set in php.ini;报告所有的错误但不包括E_NOTICE
error_reporting(E_ALL ^ E_NOTICE);
// Report all PHP errors (bitwise 63 may be used in PHP 3);报告所有的错误
error_reporting(E_ALL);
// Same as error_reporting(E_ALL);同上
ini_set(’error_reporting’, E_ALL);