手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆

PHP调用不存在的类时自动创建相应类

首页 > PHP >

在项目中,难免会在项目中调用一个不存在的类(偶尔,偶尔,当这个类的类名是程序生成的时候,偶尔会出现这种情况啦),在new 这个类时,都会直接报fatal错误,然后程序就终止了,怎么办?怎么避免这种情况发生?

注:下面的例子其实是指有autoload的情况下所触发的。如果没有autoload,也就相当于不会触发一个include文件的操作。直接就报FATAL错误了。而如果有autoload,则是报include文件的错误,这个时候才能被捕获,多谢神仙的指正

于是看手册set_error_handler,调用一个callback,处理完后,在这个方法里重新生成一个空类就OK了。看了一下手册上的例子

PHP代码
  1. <?php  
  2. // error handler function  
  3. function myErrorHandler($errno$errstr$errfile$errline)  
  4. {  
  5.     if (!(error_reporting() & $errno)) {  
  6.         // This error code is not included in error_reporting  
  7.         return;  
  8.     }  
  9.   
  10.     switch ($errno) {  
  11.     case E_USER_ERROR:  
  12.         echo "<b>My ERROR</b> [$errno] $errstr<br />\n";  
  13.         echo "  Fatal error on line $errline in file $errfile";  
  14.         echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";  
  15.         echo "Aborting...<br />\n";  
  16.         exit(1);  
  17.         break;  
  18.   
  19.     case E_USER_WARNING:  
  20.         echo "<b>My WARNING</b> [$errno] $errstr<br />\n";  
  21.         break;  
  22.   
  23.     case E_USER_NOTICE:  
  24.         echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";  
  25.         break;  
  26.   
  27.     default:  
  28.         echo "Unknown error type: [$errno] $errstr<br />\n";  
  29.         break;  
  30.     }  
  31.   
  32.     /* Don't execute PHP internal error handler */  
  33.     return true;  
  34. }  

看了一下,结果,发现只有$errstr中才有类名出现,但还是文件名,难道我要用正则?又仔细看了一下手册,发现callback还有一个第五个参数

XML/HTML代码
  1. errcontext  
  2.     The fifth parameter is optional, errcontext, which is an array that points to the active symbol table at the point the error occurred. In other words, errcontext will contain an array of every variable that existed in the scope the error was triggered in. User error handler must not modify error context.   

 

输入第五个参数,原来,这是一个数组,如果我是类的话,里面就有className这个下标数组,直接就是类名了

同时还有一个很重要的问题,如果callback return false的话,会自动调用原来的出错处理。这  其实是影响我们的操作的。

最终代码如下:

PHP代码
  1. set_error_handler(function($errno,$errstr,$errfile,$errline,$clsname){  
  2.     if(isset($clsname['className'])&&$errno == 2&&!class_exists($clsname['className'])){  
  3.         $clsname = $clsname['className'];  
  4.         eval("class ".$clsname ." { static public function model(){return null;} }");  
  5.     }  
  6.     return true;  
  7. },7);  
  8. $result = mmmm::model();  
  9. restore_error_handler();  
  10.  

在最后一行恢复了原来的出错处理,不影响原先程序结构。

 

终于可以直接用了。

 




本站采用创作共享版权协议, 要求署名、非商业和保持一致. 本站欢迎任何非商业应用的转载, 但须注明出自"易栈网-膘叔", 保留原始链接, 此外还必须标注原文标题和链接.

Tags: php, eval

« 上一篇 | 下一篇 »

只显示10条记录相关文章

使用PHP得到所有的HTTP请求头 (浏览: 62788, 评论: 3)
我为什么会选用phpstorm (浏览: 52699, 评论: 5)
快速生成目录树 (浏览: 46847, 评论: 7)
通过file_get_contents来Post数据的实例 (浏览: 46410, 评论: 5)
PHP导入导出Excel方法 (浏览: 45235, 评论: 3)
PHP的XSS攻击过滤函数 (浏览: 42733, 评论: 2)
PHP中Eval的作用 (浏览: 41673, 评论: 4)
超详细:在Mac OS X中配置Apache + PHP + MySQL (浏览: 40396, 评论: 1)
PHP常见错误(二) (浏览: 39797, 评论: 1)
PHP sendmail (浏览: 37986, 评论: 7)

2条记录访客评论


------------
//有点小问题了。原来我在yii框架中是正常的。但我还要再测试在原生的PHP中会怎么样。稍候贴出全部代码
-----------
果然是有问题,这是基于autoload的情况下。
sorry,给各位误导了,因为include不会报fatal error。
是我自己傻了。

Post by gouki on 2012, January 6, 2:39 PM 引用此文发表评论 #1

你确定管用?class 不存在是 fatal error ,根本没机会被处理啊

Post by 神仙 on 2012, January 6, 1:36 PM 引用此文发表评论 #2


发表评论

评论内容 (必填):