До основного вмісту

PHP у cron: чим CLI відрізняється від FPM на практиці

PHP · 29.09.2026

Чим PHP CLI відрізняється від PHP-FPM для завдань cron

PHP-FPM обслуговує HTTP-запити через Nginx і працює в режимі пулу воркерів зі спільним php.ini та лімітами, заданими для вебнавантаження. PHP CLI — це окремий бінарник /usr/bin/php8.3, який запускається з командного рядка або з crontab і читає свій власний конфіг, зазвичай із /etc/php/8.3/cli/php.ini. Значення memory_limit, max_execution_time і error_reporting у CLI та FPM можуть відрізнятися, і це часта причина, чому скрипт у браузері працює, а той самий скрипт за розкладом падає або навпаки.

Друга відмінність — оточення. У процесу cron немає змінних PATH, HOME і локалі, які є в інтерактивній оболонці, і немає робочого каталогу за замовчуванням: він завжди стартує з домашнього каталогу користувача, від імені якого запущено cron.

Як правильно прописати завдання у crontab

Правило crontab повинно вказувати повний шлях до бінарника PHP, повний шлях до скрипту і робочий каталог, якщо скрипт використовує відносні шляхи до файлів.

*/5 * * * * cd /var/www/app && /usr/bin/php8.3 artisan schedule:run >> /var/log/app/cron.log 2>&1

Символ && гарантує, що php запуститься лише після успішного переходу в каталог, а 2>&1 перенаправляє помилки в той самий лог-файл, що і звичайний вивід. Без цього фатальні помилки PHP тихо зникають: cron надсилає їх на локальну пошту, яку ніхто не читає.

Власна версія php.ini для CLI

Перевірити, який конфіг насправді використовує CLI, можна однією командою — вона покаже шлях до файлу, а не припущення.

php --ini
php -i | grep memory_limit

Якщо на сервері встановлено кілька версій PHP, як описано у статті про кілька версій PHP на одному сервері, у crontab обов'язково вказуйте версію явно: /usr/bin/php8.3, а не просто php — інакше завдання може несподівано виконатися під іншою версією після оновлення alternatives.

Пам'ять, таймаути і робочий каталог: часті пастки

ПараметрВеб (FPM)Cron (CLI)
memory_limit128Mчасто без обмеження (-1)
max_execution_time30 секунд0, обмеження немає
робочий каталогкорінь сайтудомашній каталог користувача
error_logлог PHP-FPMstderr, якщо не задано явно

Значення з таблиці задаються в різних секціях php.ini: [PHP] впливає на обидва режими, а блок cli/conf.d — лише на CLI. Керування пам'яттю і завантаженням докладно розібрано у статті про memory_limit і upload_max_filesize.

Журналювання виводу завдань cron

  • Завжди перенаправляйте stdout і stderr в окремий файл журналу, а не покладайтеся на пошту cron.
  • Вказуйте display_errors = Off і log_errors = On у cli/php.ini — вивід помилок у консоль ламає формат, якщо скрипт друкує JSON чи CSV.
  • Ротацію лог-файлу cron налаштовуйте через logrotate, інакше файл виросте до гігабайтів за місяць.
  • Розбір завдань, що впали, починайте з error_log, а не з припущень — принципи розібрані у статті про логи PHP і розбір фаталів.
  • Додавайте на початок кожного завдання date і hostname в журнал — на кластері з кількох серверів інакше не зрозуміти, хто саме писав у журнал.

Підсумок: чек-лист для PHP-завдань у cron

  • У crontab вказано повний шлях до бінарника потрібної версії PHP і робочий каталог через cd.
  • Вивід команди перенаправлено у файл журналу з ротацією через logrotate.
  • Перевірені memory_limit і max_execution_time саме у cli/php.ini, а не в конфігу FPM.
  • display_errors вимкнено, log_errors увімкнено, помилки йдуть у файл, а не в пошту root.
  • Завдання перевірене вручну від імені того самого користувача, від якого його запускає cron.
← Назад до бази знань Поставити питання підтримці