Привіт усім! Сьогодні хочу поділитися невеликим, але потужним лайфхаком для PHP-розробників.
Часто буває ситуація: користувач натискає кнопку, і нам треба запустити якийсь важкий процес (наприклад, відправка імейлів, генерація великого звіту або запит до стороннього API), але ми не хочемо змушувати користувача чекати 10-20 секунд, поки скрипт завершиться.
В PHP є чудова функція fastcgi_finish_request(), яка дозволяє миттєво віддати відповідь клієнту (браузер отримає статус 200 і закриє з'єднання), але при цьому скрипт продовжить виконуватися далі на сервері.
Ось як це виглядає:
Важливий нюанс: якщо ви використовуєте звичайний Apache без FastCGI, то fastcgi_finish_request не буде існувати. У такому разі можна спробувати комбінацію ignore_user_abort(true) та flush(), хоча це не завжди гарантує, що з'єднання закриється негайно (залежить від налаштувань сервера та буферизації).
Як перевірити, чи вона у вас є?
Хтось використовує такий підхід у проектах? Чи ви віддаєте перевагу чергам (RabbitMQ/Redis)?
Часто буває ситуація: користувач натискає кнопку, і нам треба запустити якийсь важкий процес (наприклад, відправка імейлів, генерація великого звіту або запит до стороннього API), але ми не хочемо змушувати користувача чекати 10-20 секунд, поки скрипт завершиться.
В PHP є чудова функція fastcgi_finish_request(), яка дозволяє миттєво віддати відповідь клієнту (браузер отримає статус 200 і закриє з'єднання), але при цьому скрипт продовжить виконуватися далі на сервері.
Ось як це виглядає:
Код:
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request(); // Віддає відповідь клієнту і продовжує виконання
} else {
// Альтернатива для звичайного Apache/PHP-FPM
ignore_user_abort(true);
flush();
}
// Тут починається важка магія, яку юзер вже не чекає
sleep(10);
file_put_contents('log.txt', 'Job done at ' . date('H:i:s'));Важливий нюанс: якщо ви використовуєте звичайний Apache без FastCGI, то fastcgi_finish_request не буде існувати. У такому разі можна спробувати комбінацію ignore_user_abort(true) та flush(), хоча це не завжди гарантує, що з'єднання закриється негайно (залежить від налаштувань сервера та буферизації).
Як перевірити, чи вона у вас є? Код:
if (function_exists('fastcgi_finish_request')) {
echo "Функція доступна!";
} else {
echo "Функція не підтримується на цьому сервері.";
}Хтось використовує такий підхід у проектах? Чи ви віддаєте перевагу чергам (RabbitMQ/Redis)?
PHP Developer | Laravel | Symfony | Docker

