ограничить время выполнения скрипта php
Как увеличить память и время для PHP скриптов
Настройки потребления ресурсов в PHP скриптах можно установить в главном конфигурационном файле php.ini, а также в самих скриптах.
В файле php.ini за это отвечают директивы из раздела Resource Limits (ограничение потребления ресурсов).
Как увеличить память для PHP скриптов
Для этого в файле php.ini найдите и отредактируйте директиву:
Эта директива задаёт максимальное время в секундах, в течение которого скрипт должен полностью загрузиться. Если этого не происходит, парсер завершает работу скрипта. Этот механизм помогает предотвратить зависание сервера из-за плохо написанного скрипта. По умолчанию на загрузку даётся 30 секунд. Если PHP запущен из командной строки, это значение по умолчанию равно 0.
На максимальное время выполнения не влияют системные вызовы, потоковые операции и т.п.
При работе в безопасном режиме эту настройку нельзя изменить функцией ini_set(). Если значение все же нужно изменить, надо либо выключить безопасный режим, либо изменить значение прямо в php.ini.
Веб-серверы обычно имеют свои настройки тайм-аута, по истечении которого сами завершают выполнение скрипта PHP. В Apache есть директива Timeout, в IIS есть функция CGI timeout. В обоих случаях по умолчанию установлено 300 секунд. Точные значения можно узнать из документации к веб-серверу.
Функция для увеличения и ограничения времени выполнения PHP
Функция set_time_limit ограничивает время выполнения скрипта.
Она задает время в секундах, в течение которого скрипт должен завершить работу. Если скрипт не успевает, вызывается фатальная ошибка. По умолчанию дается 30 секунд, либо время, записанное в настройке max_execution_time в php.ini (если такая настройка установлена).
При вызове set_time_limit() перезапускает счетчик с нуля. Другими словами, если тайм-аут изначально был 30 секунд, и через 25 секунд после запуска скрипта будет вызвана функция set_time_limit(20), то скрипт будет работать максимум 45 секунд.
Возвращаемые значения: возвращает TRUE в случае успеха, иначе FALSE.
Внимание: эта функция не работает, если PHP работает в безопасном режиме. Обойти это ограничение можно только выключив безопасный режим или изменив значение настройки в php.ini.
Замечание: функция set_time_limit() и директива max_execution_time влияют на время выполнения только самого скрипта. Время, затраченное на различные действия вне скрипта, такие как системные вызовы функции system(), потоковые операции, запросы к базам данных и т.п. не включаются в расчет времени выполнения скрипта. Это не относится к системам Windows, где расчитывается абсолютное время выполнения.
Обе set_time_limit(…) и ini_set(‘max_execution_time’,…); не учитывают время, потраченное функциями sleep, file_get_contents, shell_exec, mysql_query и некоторыми другими.
Увеличение выделенной памяти для PHP скриптов
Директива в файле php.ini
задаёт максимальный объем памяти в байтах, который разрешается использовать скрипту. Это помогает предотвратить ситуацию, при которой плохо написанный скрипт съедает всю доступную память сервера. Для того, чтобы убрать ограничения, установите значение этой директивы в -1.
В версиях до PHP 5.2.1 для использования этой директивы, она должна была быть указана на этапе компиляции. Так, ваша строка конфигурации должна была включать: —enable-memory-limit. Эта опция компиляции была также необходима для использования функций memory_get_usage() и memory_get_peak_usage() до версии 5.2.1.
Если используется целое число, то значение измеряется байтами. Вы также можете использовать сокращённую запись.
Доступные опции: K (для килобайт), M (для мегабайт) и G (для гигабайт; доступна начиная с PHP 5.1.0); они регистронезависимы. Все остальное считается байтами. 1M равно одному мегабайту или 1048576 байтам. 1K равно одному килобайту или 1024 байтам. Эти сокращения вы можете использовать в php.ini и в функции ini_set(). Обратите внимание, что числовое значение приводится к типу integer; например, 0.5M интерпретируется как 0.
Увеличение времени парсинга данных из запроса.
Директива в файле php.ini
задаёт максимальное время в секундах, в течение которого скрипт должен разобрать все входные данные, переданные запросами вроде POST или GET. Это время измеряется от момента, когда PHP вызван на сервере до момента, когда скрипт начинает выполняться. Значение по умолчанию -1, что означает, что будет использоваться max_execution_time. Если установить равным 0, то ограничений по времени не будет.
При запуске в командной строке значение директивы установлено на -1 (неограниченно).
Увеличение глубины вложенности входных переменных
Директива в файле php.ini
Ограничение на количество входных переменных
Директива в файле php.ini
Внимание: после внесения изменений в файл php.ini необходимо перезагрузить веб-сервер, чтобы изменения вступили в силу.
Проверка использование ресурсов
Функция getrusage получает информацию об использовании текущего ресурса.
Возвращаемые значения: возвращает ассоциативный массив, содержащий данные возвращённые из системного вызова. Имена элементов соответствуют документированным именам полей.
Пример использования getrusage():
Увеличение разрешённого размера файлов для загрузки на сервер
Кроме описанных ограничений на потребление непосредственных ресурсов веб-сервера, также имеются ограничения, которые оказывают косвенное воздействие на ресурсы: например, загрузка слишком большого файла на сервер может потребовать большого количества ресурсов для его обработки, либо привести к переполнению дискового хранилища сервера. Поэтому существуют дополнительные лимиты, включённые в другие разделы конфигурационного файла помимо Resource Limits.
В частности, директива
устанавливает максимальный размер закачиваемого файла.
Если используется целое число, значение измеряется байтами. Вы также можете использовать сокращённую запись, которая описана чуть выше.
Максимально допустимый размер данных, отправляемых методом POST
Методом пост могут отправляться как текстовые данные (например, при отправке комментария на сайт), так и файлы. Если вы увеличили значение upload_max_filesize чтобы иметь возможность загружать файлы большего размера на сайт, то также нужно увеличить и значение директивы:
которая устанавливает максимально допустимый размер данных, отправляемых методом POST. Это значение также влияет на загрузку файлов. Для загрузки больших файлов это значение должно быть больше значения директивы upload_max_filesize. В сущности, memory_limit должна быть больше чем post_max_size. Если используется integer, значение измеряется байтами. Вы также можете использовать сокращённую запись, которая описана выше. Если размер POST-данных больше чем post_max_size, суперглобальные переменные $_POST и $_FILES будут пустыми. Это можно отследить различными способами, например передав $_GET переменную в скрипт, обрабатывающий данные, т.е.
Проблемы «долгих» скриптов PHP
Внешний таймаут
В первую очередь нужно установить подходящее значение параметра max_execution_time в конфиге PHP.
Веб-сервер может также проксировать запросы на другой веб-сервер, который и запустит PHP скрипт (не редкий пример, nginx — фронтенд, apache — бэкэнд). В этом случае на проксирующем веб-сервере необходимо также настраивать таймаут проксирования. Для apache ProxyTimeout, для nginx proxy_read_timeout.
Прерывание пользователем
Если скрипт запускается в ответ на HTTP-запрос, то пользователь может остановить выполнение запроса в своем браузере, в этом случае прекратит свою работу и PHP скрипт. Если же требуется, чтобы скрипт продолжил свою работу даже после остановки запроса, установите в TRUE параметр ignore_user_abort в конфиге PHP.
Потеря открытых соединений
В таких случаях следует в первую очередь попробовать увеличить таймаут соединения. Например, для MySQL можно выполнить запрос (спасибо Snowly)
Параллельный запуск
В таких случаях можно использовать блокировку используемых ресурсов, но эта задача всегда решается индивидуально. Либо можно просто проверять, не запущена ли другая копия этого скрипта, и либо подождать завершения его работы, либо завершить текущий запуск. Для этого можно просматривать список запущенных процессов, либо использовать блокировку запуска самого скрипта, что то вроде:
Нагрузка на веб-сервер
В случаях, когда долгие скрипты запускаются через веб-сервер, соединение клиента с этим самым веб-сервером остается открытым до тех пор, пока не отработает скрипт. Это не есть хорошо, т.к. задача веб-сервера как можно быстрее обработать запрос и отдать результат. Если же соединение остается висеть, то один из воркеров (процессов) веб-сервера на долгое время будет занят. А если одновременно будет запущено достаточно много таких скриптов, то они могут занять все (ну или почти все) свободные воркеры (для apache см. MaxClients), и веб-сервер просто не сможет обрабатывать другие запросы.
Поэтому следует при обработке запроса пользователя, запускать скрипт в фоновом режиме через php-cli, чтобы не нагружать веб-сервер, а пользователю отвечать что его запрос обрабатывается. При необходимости можно периодически проверять состояние обработки при помощи AJAX запросов.
Вот, пожалуй, и все что я могу рассказать по этой теме. Надеюсь, для кого-то будет полезным.
Ограничить время выполнения функции или команды PHP
Привет есть возможность установить ограничение по времени только для команды или только для функции, например:
Я хочу установить ограничение по времени только для function1.
там выходит set_time_limit, но я думаю, что это устанавливает ограничение по времени для всего скрипта. Кто-нибудь какие-нибудь идеи?
6 ответов
set_time_limit() не глобально, но его можно восстановить локально.
задайте количество секунд, в течение которых скрипт может выполняться. Если это достигнуто, скрипт возвращает фатальную ошибку. Ограничение по умолчанию-30 секунд или существует значение max_execution_time, определенное в php.ini.
при вызове set_time_limit( ) перезапускает счетчик тайм-аута с нуля. В другими словами, если таймаут по умолчанию 30 секунд, а 25 секунд в сценарий выполнение такой вызов set_time_limit(20) сценария будет работать в общей сложности 45 секунд до тайм-аута.
Я не тестировал его, но вы можете установить его локально, сбросив, когда вы оставите
вам нужно будет кодировать это самостоятельно, если вы хотите, чтобы function1 возвращался, когда истечет срок.
конечно, «материал», который вы делаете, должен быть итеративным, чтобы вы могли продолжать проверять свое истекшее время и при необходимости уходить.
Если вы хотите выполнить тайм-аут произвольной функции и вернуть вам управление, это не поддерживается. Если вам действительно нужно это сделать, спроектируйте его как отдельный процесс. Затем вы можете закрыть процесс, если он кажется, слишком долго.
Ограничить время выполнения скрипта php
Имя | По умолчанию | Место изменения | Список изменений |
---|---|---|---|
assert.active | «1» | PHP_INI_ALL | |
assert.bail | «0» | PHP_INI_ALL | |
assert.warning | «1» | PHP_INI_ALL | |
assert.callback | NULL | PHP_INI_ALL | |
assert.quiet_eval | «0» | PHP_INI_ALL | |
assert.exception | «0» | PHP_INI_ALL | Доступна с версии PHP 7.0.0. |
enable_dl | «1» | PHP_INI_SYSTEM | Эта возможность устарела и будет обязательно удалена в будущем. |
max_execution_time | «30» | PHP_INI_ALL | |
max_input_time | «-1» | PHP_INI_PERDIR | |
max_input_nesting_level | «64» | PHP_INI_PERDIR | Доступна с PHP 5.2.3. |
max_input_vars | 1000 | PHP_INI_PERDIR | Доступна с PHP 5.3.9. |
magic_quotes_gpc | «1» | PHP_INI_PERDIR | Удалена в PHP 5.4.0. |
magic_quotes_runtime | «0» | PHP_INI_ALL | Удалена в PHP 5.4.0. |
zend.enable_gc | «1» | PHP_INI_ALL | Доступна с PHP 5.3.0. |
Для подробного описания констант PHP_INI_*, обратитесь к разделу Где могут быть установлены параметры конфигурации.
Краткое разъяснение конфигурационных директив.
Завершение работы скрипта при провале проверки утверждений.
Вызов предупреждений PHP для каждой проваленной проверки утверждения.
Пользовательская функция, вызываемая при провале проверки утверждений.
Используйте эту настройку функции error_reporting() во время выполнения проверки утверждений. При включении настройки сообщения об ошибках во время проверки утверждений показываться не будут (неявный вызов error_reporting(0)). Если настройка выключена, ошибки будут выдаваться в соответствии с настройками error_reporting()
Генерирует исключение AssertionError для неудачной проверки утверждения.
Главной причиной, по которой требуется выключение динамической загрузки, является безопасность. С помощью динамической загрузки можно обойти все open_basedir ограничения. По умолчанию динамическая загрузка разрешена.
Данная возможность была объявлена УСТАРЕВШЕЙ, начиная с PHP 5.3.0 и была УДАЛЕНА в PHP 5.4.0.
Задаёт режим magic_quotes для GPC (Get/Post/Cookie) операций. Если magic_quotes включён, все ‘ (одинарные кавычки), » (двойные кавычки), \ (обратный слеш) и NUL автоматически экранируются обратным слешем.
Данная возможность была объявлена УСТАРЕВШЕЙ, начиная с PHP 5.3.0 и была УДАЛЕНА в PHP 5.4.0.
Включает или отключает сборщик циклических ссылок.
Установить максимальное время выполнения в PHP в CLI
Я знаю, что php CLI обычно используется из-за ограничений по времени и первичных, потому что он не использует потоки/процессы Apache.
но есть ли способ явно установить max_execution_time для некоторых скриптов, которые я не хочу иметь свободу «неограниченного времени» и просто хочу держать этот скрипт под контролем?
Если вы думаете, что на этот вопрос можно лучше ответить на superuser.com и получить разрешение на перемещение, сделать это. 🙂
редактировать: Я немного погуглил и нашел правильный параметр:
4 ответов
на документация говорит, что при запуске в режиме командной строки, по умолчанию стоит 0 (без ограничений). Он не говорит, что вы не можете переопределить это:
Edit: Я просто попробовал сам, и он работает, как ожидалось.
set_time_limit() работает в CLI скриптах.
через секунду возвращается со следующим сообщением об ошибке:
Первоначально я пытался со sleep (), и ограничение по времени не применяется. Как предложил @Jon, используя реальное вычисление, как работает бесконечный цикл.
Я нашел этот интересный комментарий в sleep () страница PHP:
Примечание: функция set_time_limit () и директива конфигурации max_execution_time влияют только на время выполнения самого скрипта. любое время, затраченное на действия, которые происходят вне выполнения скрипта, такие как системные вызовы с использованием system(), функция sleep (), запросы к базе данных и т. д. не входит при определении максимального времени выполнения скрипта
у меня аналогичная проблема. Но в моем случае у меня были удаленные вызовы базы данных, занимающие значительное время, и я хотел завершить сценарий через определенное время. Как отмечено в других ответах, внешние вызовы (или sleep() ) не считается с настроенным параметром тайм-аута.
обратите внимание, что возможно, что ваш сценарий заканчивается красиво, и новый, другой запускается с тем же pid, который эта команда kill завершит. Это маловероятно, но вы должны рассматривать это как возможность, если вы используете этот подход.