За последние 24 часа нас посетили 20232 программиста и 1203 робота. Сейчас ищут 649 программистов ...

echo блокирует ignore_user_abort

Тема в разделе "PHP для профи", создана пользователем Xopc11, 24 мар 2024.

  1. Xopc11

    Xopc11 Активный пользователь

    С нами с:
    4 апр 2019
    Сообщения:
    13
    Симпатии:
    1
    Доброго времени суток.
    Столкнулся с такой проблемой.

    Есть ajax запрос с "заморозкой" браузера до получения ответа. Скрипт к которому он обращается должен отдать ответ и продолжить работать некоторое время. Для разрыва соединения использую следующее
    PHP:
    1. ignore_user_abort(true); // игнорим что клиент отвалился и продолжаем работу
    2. set_time_limit(0); // делаем лимит времени выполнения бесконечным
    3. ob_start(); // включаем буферизацию вывода
    4. file_put_contents('1.txt','№1 - time:'.date('H:i:s')." - запрос"."\n",FILE_APPEND); // тестовый файлик с результатами выполнения
    5. // echo json_encode(['data1'=>1,'data2'=>2]); // ответ сервера блин браузера
    6. session_write_close(); // записываем сессию и завершаем её
    7. header('Connection: close'); // посылаем заголовок клиенту, что соединение закрыто
    8. header('Content-Length: ' . ob_get_length()); // посылаем количество байт
    9. ob_end_flush(); // сбрасывает буфер вывода
    10. ob_flush(); // сбрасывает буфер вывода
    11. flush(); // сбрасываем системный буфер и отправляем
    12. // На этом этапе клиент должен быть отключен
    13. sleep(5); // имитация бурной деятельности
    14. file_put_contents('1.txt','№2 - time:'.date('H:i:s')." - готово"."\n",FILE_APPEND); // тестовый файлик с результатами выполнения
    Проблема заключается echo. Если его убрать (отдать браузеру пустоту) все сработает. Браузер сразу получает ответ. Выходит следующее
    №1 - time:04:36:49 - запрос
    Браузер получил ответ
    №2 - time:04:36:54 - готово

    Верное поведение. Поступил запрос, ответ вернулся, через 5 сек скрипт закончил работу.

    Но если я раскомментировать echo, все ломается. Запрос отправляется и браузер "замирает" до полного завершения скрипта. В итоге
    №1 - time:04:36:49 - запрос
    №2 - time:04:36:54 - готово
    Браузер получил ответ

    Были еще проблемы с тем что в php.ini ignore_user_abort был закомментирован. Поставил on, но с этой проблемой это не помогло.

    Тестирую на OpenServer
    Apache_2.4-PHP_7.2-7.4
    PHP_7.2_php

    Вот и вопрос почему так происходит?
    Заранее спасибо.
     
  2. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    260
    Симпатии:
    51
    Адрес:
    Бавария, Германия
    Добрый день!
    Оператор echo посылает заголовок и ответ браузеру. После этого header и.т.д. игнорируются.
    Верно, echo д.б. закомментирован.
    Специально для таких случаев советую написать простенькую функцию для сохранения debug в файл на сервере.
    Удачи!
     
  3. Xopc11

    Xopc11 Активный пользователь

    С нами с:
    4 апр 2019
    Сообщения:
    13
    Симпатии:
    1
    Да но ведь echo в данный момент еще никуда не отправляется. Я перегуглил десятки статей на эту тему и во всех присутствует echo, браузер получает инфу от сервера. Более того, нечто подобное у меня уже было когда-то на хостинге и тоже прекрасно работало. Я скопировал этот кусок кода из тех же статей и тогда все было ок.

    Проблема именно на моем OpenServer. Я подозреваю какие-то настройки самого сервера о которых я не в курсе.
     
  4. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    260
    Симпатии:
    51
    Адрес:
    Бавария, Германия
    Нет Вы ошибаетесь. Проблема не в OpenServer. Включите erro_reporting.
    PHP после echo на операторе header выдаст предупреждение:
    где 5 - номер строки с оператором echo
    Можете проверить на другом сервере или на OpenServer вставив console.log в JS
    Код (Javascript):
    1. ...
    2. xhr.onreadystatechange = function()
    3. {
    4.    if (this.readyState == 4 && this.status == 200)
    5.    {
    6.       console.log(this.responseText);
    7.    }  
    8. }
    9. ...
     
    Xopc11 нравится это.
  5. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    260
    Симпатии:
    51
    Адрес:
    Бавария, Германия
    (дополнение)
    Обратите внимание на то, что аналогичная пролема возникает с session_start и setcookie
     
  6. Xopc11

    Xopc11 Активный пользователь

    С нами с:
    4 апр 2019
    Сообщения:
    13
    Симпатии:
    1
    Да, действительно. У меня есть свой обработчик всех ошибок, которой, видимо, выбрасывает Warning и из-за этого header уже не отрабатывает. А из-за буферизации сам Warning в ответ не попадает.
    Получается что-то вроде
    (Warning: Cannot modify header information - headers already sent by)
    №1 - time:04:36:49 - запрос
    №2 - time:04:36:54 - готово
    Браузер получил ответ

    Отключил ошибки и все заработало.