Php: Bypass max_execution_time

Very common situation when you have some long-running Php script that exceeds Php’s max_execution_time directive. The easiest way to overcome this limit is to increase it’s value:

In your .php script file:


Or in php.ini file:

max_execution_time=300;300 seconds

Note that in later example this limit will be used for EVERY script.

But the problem is that not always you have access to php.ini file (E.g. when using shared hosting) or overwriting of max_execution_time is not allowed for scripts.

In this case, possible solution is to divide script execution into parts limited by time execution (Like you can limit query results in MySql with help of LIMIT 20, 30 or similar).

I wrote a small class which makes code division a very simple thing.

Example

Say you have some script logging big set of data (E.g. million of records needed to be put into files in special format) into files or something. Take a look at this code:

value('offset', 0);//Retrieve offset value from lib's cache or use 0 as default value for first script call

$r = DB::query('SELECT * FROM `logs` ORDER BY `id` LIMIT '.$offset.' LIMIT 999');

while($row = DB::row($r)) {
    appendToLogFile($row);

    ++$offset;

    $MET->check(//Check for time limit
        'offset',
        $offset,
        function(){
            DB::close();
        }
    );
}

DB::close();

Here we fetch rows from `logs` table and perform some logic with them. After logging each row we check for taken time and if limit is near (You can set count of seconds before max_execution_time value to be used as critical value, see below), MET class performs script reload, calling passed anonymous function before exit.
So, if script found out that reload is needed after 100 rows worked, at second call $offset will get value of 100 (Remember, that 0 is for first call => 100 for 101 row) and will start from 101's row.

Description

MET::check() can be called with arguments:

  • If one or two passed, will call MET::update before check
  • If three passed, third argument must be a callable. Will call MET::update before check and if reload is needed, will call passed callable before exit
$MET->check();//Just reload script if needed
$MET->check('offset', $offset);//Update 'offset' variable with new value and reload script if needed
$MET->check('offset', $offset, 'userFunction');//Update 'offset' variable with new value, if reload is needed: call userFunction (You can pass function name or anonymous function) and reload script

MET::limit is used as count of seconds before max_execution_time value as critical value, e.g. if you set $MET->limit=5 and max_execution_time is equal to 30, script will be reloaded if taken time is 25 or more.

MET::value($key, $default = null) is used to get cached value by its key. If no value is being cached by key, $default will be used as result, you can have as many variables cached as you want. After script reload you can retrieve cached value by key.

$MET->value('level', 5);//Update 'level' variable to 5
$MET->value(array(//Update 'level', 'offset' and 'data' variables with new values
    'level' => 10,
    'offset' => 90,
    'data' => array(
        'user' => 'John',
        'admin' => true,
    )
))

MET::update() updates one or more cached variables. If two arguments passed, first will be used as key and second as value. If one, must be associative array of [key] => [value] pairs. You can set any types of data you want (Integers, strings, arrays etc.)

MET::delete($key) deletes cached variable from cache by key.

$MET->delete('offset');//Delete 'offset' variable from cache

MET::clean() clears cache.

MET::save() makes immidiate save of cached variables to storage (See below).

When you create new MET instance, you can provide storage key as single parameter:


Default storage key is 'MTE_storage'.

Storage

For web mode (When script is being called from Apache, nginx etc. server via web call (When you simply open http://example.com/script.php page)), MET uses $_SESSION as storage.
For CLI mode (When you run script from console, cron task etc.), MET creates cache file in __DIR__ with storage key name for storing cache variables. File will be deleted on MET::clean() call.

When running in CLI mode, MET will check for permission to run self script via global exec method.

Github repository: https://github.com/xf3/met.

You can also include MET library with Composer: "xf3/met"

You are welcome to share, comment and ask questions.

Share Button

Leave a Reply

Your email address will not be published. Required fields are marked *