Как захватить ошибки компиляции из скрипта включения?

Я хочу включить файл в функцию и используя ob_start(), ob_get_contents()и т. д. сохранить вывод в файл.

Но если есть ошибка во включенном файле, я хочу:

  1. Чтобы моя функция знала это и захватила его (чтобы он мог справиться с этим изящно)

  2. Не выводить ошибку

Будет set_error_handler разрешить это?

1 ответ

Для (большинства) не смертельных, да, set_error_handler можете поймать тех, и вы можете обращаться с ними изящно.

Для фатальных ошибок взгляните на ответ на этот вопрос: PHP: Пользовательский обработчик ошибок - обработка разбора и фатальных ошибок

Теперь, если вы заинтересованы в предотвращении простых ошибок разбора, вы можете использовать runkit_lint_file расширения runkit, если вы можете установить расширения для вашей установки PHP. [Дополнение к редактированию: то есть, скопируйте файл перед его включением. Ошибки разбора не подлежат восстановлению. Это также можно сделать, запустив php в командной строке с параметром -l. Хотя в зависимости от того, как настроен ваш хост, вам может потребоваться изменить среду для работы опции php командной строки.]

Вот пример с командной строкой php, но я не уверен, что это хороший пример. Разорвано с одного из моих проектов с некоторыми добавленными комментариями.

/**
 * Lint and and retrieve the result of a file. (If lint is possible)
 * @param $file
 * @return Mixed bool false on error, string on success.
 */
function lint_and_include ($file) {
   if(is_readable($file)) {
      //Unset everything except PATH.
      //I do this to prevent CGI execution if we call
      //a CGI version of PHP.
      //Someone tell me if this is overkill please.
      foreach($_ENV as $key=>$value)
      {
         if($key == "PATH") { continue; }
         putenv($key);
      }
      $sfile = escapeshellarg($file);
      $output = $ret = NULL;
      //You could modify this to call mandatory includes to 
      //also catch stuff like redefined functions and the like.
      //As it is here, it'll only catch syntax errors.
      //You might also want to point it to the CLI php executable.
      exec("php -l $sfile", $output, $return);
      if($return == 0) {
         //Lint Okay
         ob_start();
         include $file;
         return ob_get_clean();
      }
      else {
         return false;
      }
   }
   else {
      return false;
   }
}

Дополнительные примечания: в этом случае ваш set_error_handler callback должен регистрировать ошибки, которые он может где-то перехватить, вместо того, чтобы выводить их Если какой-либо из включенного кода может выдавать исключения, вы можете также перехватить их с помощью блока try-catch.

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