定义和用法

set_error_handler() 函数设置用户自定义的错误处理函数。 该函数用于创建运行时期间的用户自己的错误处理方法。 该函数会返回旧的错误处理程序,若失败,则返回 null。

语法

set_error_handler(error_function,error_types)

参数 描述
error_function 必需。规定发生错误时运行的函数。
error_types 可选。规定在哪个错误报告级别会显示用户定义的错误。默认是 "E_ALL"。

提示和注释

提示:如果使用了该函数,会完全绕过标准的 PHP 错误处理函数,如果必要,用户定义的错误处理程序必须终止 (die() ) 脚本。 注意:如果在脚本执行前发生错误,由于在那时自定义程序还没有注册,因此就不会用到这个自定义错误处理程序。

例子

01 <?php
02 //error handler function
03 function customError($errno$errstr$errfile$errline) {
04     echo "<b>Custom error:</b> [$errno] $errstr<br />";
05     echo "Error on line $errline in $errfile<br />";
06     echo "Ending Script";
07     die();
08 }
09  
10 //set error handler
11 set_error_handler("customError");
12  
13 $test=2;
14  
15 //trigger error
16 if ($test > 1) {
17     trigger_error("A custom error has been triggered");
18 }
19 ?>

输出:

1 Custom error: [1024] A custom error has been triggered
2 Error on line 19 in C:webfolder est.php
3 Ending Script

需要注意的是:

set_error_handler("customError") 不仅可以接受函数,还可以接受 类的方法(公开的静态方法 及 公开的非静态方法 都可以),但需要以 数组形式 传递,数组的第一值为“类名”,第二个参数为“方法名”,如下代码所示:

01 <?php
02 class App{
03     //error handler function
04     function customError($errno$errstr$errfile$errline) {
05         echo "<b>Custom error:</b> [$errno] $errstr<br />";
06         echo "Error on line $errline in $errfile<br />";
07         echo "Ending Script";
08         die();
09     }
10 }
11  
12 //set error handler
13 set_error_handler(array("App","customError"));
14  
15 $test=2;
16  
17 //trigger error
18 if ($test > 1) {
19     trigger_error("A custom error has been triggered");
20 }
21 ?>

错误路径泄露

1.漏洞原因: PHP遇到错误时,就会给出出错脚本的位置、行数和原因,例如:

Notice: Use of undefined constant test - assumed ''test'' in D:interpubbigflytest.php on line 3

有很多人说,这并没有什么大不了。但泄露了实际路径的后果是不堪设想的,对于某些入侵者,这个信息可是非常重要,而事实上现在有很多的服务器都存在这个问题。 有些网管干脆把PHP配置文件中的 display_errors 设置为 Off 来解决,但本人认为这个方法过于消极。有些时候,我们的确需要PHP返回错误的信息以便调试。而且在出错时也可能需要给用户一个交待,甚至导航到另一页面。 2.漏洞解决: PHP从4.1.0开始提供了自定义错误处理句柄的功能函数 set_error_handler() ,但很少数脚本编写者知道。在众多的PHP论坛中,我只看见很少一部分对此情况进行了处理。set_error_handler的使用方法如下:

string set_error_handler ( callback error_handler [, int error_types])

现在我们就用自定义的错误处理把实际路径过滤掉。

01 <?php
02 //admin为管理员的身份判定,true为管理员。
03 //自定义的错误处理函数一定要有这4个输入变量$errno,$errstr,$errfile,$errline,否则无效。
04 function my_error_handler($errno$errstr$errfile$errline) {
05     //如果不是管理员就过滤实际路径
06     if (!admin) {
07         $errfile str_replace(getcwd(), ""$errfile);
08         $errstr str_replace(getcwd(), ""$errstr);
09     }
10  
11     switch ($errno) {
12         case E_ERROR:
13             echo "ERROR: [ID $errno] $errstr (Line: $errline of $errfile)";
14             echo "程序已经停止运行,请联系管理员。";
15             //遇到Error级错误时退出脚本
16             exit;
17         break;
18         case E_WARNING:
19             echo "WARNING: [ID $errno] $errstr (Line: $errline of $errfile)";
20         break;
21         default:
22         //不显示Notice级的错误
23         break;
24     }
25 }
26  
27 //把错误处理设置为my_error_handler函数
28 set_error_handler("my_error_handler");
29 ...
30 ?>

这样,就可以很好地解决安全和调试方便的矛盾了。而且你还可以花点心思,使错误提示更加美观以配合网站的风格。不过注意两点是: (1)E_ERROR、 E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不会 被这个句柄处理的,也就是会用最原始的方式显示出来。不过出现这些错误都是编译或PHP内核出错,在通常情况下不会发生。 (2)使用set_error_handler()后,error_reporting ()将会失效。也就是所有的错误(除上述的错误)都会交给自定义的函数处理。 其它有关于set_error_handler()的信息,大家可以参考PHP的官方手册。 下面我举个实际应用中的例子:

<index.php>

01 <?php
02 /**
03  * 先定义一个错误处理函数,也可以定义在其他的文件中,再用require()调用
04  *
05  * @param $errno 错误编号
06  * @param $errstr 错误消息
07  * @param $errfile 错误所在的文件
08  * @param $errline 错误所在的行
09  * @return bool
10  */
11 function myErrorHandler($errno$errstr$errfile$errline) {
12  
13     // 为了安全起见,不暴露出真实物理路径,下面两行过滤实际路径
14     $errfile str_replace(getcwd(), ""$errfile);
15     $errstr str_replace(getcwd(), ""$errstr);
16     switch ($errno) {
17         case E_USER_ERROR:
18             echo "<b>My ERROR</b> [$errno] $errstr<br />";
19             echo "Fatal error on line $errline in file $errfile";
20             echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />";
21             echo "Aborting...<br />";
22             exit(1);
23             break;
24         case E_USER_WARNING:
25             echo "<b>My WARNING</b> [$errno] $errstr<br />";
26             break;
27         case E_USER_NOTICE:
28             echo "<b>My NOTICE</b> [$errno] $errstr<br />";
29             break;
30         default:
31             echo "Unknown error type: [$errno] $errstr<br />";
32             break;
33     }
34  
35     /* Don't execute PHP internal error handler */
36  
37     return true;
38 }
39  
40 // 下面开始连接MYSQL服务器,我们故意指定MYSQL端口为3333,实际为3306。
41 $link_id = @mysql_pconnect("localhost:3333""root""password");
42 set_error_handler(myErrorHandler);
43 if (!$link_id) {
44     trigger_error("出错了", E_USER_ERROR);
45 }
46 ?>

最新文章

  1. jquery实现ajax提交表单信息
  2. PHP代码的执行
  3. 在 Visual Studio 2013 中创建 ASP.NET Web 项目(1):概述 - 创建 Web 应用程序项目
  4. MFC LIST 获取行数和列数
  5. CentOS下搭建使用gitlab 和tortoiseGit使用
  6. 297. Serialize and Deserialize Binary Tree
  7. CodeWars题目筛选
  8. JavaScript中document.cookie
  9. linux svn服务器普通passwd和sasl2配置
  10. Regasm
  11. 由ODI初始化资料档案库(RUC)引起修改ORACLE字符集(ZHS16GBK-AL32UTF8)
  12. 转换简体中文和繁体中文 cconv-0.6.2 for win32 static
  13. [PHP] 算法-两个n位的二进制整数相加问题PHP实现
  14. [01] Collection和Map
  15. 邮件发送-》http://service.mail.qq.com/cgi-bin/help?subtype=1&amp;&amp;id=28&amp;&amp;no=1001256
  16. CentOS7下HTTP并发测试工具Apache Benchmark(AB)安装和使用
  17. QT基础:QMainWindow学习小结
  18. DB索引、索引覆盖、索引优化
  19. 【PAT】1007. 素数对猜想 (20)
  20. Linux服务器通过拷贝的方式安装多个tomcat

热门文章

  1. 2018.7.21NOIP模拟赛?解题报告
  2. T4312 最大出栈顺序
  3. Math.net,.net上的科学计算利器
  4. 算法之A星算法(寻路)
  5. COGS 1743. 忠诚
  6. JS将时间戳转换为刚刚、N分钟前、今天几点几分、昨天几点几分等表示法
  7. Linux environment variables (环境变量)
  8. python之int (整型)
  9. Java垃圾回收之老年代垃圾收集器
  10. laravel 数据导出