10

Is there a way to make the code continue (not exit) when you get a fatal error in PHP? For example I get a timeout fatal error and I want whenever it happens to skip this task and the continue with others. In this case the script exits.

2
  • If you are running a PHP script which requires say more than 2-4 seconds to execute, then you are doing something majorly wrong. Use another technology or change your workflow. Commented Jul 17, 2009 at 10:32
  • 3
    @Alec Smart I don't agree with that - cron jobs etc regularly take longer than a few seconds. Maybe it would run faster in C++, but then you'd have to hire a C++ programmer... Commented Jul 17, 2009 at 11:12

6 Answers 6

14

There is a hack using output buffering that will let you log certain fatal errors, but there's no way to continue a script after a fatal error occurs - that's what makes it fatal!

If your script is timing out you can use set_time_limit() to give it more time to execute.

Sign up to request clarification or add additional context in comments.

Comments

7

"Fatal Error", as it's name indicates, is Fatal : it stop the execution of the script / program.

If you are using PHP to generate web pages and get a Fatal error related to max_execution_time which, by defaults, equals 30 seconds, you are certainly doing something that really takes too mych time : users won't probably wait for so long to get the page.

If you are using PHP to do some heavy calculations, not in a webpage (but via CLI, or a cron, or stuff like that), you can set another (greater) value for max_execution_time. You have two ways of doing that :

First is to modify php.ini, to set this value (it's already in the file ; just edit the property's value). Problem is it'll modify it also for the web server, which is bad (this is a security measure, after all). Better way is to create a copy of php.ini, called, for instance, phpcli.ini, and modify this file. Then, use it when invoking php :

php -c phpcli.ini myscript.php

This'll work great if you have many properties you need to configure for CLI execution. (Like memory_limit, which often has to be set to a higher value for long-running batches)

The other way is to define a different value for max_execution_time when you invoke php, like this :

php -d max_execution_time=60 myscript.php

This is great if you launch this via the crontab, for instance.

Comments

1

It depends on the exact error type. You can catch errors by creating your own error handler. See the documentation on set_error_handler(), but not all types of errors can be caught. Look at the timeout error you get and see what type it is. If it is one of E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR or E_COMPILE_WARNING then you cannot catch it with an error handler. If it another type then you can. Catch it with the error handler and simply return.

Comments

1

If you have a suitable PHP version (PHP>=5.2 for error_get_last) you can try the technique described here which uses register_shutdown_function and error_get_last.

This won't allow you to "continue" when you get a fatal error, but it at least allows you to log the error (and perhaps send a warning email) before displaying a custom error page to the user.

It works something like this:

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


A few points:

  • you can use ob_clean() to remove any content that was generated prior to the fatal error.
  • it's a really bad idea to do anything to intensive in the shutdown handler, this technique is about graceful failure rather than recovery.
  • whatever you do, don't try to log the error to a database ... what if it was a database timeout that caused the fatal error?
  • for some reason I've had problems getting this technique to work 100% of the time when developing in Windows using WAMP.

Comments

1

The most simple answer I can give you is this function: http://php.net/manual/en/function.pcntl-fork.php

In more detail, what you can do is:

  • Fork the part of the process you think might or might not cause a fatal error (i.e. the bulk of your code)
  • The script that forks the process should be a very simple script.

For example this is something that I would do with a job queue that I have:

<?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;
    }
}

Comments

0

Is there a way then to limit the execution time of an function but not all script? For example

function blabla()
{
return "yes";
}

to make it so that if it is not executed in 25 seconds to return no;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.