PHP: ignore_user_abort (верный) во всех сценариях

У меня есть веб-сайт, который работает с PHP на стороне сервера.

Пользовательские страницы доступа и PHP делают некоторые вычисления, данные записей к базе данных MySQL и т.д.

Предположите, что пользователь получает доступ к странице, где PHP создает счет на пользователя. Создание состоит из двух частей: вставка регистрационных данных в таблицу "пользователи" и вставка настроек для этой учетной записи в таблицу "настройки". Это два SQL-запроса, которые должны быть выполнены один за другим. Если пользователь выходит из страницы после первого запроса, нет никаких значений, вставленных в "настройки".

Как я мог избежать этой проблемы? Я думаю просто при помощи (верного) ignore_user_abort, правильно?

Так разве не полезно называть ignore_user_abort (верным) на верхней части каждого Сценария PHP? Я не знаю случаев, где это должно вызвать проблемы.

11
задан caw 7 March 2010 в 17:20
поделиться

3 ответа

Для вашего конкретного примера использование транзакций базы данных (как упомянул Игнасио) было бы более подходящим подходом.

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

Однако обратите внимание, что разрыв трубы из-за прерывания соединения клиентом не останавливает выполнение сразу, а только в момент следующей попытки записи в вывод скрипта. Это может быть вызов echo или print, или даже просто закрытие тега PHP и вставка пробельных символов перед открытием нового (... ?> ). Таким образом, если вы разместили все "действия" вашего сценария в верхней части страницы, до того как вы попытаетесь написать содержимое страницы, вам не придется беспокоиться о том, что прерывания от сломанных труб повлияют на логику вашего приложения.

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

От http://php.net/manual/en/function.ignore-user-abort.php#refsect1-function.ignore-user-abort-notes

PHP не обнаружит, что пользователь прервал соединение, пока не будет сделана попытка отправить информацию клиенту. Простое использование оператора echo не гарантирует, что информация будет отправлена

13
ответ дан 3 December 2019 в 07:37
поделиться

Вы можете установить ignore_user_abort в php.ini: Конфигурация PHP.ini

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

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

1
ответ дан 3 December 2019 в 07:37
поделиться

Если вам нужно, чтобы несколько запросов либо выполнялись полностью, либо не выполнялись вообще, то вам следует делать это правильно, используя транзакции, а не накладывать повязку на проблему.

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

2
ответ дан 3 December 2019 в 07:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: