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

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

<?php
  error_reporting(E_ALL | E_STRICT); 

  function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
    // When $errno is a notice, we would like a way for the execution to continue here. Since it is only a notice, eventually it could go back to where the notice was triggered. 
  }

  set_error_handler("exception_error_handler");

  Class TopLevelManagement {
    private $genericInfo = "Very important to add in notices"; 

    function highleveljob() {
      try{
        // In practice, the following statements could occur below in the execution tree, after a few other function calls. 
        $specific = new SpecificAndEncapsulated();
        $specific->specificjob();
      }
      catch (ErrorException $e) {
        $message = $e->getMessage() . $this->genericInfo; 
        mail($admin_email, "Consider the generic info and recover from this situation", $message); 
        // Here we would like the execution to continue where the exception was thrown. In the real world, this would be like "thank you error handler for SpecificAndEncapsulated::specificjob, we have taken care of the issue with the help of our larger perspective.". 
      }   
    } 
  }

  Class SpecificAndEncapsulated {

    function specificjob() {
      // Some processing
      if($unexpected == true) trigger_error('Here is how little I know, as I should', E_USER_NOTICE);
      // Continue as expected after a notice.
    }
  }
?>

Конечно, одно решение состоит в том, чтобы пройти $genericInfo в качестве параметра или в качестве глобальной переменной SpecificAndEncapsulated::justdomyjob и пусть обработчик ошибок позаботится о проблеме, не создавая никаких исключений. Однако это решение не является естественным. Есть и другие способы систематически передавать переменную $genericInfo в SpecificAndEncapsulated, но вопрос будет таким же. Не нужно систематически передавать значение $genericInfo, потому что это не должно беспокоить SpecificAndEncapsulatedдаже когда происходит исключение, даже менее систематически при каждом вызове. Обратное сообщение издателю исключения, говорящему "спасибо, теперь продолжайте", после того, как уведомление было обработано на более высоком уровне, является естественным. Есть ли поддержка для этого типа управления E_NOTICE или E_USER_NOTICE?

2 ответа

Решение

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

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

Вы должны ловить исключения внутри работы, если хотите продолжить работу. Один из жизнеспособных подходов - передать в работу функцию-обработчик ошибок или объект-делегат.

PHP 5 имеет модель исключений, аналогичную модели других языков программирования. Исключение может быть сгенерировано и "поймано" в PHP. Код может быть заключен в блок try, чтобы облегчить отлов потенциальных исключений. Каждая попытка должна иметь хотя бы один соответствующий блок catch. Несколько блоков catch могут использоваться для перехвата различных классов исключений. Нормальное выполнение (когда в блоке try не генерируется исключение или когда отсутствует перехват, соответствующий классу брошенного исключения) будет продолжаться после последнего блока catch, определенного в последовательности. Исключения могут быть выброшены (или переброшены) в блоке catch.

Когда генерируется исключение, код, следующий за оператором, не будет выполнен, и PHP попытается найти первый соответствующий блок catch. Если исключение не перехвачено, PHP-фатальная ошибка будет выдана с сообщением "Uncaught Exception ...", если обработчик не был определен с помощью set_exception_handler().

В PHP 5.5 и более поздних, блок finally также может быть указан после блоков catch. Код в блоке finally всегда будет выполняться после блоков try и catch независимо от того, было ли выброшено исключение, и до возобновления нормального выполнения.

Брошенный объект должен быть экземпляром класса Exception или подклассом Exception. Попытка выбросить объект, который не является, приведет к фатальной ошибке PHP.

Другие вопросы по тегам