12

Is there a way in PHP to trap the fatal error when the max execution time is reached and give the user a better message?

Cœur
  • 37,241
  • 25
  • 195
  • 267
AdamA
  • 195
  • 2
  • 6

4 Answers4

9

After reading the first two answers here, I had to test register_shutdown_function() myself -- I didn't think it'd run. After all, how can a user function run once there's no more memory, or execution time has elapsed? I was surprised to learn that shutdown functions do run, even in an OOM situation, or when execution time has been exceded. Proof of concept:

To test memory limit:

<?php
function asdf() { echo "omg\n"; }
register_shutdown_function('asdf');

ini_set('memory_limit', '1000');

$x = '';
while(true) {
 $x .= 'lkajsdlfkjasldkfjlaskdfjasldkfj';
}

Output:

PHP Fatal error:  Allowed memory size of 262144 bytes exhausted (tried to allocate 169540 bytes) in /home/scratch.php on line 9
PHP Stack trace:
PHP   1. {main}() /home/scratch.php:0

Fatal error: Allowed memory size of 262144 bytes exhausted (tried to allocate 169540 bytes) in /home/scratch.php on line 9

Call Stack:
    0.0002      81360   1. {main}() /home/scratch.php:0

omg

To test execution time:

cat scratch.php
<?php
function asdf() { echo "omg\n"; }
register_shutdown_function('asdf');

set_time_limit(1);

while(true) {}

Output:

PHP Fatal error:  Maximum execution time of 1 second exceeded in /home/scratch.php on line 7
PHP Stack trace:
PHP   1. {main}() /home/scratch.php:0

Fatal error: Maximum execution time of 1 second exceeded in /home/scratch.php on line 7

Call Stack:
    0.0002      80200   1. {main}() /home/scratch.php:0

omg

Note that, to get your message to display before PHP's error output, you'd have to disable PHP's error output entirely. Which is best practice for a production site anyway.

Frank Farmer
  • 38,246
  • 12
  • 71
  • 89
  • Max execution time reached != Allowed memory exhausted It's hard to make script reach max execution time with loops and sleep functions, sleep freezes execution time counter ... – shfx Apr 20 '10 at 21:38
  • My bad. Editing post to test execution time limit instead of memory exhaustion – Frank Farmer Apr 20 '10 at 22:27
3

My original answer won't work, as you can't catch a fatal error. If you want to read it anyway, check the revision history.

My only guess is that you could use register_shutdown_function. Set a variable at the start of the script, clear it when the script has completed successfully. Write a function that checks that variable and acts on it if it's still set, then apply the function using register_shutdown_function

http://php.net/manual/en/function.register-shutdown-function.php

Adam Hopkinson
  • 28,281
  • 7
  • 65
  • 99
3

Try setting a "Done" flag after the execution of a file and registering a shutdown function that will check if that flag is defined

shfx
  • 1,261
  • 1
  • 11
  • 16
0

If there's no way to trap the error from the API level, the PHP engine should be able to dump the memory on hdd whenever a fatal error occurs, like what Windows does when you see a 'blue screen'.