Предположим, что я делаю HTTP-запрос AJAX из jQuery для внутреннего скрипта PHP. Запрос выполнен, скрипт PHP запускается и выполняет свою магию. Предположим, что я перехожу на другой сайт, вдали от сайта, на котором был сделан оригинальный запрос AJAX. Кроме того, я делаю это до того, как PHP-скрипт заканчивается и успевает выполнить ответ HTTP-ответа. Завершает ли PHP-скрипт выполнение своей работы, даже если я перешел на другой сайт, прежде чем получил HTTP-ответ?
Итак, порядок в этом.
Что происходит с blah.php? Продолжается ли исполнение? Он остановился? Я имею в виду, что у него не было шанса ответить так …
Это может зависеть от конфигурации вашего сервера, но в целом сценарий будет продолжать выполняться, несмотря на закрытое HTTP-соединение .
Я тестировал это с Apache 2 + PHP 5 как mod_php . Я бы ожидал подобного поведения с PHP как CGI и с другими веб-серверами, но не знаю наверняка.
Лучший способ определить для определенной конфигурации, как @tdammers предлагает: настроить тестовый сценарий примерно так: следить за журналом.
<?php error_log('Test script started.'); for ($i = 1; $i < 13; $i++) { sleep(10); error_log('Test script got to ' . (10 * $i) . ' seconds.'); } error_log('Test script got to the end.'); ?>
Получите доступ к этому скрипту (на /test.php
или что-то еще), прежде чем вы получите какие-либо результаты, нажмите «остановить» в своем браузере. Это эквивалентно навигации до вашего XHR. Вы даже можете использовать его как цель XHR и перемещаться.
Затем проверьте свой журнал ошибок: вы должны начать, а затем сообщения каждые 10 секунд в течение двух минут и с конца. Вы можете изменить, как высокий $i
получает, чтобы ваш скрипт достиг своего ожидаемого максимального времени выполнения, если вы тоже хотите его проверить.
Вам не нужно использовать error_log()
– вы можете записать в файл или сделать некоторые другие постоянные изменения на сервере, которые можно проверить, не открывая соединение клиента.
Время выполнения скрипта может прекратиться до этого из-за директивы max_execution_time
php.ini, но в любом случае это должно отличаться от того, когда веб-сервер отключается.
Попробуйте ignore_user_abort (true);
ignore_user_abort(true);
он не должен прерывать выполнение кода
Вы можете проверить ответы на этот вопрос . В основном, когда вы делаете свой вызов ajax функции php, которая вызывает функцию exec()
как показано в ответах на этот вопрос, вы получите ответ ajax почти сразу, так как ваша php-функция фактически не нуждается в обработке чего-либо. Таким образом, не важно, покидает ли пользователь страницу. Вот небольшой пример:
ajax-вызов в html-файле: $.ajax({url: 'blah.php'});
Файл blah.php: exec('bash -c "exec nohup setsid php really_slow_script.php > /dev/null 2>&1 &"');
И затем, наконец, в файле really_slow_script.php, просто укажите фактический код, который вы хотите запустить.
Я успешно использовал эту логику, чтобы пользователи могли публиковать уже загруженное видео со своей учетной записи на моем веб-сайте на youtube. (Видео должно было быть отправлено на YouTube, и поскольку видео, как правило, являются большими файлами, я не хотел, чтобы пользователю приходилось ждать, пока видео было загружено на youtube)
Навигатор будет вызывать сообщение об отключении на сервере. Последствия этого полностью зависят от того, что настроил ваш сервер .
По умолчанию сервер будет настроен таким образом, чтобы отключение не прерывало работу программы. Тем не менее, можно сделать так, чтобы пользователь отключил функцию, зарегистрированную с помощью register_shutdown_function
, сбор мусора, и сценарий завершится.
Поскольку это то, что может быть настроено в нескольких разных местах, было бы проще всего запустить тест, но это директива php.ini. Если вы хотите настроить это на глобальном уровне, вы можете установить ignore_user_abort = Off
в php.ini. Если вы хотите это на уровне сайта, вы можете использовать php_value ignore_user_abort off
в htaccess в родительском каталоге текущего сайта. В противном случае вы можете использовать ignore_user_abort(false);
,
Конечно, на общем сервере нет гарантии, что у вас есть контроль над htaccess или php.ini, поэтому вам просто нужно использовать ignore_user_abort(false);
,