抓住致命的例外并继续 [英] Catch a fatal exception and continue

查看:149
本文介绍了抓住致命的例外并继续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,根据其定义,一个致命的例外应该是杀死执行,不应该被抑制,但这里是这个问题。



m运行一个脚本,可以在大约10,000页的数据库中查看,分析和存储数据。这需要几个小时,在极少数情况下(1/1000)中,一个页面无法解析并引发致命异常。



目前,我正在这样做: ($ i = 0; $ i $ $ count; $ i ++)




$ b $ = $ classObjects [$ i];

echo $ i。 :。 memory_get_usage(true)。 \\\
;

$ classDOM = $ scraper-> scrapeClassInfo($ classObject,$ termMap,$ subjectMap);
$ class = $ parser-> parseClassInfo($ classDOM);
$ dbmanager-> storeClassInfo($ class);

unset($ classDOM,$ class,$ classObject);
}

我可以做一些像


$ b $ ($ i = 0; $ i $ $ count; $ i ++)
{
$ classObject = $ classObjects [$ i]; b

  
echo $ i。 :。 memory_get_usage(true)。 \\\
;

try
{
$ classDOM = $ scraper-> scrapeClassInfo($ classObject,$ termMap,$ subjectMap);
$ class = $ parser-> parseClassInfo($ classDOM);
$ dbmanager-> storeClassInfo($ class);
unset($ classDOM,$ class,$ classObject);
}
catch(异常$ e)
{
//记录错误
继续;
}
}

上面的代码不适用于致命异常



是否可以这样做:
如果我将主循环移动到方法,然后调用方法从 register_shutdown_function



像这样:


$ ($ i $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b {
// do stuff here
}
}

register_shutdown_function('shutdown');

函数shutdown()
{
do();
}

这是执行停止时输出的消息:

 致命错误:调用一个非对象的成员函数find()... 

当我使用的方法不能解析页面时,我期待这个上面的消息。我很好,只是跳过那个页面,并转到下一个循环的循环。

解决方案

致命错误是致命的,终止执行。如果发生致命错误,则无法解决此问题。但是,您的错误:


致命错误:调用成员函数find()在...上的非对象


是完全可以预防的。只需添加一个支票来确保你有一个正确对象的实例,如果没有,请处理错误:

  if( $ foo instanceof SomeObject){
$ foo-> find(...);
} else {
//发生错误
}


I know, that by its very definition, a fatal exception is supposed to kill the execution, and should not be suppressed, but here's the issue.

I'm running a script that scrapes, parses and stores in a DB about 10,000 pages. This takes a couple of hours, and in rare cases (1 in 1000) a page fails parsing and throws a fatal exception.

Currently, I'm doing this:

for ($i=0;$i<$count;$i++)   
        {
            $classObject = $classObjects[$i];           

            echo $i . "   :   " . memory_get_usage(true) . "\n";

            $classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);           
            $class = $parser->parseClassInfo($classDOM);                    
            $dbmanager->storeClassInfo($class);         

            unset($classDOM,$class,$classObject);           
        }        

Can I do something like

for ($i=0;$i<$count;$i++)   
{
   $classObject = $classObjects[$i];            
   echo $i . "   :   " . memory_get_usage(true) . "\n";

   try
   {
      $classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);         
      $class = $parser->parseClassInfo($classDOM);                  
      $dbmanager->storeClassInfo($class);           
      unset($classDOM,$class,$classObject);         
    }
    catch (Exception $e)
    {
       //log the error here
       continue;
    }
}

The code above doesn't work for fatal exceptions.

Would it be possible to do something like this: If I moved the main loop into a method, and then call the method from register_shutdown_function ?

Like this:

function do($start)
{
   for($i=$start;$i<$count;$i++)
   {
      //do stuff here
   }
}

register_shutdown_function('shutdown');

function shutdown()
{ 
   do();
}

This is the message that is output when execution stops:

Fatal error:  Call to a member function find() on a non-object in ...

I expect this above message when a page isn't parse-able by the method I am using. I'm fine with just skipping that page and moving on to the next iteration of the loop.

解决方案

Fatal errors are fatal and terminate execution. There is no way around this if a fatal error occurs. However, your error:

Fatal error: Call to a member function find() on a non-object in ...

is entirely preventable. Just add a check to make sure you have an instance of the correct object, and if not, handle the error:

if ($foo instanceof SomeObject) {
    $foo->find(...);
} else {
    // something went wrong
}

这篇关于抓住致命的例外并继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆