Ограничить время выполнения функции или команды PHP

Привет, есть ли возможность установить ограничение по времени только для команды или только для функции, например:

function doSomething()
{
    //..code here..

    function1();

    //.. some code here..

}

Я хочу установить ограничение по времени только для function1.

Там выходит set_time_limit, но я думаю, что это устанавливает ограничение по времени для всего сценария. У кого-нибудь есть идеи?


person Granit    schedule 24.07.2009    source источник
comment
Что вы хотите, чтобы произошло, если таймер истекает, пока функция1 все еще работает?   -  person tialaramex    schedule 24.07.2009


Ответы (5)


set_time_limit() работает глобально, но его можно сбросить локально.

Установите количество секунд, в течение которых скрипт может выполняться. Если это достигнуто, сценарий возвращает фатальную ошибку. Ограничение по умолчанию составляет 30 секунд или, если оно существует, значение max_execution_time, определенное в файле php.ini.

При вызове set_time_limit() счетчик времени ожидания перезапускается с нуля. Другими словами, если тайм-аут по умолчанию составляет 30 секунд, а через 25 секунд после выполнения скрипта выполняется вызов, такой как set_time_limit(20), скрипт будет работать в общей сложности 45 секунд до истечения времени ожидания.

Я не проверял это, но вы можете установить его локально, сбрасывая, когда вы выходите из

<?php
set_time_limit(0);  // global setting

function doStuff()
{
    set_time_limit(10);   // limit this function
    //  stuff
    set_time_limit(10);   // give ourselves another 10 seconds if we want
    //  stuff
    set_time_limit(0);    // the rest of the file can run forever
}

// ....
sleep(900);
// ....
doStuff();  // only has 10 secs to run
// ....
sleep(900);
// ....

set_time_limit() ... Время, потраченное на действия, происходящие вне выполнения сценария, такие как системные вызовы с использованием system(), потоковые операции, запросы к базе данных и т. д., не учитываются при определении максимального времени выполнения сценария. Это не так в Windows, где измеренное время является реальным.

person Alister Bulman    schedule 24.07.2009
comment
Очень хорошо! спасибо! но он возвращает фатальную ошибку, если критерии времени не были соблюдены. Есть ли способ избежать этого. - person Granit; 24.07.2009
comment
Невозможно остановить фатальную ошибку - таков тайм-аут. Если вы хотите сделать что-то еще, вам придется более полно определить, что вы делаете, и спроектировать систему, которая будет работать так, как требуется. Если вы выполняете запросы к базе данных, которые занимают слишком много времени, я бы попытался улучшить запрос (и базовую базу данных), чтобы ускорить их, а не пытаться исправить что-то вне исходной проблемы. - person Alister Bulman; 24.07.2009
comment
Спасибо, вы помогли мне найти правильную вещь. Я думаю, что я искал max_input_time. Знаете ли вы, возвращает ли он также фатальную ошибку, если крайний срок не соблюден? - person Granit; 24.07.2009
comment
конфигурация php.ini, max_input_time, определяет, сколько времени требуется скрипту для запуска, анализа входных данных, таких как POST, GET и загрузка файлов. Эти задачи должны быть выполнены до того, как будет запущен любой ваш PHP-код. - person Alister Bulman; 24.07.2009
comment
не очень хорошее решение, потому что оно затрагивает глобально все скрипты, так что лучше используйте тайм-ауты! - person Vladimir Ch; 16.10.2020

Вам нужно будет закодировать это самостоятельно, если вы хотите, чтобы function1 возвращался, когда истекает срок.

function doStuff($seconds)
{
    $finish=time()+$seconds;

    $done=false;
    $timeout=false;

    while (!$done && !$timeout)
    {
        //do stuff here, set $done to true if you complete

        //out of time?
        $timeout=time() >= $finish;

    }

    return $done; //let caller know if we completed
}

Конечно, «вещи», которые вы делаете, должны повторяться, чтобы вы могли продолжать проверять прошедшее время и при необходимости выйти.

Если вы хотите, чтобы время выполнения произвольной функции истекло, и вам вернули управление, это не поддерживается. Если вам действительно нужно это сделать, спроектируйте это как отдельный процесс. Затем вы можете закрыть процесс, если он кажется слишком долгим.

person Paul Dixon    schedule 24.07.2009
comment
Спасибо за ответ, но посмотрите на этот сценарий function doStuff($seconds) { $finish=time()+$seconds; $ сделано = ложь; $ тайм-аут = ложь; while (!$done && !$timeout) { //сделайте что-то здесь, установите для $done значение true, если вы закончите //вне времени? $результат = другая функция(); эта функция является стандартной функцией php, которую нельзя изменить, и в моем случае для ее выполнения требуется слишком много времени. $timeout=time() ›= $finish; } вернуть $done; // сообщим вызывающей стороне, если мы завершили } - person Granit; 24.07.2009
comment
Спасибо за ответ, но посмотрите на этот ‹code› сценарий function doStuff($seconds) { $finish=time()+$seconds; $ сделано = ложь; $ тайм-аут = ложь; while (!$done && !$timeout) { //сделайте что-то здесь, установите для $done значение true, если вы закончите //вне времени? $результат = другая функция(); эта функция является стандартной функцией php, которую нельзя изменить, и в моем случае для ее выполнения требуется слишком много времени. $timeout=time() ›= $finish; } вернуть $done; // сообщаем вызывающему абоненту, если мы завершили }‹/code› - person Granit; 24.07.2009
comment
Вы не можете закрыть произвольную функцию через определенное время. Если вам действительно нужно это сделать, спроектируйте это как отдельный процесс. Затем вы можете закрыть процесс, если он кажется слишком долгим. - person Paul Dixon; 24.07.2009
comment
Ну, вы можете сделать это практически на любом другом языке. Еще одна замечательная особенность PHP... - person tex; 16.05.2012
comment
у меня не работал php v7.2.3, если делать что-то здесь занимает слишком много времени, другая часть не срабатывала до тех пор, пока «выполнение» не закончится, все зависло! нерабочее решение( - person Vladimir Ch; 16.10.2020

Нет, это невозможно: max_execution_time используется как мера безопасности, чтобы не допустить, чтобы скрипты с ошибками (например, бесконечный цикл) разрушили сервер; но он не предназначен для работы на основе функциональных единиц.

И тот факт, что это заканчивается фатальной ошибкой, определенно не нравится пользователю...

person Pascal MARTIN    schedule 24.07.2009

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

person Community    schedule 03.08.2009

Я не думаю, что это возможно, но зачем вам это делать? Если сценарий когда-либо прерывается, я, возможно, не хочу, чтобы вы этого хотели. Это должно быть больше похоже на защиту от самого себя (на всякий случай, если вы загружаете бесконечный цикл или что-то, что будет занимать часы), но если ваш скрипт занимает много времени, вы должны либо дать ему время, которое требуется, либо изменить скрипт чтобы он работал быстрее (для некоторых cron это нормально, но если обычный скрипт, который вызывается довольно часто, занимает больше времени, чем ограничение по умолчанию, вы можете столкнуться с серьезными проблемами производительности)

person Flo    schedule 24.07.2009
comment
Допустим, мои сценарии получают данные из базы данных и для каждой строки пытаются что-то сделать с этой строкой, например doSomething(row), но иногда это может занимать слишком много времени. Поэтому мне нужно что-то вроде того, когда это doSomething не будет завершено через 5 минут, чтобы продолжить с другой строкой. Если бы я мог сделать такую ​​функцию: function doSomething() { // код здесь возвращает результаты; } Но если эта функция не может быть завершена за 5 минут, например, вернуть false! - person Granit; 24.07.2009
comment
а, хорошо, в таком случае придерживайтесь ответа Пола Диксона - person Flo; 24.07.2009