РНР: поймать исключение и продолжить выполнение, это возможно?



можно ли поймать исключение и продолжить выполнение скрипта?

688   7  
PHP

7 ответов:

конечно, просто поймать исключение, где вы хотите продолжить выполнение...

  try
  {
      SomeOperation();
  }
  catch (SomeException $e)
  {
      // do nothing... php will ignore and continue    
  }

конечно, это имеет проблему молчаливого отбрасывания того, что может быть очень важной ошибкой. Некоторые операции() могут не сработать, вызывая другие тонкие, трудные для понимания проблемы, но вы никогда не узнаете, если вы молча отбросите исключение.

да, но это зависит от того, что вы хотите выполнить:

например.

try {
   a();
   b();
}
catch(Exception $e){
}

c();

c() всегда будет выполняться. Но если a() выдает исключение, b() - это не выполняется.

только положить вещи в try блок, который зависит друг от друга. Е. Г. b зависит от того, какой результат a нет смысла ставить b после try-catch заблокировать.

обязательно:

try {
   throw new Exception('Something bad');
} catch (Exception $e) {
    // Do nothing
}

возможно, вы захотите прочитать документацию PHP на исключения.

да.

try {
    Somecode();
catch (Exception $e) {
    // handle or ignore exception here. 
}

однако обратите внимание, что php также имеет коды ошибок, отличные от исключений, унаследованных от предыдущих примитивов php с ООП. Большинство встроенных библиотек по-прежнему вызывают коды ошибок, а не исключения. Чтобы игнорировать код ошибки, вызовите функцию с префиксом@:

@myfunction();

старый вопрос, но один у меня был в прошлом, когда я уходил от VBA scipts на php, где вы могли бы нам "перейти", чтобы повторно ввести цикл "по ошибке" с "резюме", и он все еще обрабатывал функцию.
В php, после небольшого проб и ошибок, я теперь использую вложенные try{} catch{} для критических и некритических процессов или даже для взаимозависимых вызовов классов, чтобы я мог проследить свой путь до начала ошибки. например, если функция b зависит от функции a, но функция c является a приятно иметь, но не следует останавливать процесс, и я все еще хочу знать результаты всех 3 независимо, вот что я делаю:

//set up array to capture output of all 3 functions
$resultArr = array(array(), array(), array());

// Loop through the primary array and run the functions 
foreach($x as $key => $val)
{
    try
    {
        $resultArr[$key][0][] = a($key); 
        $resultArr[$key][1][] = b($val);
        try
        { // If successful, output of c() is captured
            $resultArr[$key][2][] = c($key, $val);
        }
        catch(Exception $ex)
        { // If an error, capture why c() failed
            $resultArr[$key][2][] = $ex->getMessage();
        }
    }
    catch(Exception $ex)
    { // If critical functions a() or b() fail, we catch the reason why
        $criticalError = $ex->getMessage();
    }
} 

теперь я могу перебирать массив результатов для каждого ключа и оценивать результаты. Если есть критический отказ для a () или b ().
У меня все еще есть точка отсчета о том, как далеко он добрался до критического сбоя, произошедшего в $resultArr, и если обработчик исключений установлен правильно, я знаю, был ли это a() или b (), который потерпел неудачу.
Если c() не удается, цикл продолжается. Если c() не удалось в разных точках, с немного дополнительной логикой цикла post Я даже могу узнать, работал ли c () или имел ошибку на каждой итерации, опросив $resultArr[$key][2].

другой угол на этом возвращает исключение, не бросая один, из кода обработки.

Мне нужно было сделать это с помощью структуры шаблонов, которую я пишу. Если пользователь пытается получить доступ к свойству, которое не существует в данных, I возвращение ошибка в функции обработки, а не бросать его.

затем, в вызывающем коде, я могу решить, следует ли выбросить эту возвращенную ошибку, вызывая try (), чтобы поймать (), или просто продолжение:

// process the template
    try
    {
        // this function will pass back a value, or a TemplateExecption if invalid
            $result = $this->process($value);

        // if the result is an error, choose what to do with it
            if($result instanceof TemplateExecption)
            {
                if(DEBUGGING == TRUE)
                {
                    throw($result); // throw the original error
                }
                else
                {
                    $result = NULL; // ignore the error
                }
            }
    }

// catch TemplateExceptions
    catch(TemplateException $e)
    {
        // handle template exceptions
    }

// catch normal PHP Exceptions
    catch(Exception $e)
    {
        // handle normal exceptions
    }

// if we get here, $result was valid, or ignored
    return $result;

результатом этого является то, что я все еще получаю контекст исходной ошибки, даже если он был брошен сверху.

другой вариант может заключаться в том, чтобы вернуть пользовательский объект NullObject или объект UnknownProperty и сравнить с ним, прежде чем принимать решение о том, чтобы отключить catch (), но поскольку вы можете повторно выбросить ошибки в любом случае, и если вы полностью контролируете общую структуру, я думаю, что это аккуратный способ обойти проблему невозможности продолжения try/catches.

php > 7

используйте новый интерфейс Throwable

    try {
        // Code that may throw an Exception or Error.
    } catch (Throwable $t) {
        // Handle exception
    }

echo "Script is still running..."; // this script will be executed.

Comments

    Ничего не найдено.