How do you set max execution time of PHP's CLI component?

How do you set max execution time of PHP's CLI component? I have a CLI script that has gone into a infinite loop and I'm not sure how to kill it without restarting. I used quicksilver to launch it, so I can't press control+c at the command line. I tried running ps -A (show all processes) but php is not showing up in that list, so perhaps it has timed out on it's own - but how do you manually set the time limit?

I tried to find information about where I should set the max_execution_time setting, I'm used to setting this for the version of PHP that runs with apache, but I have no idea where to set it for the version of PHP that lives in /usr/bin.

I did see the follow quote, which does seem to be accurate (see screenshot below), but having an unlimited execution time doesn't seem like a good idea.

Keep in mind that for CLI SAPI max_execution_time is hardcoded to 0. So it seems to be changed by ini_set or set_time_limit but it isn't, actually. The only references I've found to this strange decision are deep in bugtracker (http://bugs.php.net/37306) and in php.ini (comments for 'max_execution_time' directive). (via http://php.net/manual/en/function.set-time-limit.php)

ini_set('max_execution_time') has no effect. I also tried the same thing and go the same result with set_time_limit(7).

Update

So there seem to be three ways to achieve this:

In the script:

set_time_limit(10); // this way
ini_set('max_execution_time', 10); // or this way

Or when calling the script:

php -d max_execution_time=5 script.php

To answer my question about where the php.ini file would be loaded from, that would be from /etc/php.ini if it exists. That file also needs to be readable by the user who is running the php script, so if it was created by root and a user can't "read" it, that means php probably can't "read" it either.

However, it appears that any max_execution_time set in /etc/php.ini actually will not affect the CLI scripts - even if the file is being properly loaded (use phpinfo() to find out) - so you must use one of the other methods mentioned above.

Regarding using a sleep loop to test this, I learned that it won't work.

The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), the sleep() function, database queries, etc. is not included when determining the maximum time that the script has been running

Check out a very similar question asked on Stack Overflow: https://stackoverflow.com/questions/5874950/set-max-execution-time-in-php-cli


Solution 1:

At the top of your PHP code,

ini_set('max_execution_time',300);

or

set_time_limit(300);

Are you sure its going into a loop? If the thread of execution has passed outside of PHP into an extension (or elsewhere) then this will have no effect.

A better solution would be to wrap the script in a watchdog

Solution 2:

In your test script you used sleep(5) to test long running execution time but that is not a valid test.

The docs for max-execution-time say this:

The maximum execution time is not affected by system calls, stream operations etc.

and the docs for set_time_limit() say this:

Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real.

If you avoid the sleep system call, set_time_limit(5); should work fine in CLI scripts. Here's a test script that should exit after 5s:

<?php
set_time_limit(5);

$start = time();
$last = 0;

for ($i=0;$i>=0;$i++) {
    if ($i%10000==0) {
        $took = time()-$start;
        if ($took!=$last) {
            echo "taken {$took} s so far...\n";
            $last=$took;
        }
    }
}
php timeout_test.php 
taken 1 s so far...
taken 2 s so far...
taken 3 s so far...
taken 4 s so far...
taken 5 s so far...
PHP Fatal error:  Maximum execution time of 5 seconds exceeded in /home/tom/MailChap/timeout_test.php on line 8
PHP Stack trace:
PHP   1. {main}() /home/tom/MailChap/timeout_test.php:0