Фатальная ошибка php - PullRequest
       29

Фатальная ошибка php

10 голосов
/ 17 июля 2009

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

Ответы [ 6 ]

14 голосов
/ 17 июля 2009

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

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

7 голосов
/ 17 июля 2009

«Фатальная ошибка», как следует из названия, является фатальной: она останавливает выполнение скрипта / программы.

Если вы используете PHP для генерации веб-страниц и получаете фатальную ошибку, связанную с max_execution_time, которая по умолчанию равна 30 секундам, вы, безусловно, делаете то, что действительно занимает слишком много времени: вероятно, не буду ждать так долго, чтобы получить страницу.

Если вы используете PHP для выполнения тяжелых вычислений, не на веб-странице (но через CLI, или cron, или тому подобное) , вы можете установить еще один (больше) значение для max_execution_time. У вас есть два способа сделать это:

Сначала нужно изменить php.ini, чтобы установить это значение (оно уже есть в файле; просто измените значение свойства). Проблема в том, что он изменит его также для веб-сервера, что плохо (это, в конце концов, мера безопасности) . Лучше создать копию файла php.ini, например, phpcli.ini, и изменить этот файл. Затем используйте его при вызове php:

php -c phpcli.ini myscript.php

Это будет прекрасно работать, если у вас есть много свойств, которые необходимо настроить для выполнения CLI. (Как и memory_limit, который часто должен быть установлен на более высокое значение для длительных партий)

Другой способ - определить другое значение для max_execution_time при вызове php, например:

php -d max_execution_time=60 myscript.php

Это замечательно, если вы запустите это, например, через crontab.

1 голос
/ 22 января 2011

Если у вас есть подходящая версия PHP (PHP> = 5.2 для error_get_last), вы можете попробовать метод, описанный здесь , который использует register_shutdown_function и error_get_last.

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

Это работает примерно так:

function fatalErrorHandler()
{
    $lastError = error_get_last();
    if (isset($lastError["type"]) && $lastError["type"]==E_ERROR) {
      // do something with the fatal error
    }
}
...
register_shutdown_function('fatalErrorHandler');


Несколько баллов:

  • вы можете использовать ob_clean () для удаления любого контента, сгенерированного до фатальной ошибки.
  • это действительно плохая идея делать что-то слишком интенсивное в обработчике завершения работы, эта техника скорее изящная ошибка, чем восстановление.
  • что бы вы ни делали, не пытайтесь записать ошибку в базу данных ... что если это был тайм-аут базы данных, вызвавший фатальную ошибку?
  • по некоторым причинам у меня были проблемы с тем, чтобы эта техника работала 100% времени при разработке в Windows с использованием WAMP.
1 голос
/ 17 июля 2009

Это зависит от точного типа ошибки. Вы можете ловить ошибки, создавая собственный обработчик ошибок. См. Документацию по set_error_handler () , но не все типы ошибок могут быть обнаружены. Посмотрите на ошибку тайм-аута, которую вы получаете, и посмотрите, какой это тип. Если это один из E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR или E_COMPILE_WARNING, то вы не можете перехватить его с помощью обработчика ошибок. Если это другой тип, то вы можете. Поймай его с помощью обработчика ошибок и просто верни.

0 голосов
/ 29 февраля 2012

Самый простой ответ, который я могу вам дать - это функция: http://php.net/manual/en/function.pcntl-fork.php

Более подробно, что вы можете сделать:

  • Разделите часть процесса, который, по вашему мнению, может вызвать или не вызвать фатальную ошибку (т. Е. Основную часть вашего кода)
  • Сценарий, который разветвляет процесс, должен быть очень простым.

Например, это то, что я хотел бы сделать с имеющейся у меня очередью заданий:

<?php
// ... load stuff regarding the job queue

while ($job = $queue->getJob()) {
    $pid = pcntl_fork();
    switch ($pid) {
        case -1:
            echo "Fork failed";
            break;
        case 0:
            // do your stuff here
            echo "Child finished working";
            break;
        default:
            echo "Waiting for child...";
            pcntl_wait($status);
            // check the status using other pcntl* functions if you want
            break;
    }
}
0 голосов
/ 17 июля 2009

Есть ли способ ограничить время выполнения функции, но не всего сценария? Например

function blabla()
{
return "yes";
}

сделать так, чтобы, если он не был выполнен в течение 25 секунд, вернуть no;

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