time limit test

Как увеличить время выполнения PHP-скрипта?

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

Чтобы вы понимали, о чем идет речь, приведу небольшой пример. При выходе за выставленные рамки времени вы можете получить следующего рода ошибку:

 Fatal error: Maximum execution time of 30 seconds exceeded in pandoge_com.php on line 19

Я расскажу о 4-х способах, как избавиться от нее.

Но стоить начать с того, что в каждом отдельном случае все перечисленные способы могут не работать, так как некоторые хостинг-провайдеры запрещают самим изменять этот параметр.

Увеличение времени выполнения PHP-скрипта через конфигурационный файл php.ini

В качестве первого способа для увеличения времени выполнения скрипта мы будем использовать файл конфигурации php.ini.

Для того чтобы точно узнать, где находится этот файл, прочитайте эту статью.

Открываете его удобным для вас способом и в самый низ вставляете:

Где «300» означает 300 секунд (меняете на свое). Этот файл, к сожалению, не на всех хостингах доступен пользователям для редактирования.

Увеличение времени выполнения PHP-скрипта через встроенную функцию «ini_set»

Второй способ основывается на использовании функции «ini_set». Ее вы вставляете непосредственно в сам файл скрипта, желательно в самый верх. Пример:

Здесь значение «300» вы также сменяете на нужное вам в секундах. Обратите внимание, что при использовании PHP в безопасном режиме эта функция будет недоступна.

Читайте также:  text-align

Увеличение времени выполнения PHP-скрипта через встроенную функцию «set_time_limit»

Третий способ, наверное, один из самых популярных – использование функции «set_time_limit» для изменения времени выполнения скрипта. Также используется непосредственно в самом файле PHP. Пример:

Здесь «300» вы также изменяете на нужное вам значение. Вставлять код желательно в самом верху.

Увеличение времени выполнения PHP-скрипта через файл .htaccess

Последний вариант заключается в редактировании файла .htaccess, который находится в корне вашего сайта (если таковой отсутствует – создайте его).

В самый верх этого файла вставьте:

 php_value max_execution_time 300

Значение «300» вы также меняете на свое.

Обратите внимание, что во всех случаях время выполнения скрипта указывается в секундах. Помимо этого, значение параметра во всех способах может принимать «0», что означает неограниченное время выполнения.

Как узнать, сколько времени отведено на выполнение PHP-скрипта?

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

Для этого создайте PHP-файл в корне вашего сайта, где выведите значение установленного времени:

Если время равняется тому, что вы указали – поздравляем вас, вы достигли желаемой цели. В противном же случае прочитайте статью еще раз, напишите в комментариях о вашей проблеме или направьте ее вашему хостинг-провайдеру.

Источник

Запуск долгих скриптов на php

Универсальная галерея - модуль для битрикс

Хотя запуск долгих скриптов на php (от 5 мин и более) по разным причинам обычно считается нежелательным, в некоторых ситуациях это может выручить. Простой пример: при xml-импорте инфоблока в битриксе с 500 свойствами и 10000 элементами, стандартного максимального времени выполнения может быть недостаточно — хотя скрипт и выполняется по шагам, но может, например, зависнуть, на создании вспомогательных индексов.

Показать скрытое содержимое
В данной статье рассмотрим запуск долгих php скриптов на apache+nginx и рассмотрим также ограничения браузеров.

Читайте также:  What is console log in php

Самое первое, что необходимо проверить — это настройки php «max_execution_time» и «session.gc_maxlifetime» (максимальное время выполнения скрипта и время сессии соответственно). Ее можно установить из htaccess (параметры устанавливаются в секундах):

 php_value max_execution_time 2400 
php_value session
.gc_maxlifetime 2400
 set_time_limit(2400); 
ini_set('session.gc_maxlifetime', 2400);

Однако, даже если установить большое значение max_execution_time, при установленном nginx, если время еще не истекло, вы можете получить сообщение об ошибке подобное этому:

504 Gateway Timeout error using Nginx

Данную ситуацию можно исправить, отредактировав файл конфигурации nginx (на системах Debian находится здесь — /etc/nginx/nginx.conf):

 proxy_connect_timeout 2400; 
proxy_send_timeout 2400;
proxy_read_timeout 2400;

Но и это еще не все. У браузеров также есть свои ограничения по времени на получение страниц и у разных браузеров они отличаются. Но это также поправимо, и проще всего эта настройка меняется в браузере Mozilla Firefox: нужно зайти в расширенные настройки введя в адресной строке «about:config», затем найти по поиску значение «network.http.connection-timeout», в котором, как и везде, можно установить значение максимального времени получения страницы в секундах.

Скрипты тестирования максимального времени выполнения скрипта

Для тестирования описанных мной настроек, я приведу здесь два скрипта — простой запуск страницы и получение с использованием ajax (это может быть важно, т.к. настройки браузера могут отличаться для получения простых страниц и средствами XHR).

  
$ts_start = time();

$cur_sec = 0;

while(
true) <

$seconds = time() - $ts_start;

if(
$seconds%20==0 && $cur_sec!=$seconds) <
echo
$seconds."
"
;
$cur_sec = $seconds;
>

if(
$seconds>=2350)
break;

>

  


Start ajax test



Источник

Как на PHP выполнить долгий скрипт?

riky

у вас проблема не со временем, а в том что память заканчивается, или memory limit поднимайте или оптимизируйте алгоритм.
очень подозрительный код, если это консоль, то зачем там ob_* функции и flush ?
данные не нужно накапливать в памяти сохраняйте обработанные данные сразу в базу или файлы

увеличивая memory limit объем данных обработанных так же увеличивается.
ob_* и flush использую для записи данных в файл (не знаю на сколько это правильно).
memory limit был указа 256M изменил на 512M ошибка та же вылетает

riky

Алексей: «ob_* и flush использую для записи данных в файл»
вы меня расстраиваете, не делайте так.
file_put_contents + FILE_APPEND всегда хватает, или fopen на крайняк, а так делать очень плохо.
либо увеличивайте мемори лимит еще сильнее (4гига например), если не доходит что вы делаете плохо и все таки хотите познать жизнь через боль.

Юрий: У меня стоит задача по битриксу т.е.

$crmContact = new CAllCrmContact(false); $dbResult = $crmContact->GetList( array('ID' => 'DESC'), array('CHECK_PERMISSIONS' => 'N'), array('ID', 'NAME', 'LAST_NAME', 'FULL_NAME', 'DATE_CREATE', 'ASSIGNED_BY_ID') ); while ($contact = $dbResult->GetNext()) < // здесь вносятся изменения в бд и сохранаются логи в файл // при увеличении памяти (memory limit) до 4G обрабатывается только 70т // после выдается ошибка >

riky

Алексей: 1) я надеюсь в логи вы начали писать file_put_contents с флагом FILE_APPEND то есть строку не накапливаете.
2) если вы говоорите что данные хоть как то обрабатываются значит crmContact->GetList загружает их полностью (иначе я бы предложил загружать эти записи по частям например по 1000 обрабатывать и загружать следующее), а проблема возникает уже в месте «здесь вносятся изменения в бд и сохранаются логи в файл» нужно смотреть этот код на предмет того где он потребляет столько памяти.
под подозрением строки типа
$str .= ‘ololo’;
$arr[] = ‘new item’;
то есть где вы потребляете память строками или новыми элементами массива.

Юрий: когда начал использовать file_put_contents то объем выполнения увеличился, но ошибка все же выполняется.
У меня в начале при каждом новом цикле обнуляются переменные. Может это как то повлиять?

riky

Алексей: если обнуляются, то не должны влиять.
по нормальному надо брать xdebug и по шагам смотреть где память теряется.
в вашем случая я бы просто порекомендовал старый добрый метод «исключения». убираете часть кода/запускаете и смотрите выполняется ли до конца. если нет — убираете еще кусок. если выполняется значит потихоньку добавляете код, пока не дойдете до места которое сьедает память.

Как я понял у вас проблема не во времени выполнения скрипта, а в количестве памяти, которое ему требуется. Попробуйте увеличить memory_limit в php.ini или оптимизируйте скрипт, снизив количество данных, которое ему требуется хранить — запускать скрипт несколько раз с сохранением состояния, на котором он остановился (к примеру используя флаги в tmp файле)

При запуске скрипта проверяете наличие tmp-файла — есть — достаете значение текущей итерации с записью в переменную $iterationFrom. Далее при запуске логики работы скрипта используете не foreach, а for ($i = $iterationFrom; $i < count($items); $i++), внутри цикла if ($i - $iterationFrom >= $maxIterationCount), которые выполняет break for цикла и запись $iterationFrom в tmp-файл. Не могу целый ответ написать, дико неудобно через комментарий

Николай Конюхов: а в данном случае while не подойдет?

$crmContact = new CAllCrmContact(false); $dbResult = $crmContact->GetList( array('ID' => 'DESC'), array('CHECK_PERMISSIONS' => 'N'), array('ID', 'NAME', 'LAST_NAME', 'FULL_NAME', 'DATE_CREATE', 'ASSIGNED_BY_ID') ); while ($contact = $dbResult->GetNext()) < // здесь вносятся изменения в бд и сохранаются логи в файл // при увеличении памяти (memory limit) до 4G обрабатывается только 70т // после выдается ошибка >

Алексей: Суть в том, чтобы прервать выполнение скрипта до получения ошибки о переполнении памяти с сохранением состояния на котором он остановился. Я себе вашу задачу представляю так — делается крон правило с выполнением каждые 5 минут. При этом данные нужно обновлять только каждый день. При запуске скрипт проверяет наличие tmp-файла с текущей позицией запуска: 1) Файла нет — запускаем, к примеру, через require выполнение основного скрипта обработки. 2) Файл есть — достаем данные из файла — там может быть указатель позиции, на которой скрипт остановился или флаг успешного выполнения (-1, к примеру) — если там -1 — проверяем mktime файла — если данные успешно обработаны сегодня — ничего не делаем, если разница с текущем временем > суток — удаляем файл и начинаем выполнять основной скрипт обработки .

// cron_wrapper.php define(POS_END, -1); define(FRESHNESS_TIME, 86400); // сутки function start_update($position, $flagFile) < $crmContact = new CAllCrmContact(false); $contactsRoundCount = 20000; $dbResult = $crmContact->GetList( array('ID' => 'DESC'), array('CHECK_PERMISSIONS' => 'N'), array('ID', 'NAME', 'LAST_NAME', 'FULL_NAME', 'DATE_CREATE', 'ASSIGNED_BY_ID') // добавить LIMIT => $position, $contactsRoundCount ); $i = 0; while ($contact = $dbResult->GetNext()) < // здесь вносятся изменения в бд и сохранаются логи в файл $i++; if ($contactsRoundCount > // если вышли из while до достижения $contactsRoundCount значит данные для обновлений закончились if ($i > $flagFile = 'current.pos'; if (file_exists($flagFile)) < $currentPos = file_get_contents($flagFile); if ($currentPos == POS_END) < if (time() - filemtime($flagFile) >FRESHNESS_TIME) < $currentPos = 0; unlink($flagFile); >else < die("Nothing to update"); >> > start_update($currentPos, $flagFile);

Источник

Оцените статью