• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

PHP set_error_handler函数的使用

php 搞代码 4年前 (2022-01-23) 13次浏览 已收录 0个评论

我们写程序,难免会有问题(是经常会遇到问题 ),而PHP遇到错误时,就会给出出错脚本的位置、行数和原因。有很多人说,这并没有什么大不了。确实,在调试程序阶段,这确实是没啥的,而且我认为给出错误路径是必要的。

但泄露了实际路径的后果是不堪设想的,对于某些入侵者,这个信息可是非常重要,而事实上现在有很多的服务器都存在这个问题。有些网管干脆把PHP配置文件中的display_errors设置为Off来解决(貌似我们就是这样做的),但本人认为这个方法过于消极。

有些时候,我们的确需要PHP返回错误的信息以便调试。而且在出错时也可能需要给用户一个交待,甚至导航到另一页面。

那么,有啥解决办法呢?

set_error_handler()

PHP从4.1.0开始提供了自定义错误处理句柄的功能函数set_error_handler(),但很少数脚本编写者知道。set_error_handler这个函数可以很好地防止错误路径泄露,当然还有其它更多的作用。

  1. 可以用来屏蔽错误。 出现错误一来会把一些信息暴漏给用户,极有可能成为黑客攻击你网站的工具。 二来让用户觉得你的水平很挫。
  2. 可以记下错误的信息, 及时发现一些生产环境的出现的问题。
  3. 可以做相应的处理, 出错的时候可以显示跳转到预先定义好的出错页面,提供更好的用户体验。
  4. 可以作为调试工具, 一些时候必须在生产环境调试一些东西, 但又不想影响正在使用的用户。
  5. 。。。。

set_error_handler的使用方法如下:

<span>string</span> set_error_handler ( callback error_handler [, <span>int</span> error_types])

现在我们就用自定义的错误处理把实际路径过滤掉。假设有一个变量$admin,我们是用来判断访问者是否是管理员的(可以通过IP或者登录的用户id来做这个判断)

<span>//</span><span>admin为管理员的身份判定,true为管理员。 </span><span>//</span><span>自定义的错误处理函数一定要有这4个输入变量$errno,$errstr,$errfile,$errline,否则无效。</span><span>function my_error_handler($errno,$errstr,$errfile,$errline) {      </span><span>//</span><span>如果不是管理员就过滤实际路径 </span><span>if</span>(!<span>admin)     {         $errfile</span>=str_replace(getcwd(),<span>""</span><span>,$errfile);         $errstr</span>=str_replace(getcwd(),<span>""</span><span>,$errstr);     }      </span><span>switch</span><span>($errno)     {         </span><span>case</span><span> E_ERROR:           echo </span><span>"</span><span>ERROR: [ID $errno] $errstr (Line: $errline of $errfile) \n</span><span>"</span><span>;         echo </span><span>"</span><span>程序已经停止运行,请联系管理员。</span><span>"</span><span>;         </span><span>//</span><span>遇到Error级错误时退出脚本 </span><span>break</span><span>;         </span><span>case</span><span> E_WARNING:         echo </span><span>"</span><span>WARNING: [ID $errno] $errstr (Line: $errline of $errfile) \n</span><span>"</span><span>;         </span><span>break</span><span>;         </span><span>default</span><span>:         </span><span>//</span><span>不显示Notice级的错误 </span><span>break</span><span>;         } }  </span>

这样就自定义了一个错误处理函数,那么怎么把错误的处理交给这个自定义函数呢?

<span>//</span><span> 应用到类 </span>set_error_handler(array(&$<span>this</span>,<span>"</span><span>appError</span><span>"</span><span>)); </span><span>//</span><span>示例的做法 </span>set_error_handler(<span>"</span><span>my_error_handler</span><span>"</span>);  

so easy,这样,就可以很好地解决安全和调试方便的矛盾了。而且你还可以花点心思,使错误提示更加美观以配合网站的风格。

原作者给出了两点需要注意的地方,我也放出来吧,希望引起广大同胞们的注意:

  1. E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、 E_COMPILE_ERROR、E_COMPILE_WARNING是不会被这个句柄处理的,也就是会用最原始的方式显示出来。不过出现这些错误都是编 译或PHP内核出错,在通常情况下不会发生。
  2. 使用set_error_handler()后,error_reporting ()将会失效。也就是所有的错误(除上述的错误)都会交给自定义的函数处理。

<span>//</span><span>先定义一个函数,也可以定义在其他的文件中,再用require()调用  </span><span>function myErrorHandler($errno, $errstr, $errfile, $errline)  {       </span><span>//</span><span>为了安全起见,不暴露出真实物理路径,下面两行过滤实际路径  </span>    $errfile=str_replace(getcwd(),<span>""</span><span>,$errfile);      $errstr</span>=str_replace(getcwd(),<span>""</span><span>,$errstr);        </span><span>switch</span><span> ($errno) {      </span><span>case</span><span> E_USER_ERROR:         echo </span><span>"</span><span><b>My ERROR</b> [$errno] $errstr<br />\n</span><span>"</span><span>;          echo </span><span>"</span><span>  Fatal error on line $errline in file $errfile</span><span>"</span><span>;          echo </span><span>"</span><span>, PHP </span><span>"</span> . PHP_VERSION . <span>"</span><span> (</span><span>"</span> . PHP_OS . <span>"</span><span>)<br />\n</span><span>"</span><span>;          echo </span><span>"</span><span>Aborting...<br />\n</span><span>"</span><span>;          exit(</span><span>1</span><span>);          </span><span>break</span><span>;        </span><span>case</span><span> E_USER_WARNING:          echo </span><span>"</span><span><b>My WARNING</b> [$errno] $errstr<br />\n</span><span>"</span><span>;          </span><span>break</span><span>;        </span><span>case</span><span> E_USER_NOTICE:          echo </span><span>"</span><span><b>My NOTICE</b> [$errno] $errstr<br />\n</span><span>"</span><span>;          </span><span>break</span><span>;        </span><span>default</span><span>:          echo </span><span>"</span><span>Unknown error type: [$errno] $errstr<br />\n</span><span>"</span><span>;          </span><span>break</span><span>;      }        </span><span>/*</span><span> Don't execute PHP internal error handler </span><span>*/</span><span>return</span><span>true</span><span>;  }    </span><span>//</span><span>下面开始连接MYSQL服务器,我们故意指定MYSQL端口为3333,实际为3306。  </span>$link_id=@mysql_pconnect(<span>"</span><span>localhost:3333</span><span>"</span>,<span>"</span><span>root</span><span>"</span>,<span>"</span><span>password</span><span>"</span><span>);  set_error_handler(myErrorHandler);  </span><span>if</span> (!<span>$link_id) {      trigger_error(</span><span>"</span><span>出错了</span><span>"</span><span>, E_USER_ERROR);  }  </span>

好了,总结一下,下面是 set_error_handler 三种用法:

<span>class</span><span> CallbackClass {     function CallbackFunction() {         </span><span>//</span><span> refers to $this  </span><span>   }       function StaticFunction() {         </span><span>//</span><span> doesn't refer to $this  </span><span>   }  }    function NonClassFunction($errno, $errstr, $errfile, $errline) {  }    </span><span>//</span><span> 三种方法如下:  </span><span>1</span>: set_error_handler(<span>'</span><span>NonClassFunction</span><span>'</span>);  <span>//</span><span> 直接转到一个<div style="color:transparent">本&文来源gaodai^.ma#com搞#代!码网</div><strong>搞gaodaima代码</strong>普通的函数 NonClassFunction  </span><span>2</span>: set_error_handler(array(<span>'</span><span>CallbackClass</span><span>'</span>, <span>'</span><span>StaticFunction</span><span>'</span>)); <span>//</span><span> 转到 CallbackClass 类下的静方法 StaticFunction  </span><span>3</span>: $o =& <span>new</span><span> CallbackClass();      set_error_handler(array($o, </span><span>'</span><span>CallbackFunction</span><span>'</span>));  <span>//</span><span> 转到类的构造函数,其实本质上跟下面的第四条一样。  </span><span>4</span>. $o = <span>new</span><span> CallbackClass();      </span><span>//</span><span> The following may also prove useful:  </span><span>class</span><span> CallbackClass {     function CallbackClass() {         set_error_handler(array(</span>&$<span>this</span>, <span>'</span><span>CallbackFunction</span><span>'</span>)); <span>//</span><span> the & is important  </span><span>   }          function CallbackFunction() {         </span><span>//</span><span> refers to $this  </span><span>   }  }  </span>

以上就介绍了PHP set_error_handler函数的使用,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:PHP set_error_handler函数的使用

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址