Как заставить div исчезнуть после выполнения PHP с помощью ob_flush()

#php

#php

Вопрос:

У меня есть PHP-файл, который я хочу показать загружаемому тексту или изображению посетителю, пока он полностью загружен. Насколько я знаю, я должен использовать ob_flush(); для этого. Я попробовал следующий код:

 <?php

ob_start();

echo '<div> Loading </div>';

ob_end_flush();

ob_flush();
flush();

ob_start();
ob_clean();

//my php code
//my php code

?>
  

С этим кодом все в порядке, сначала появляется текст загрузки, а затем запускается исключение PHP. Но моя проблема в том, что после завершения выполнения PHP текст загрузки все еще находится на странице и не исчезает.

Пожалуйста, помогите мне решить эту проблему 🙂

Комментарии:

1. О каком исключении вы говорите? Почему бы не удалить div с помощью Javascript?

2. @NicoHaase К сожалению, я не очень хорошо знаком с javascript, пожалуйста, объясните немного больше об этом или приведите пример об этом

Ответ №1:

Нет, это не то, ob_flush() для чего. Это вообще невозможно с таким серверным языком, как PHP. Вместо этого вы должны использовать javascript.

Вот грубо упрощенное и не на 100% точное описание того, что происходит, когда вы запрашиваете веб-страницу PHP:

  1. Браузер отправляет запрос на сервер «Привет, сервер, дай мне страницу домой»
  2. Сервер запускает PHP-скрипт для домашней страницы
  3. Обычно PHP-скрипт генерирует некоторый вывод. Сервер соберет этот вывод.
  4. Когда скрипт завершен, сервер сообщает «OK Browser, вот ваша домашняя страница», отправляет вывод (ответ) в браузер, а затем закрывает соединение.
  5. Соединение теперь закрыто, и сервер уже забыл, что браузер даже запрашивал страницу 1 секунду назад.
  6. Браузер с радостью отобразит недавно полученную веб-страницу. Теперь нет способа заставить что-то произойти в браузере для вашего PHP-скрипта.

Это называется шаблоном ответа на запрос, и он все еще несколько фундаментален для Интернета.

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

 <!DOCTYPE html>
<html>
<head>
  <title>Loading overlay test</title>
</head>
<body>
    <a href="">Click me!</a>
    <script>
        document.addEventListener(
            'click',
            function() {
                if(event.target.matches('a')) {
                    document.body.innerHTML = "Loading next page ...";
                }
            },
            false
        );
    </script>
</body>
</html>
  

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

Когда вам абсолютно необходимо наложение для первого запроса страницы, все становится сложнее. Вот готовый к работе пример без ajax:

 <?php
// Detect 1st page hit
if(empty($_GET['fetch_real_page'])) {

// Loading page - keep as simple(fast) as possible, 
// prevent any slow database queries etc.
?>
<!DOCTYPE html>
<html>
<head>
    <title>The loading page</title>
</head>
<body>
   Loading first page...
   <script>
       // This will instantly request the "real" page
       window.location.replace(window.location.href   '?fetch_real_page=1');
   </script>
</body>
 </html>

<?php

exit; 
// (Does not need to be called explicitely
// when nothing comes after the if-else construct)

} else {

sleep(2); 
// Simulates a slow page load,
// do all the heavy database stuff that slows down your page here.
// Then, output the "real" page:
?>

<!DOCTYPE html>
<html>
<head>
    <title>The real page</title>
</head>
<body>
    <a href="my_page.php?fetch_real_page=1">Click me!</a>
    <script>
        // Set up the loading overlay for secondary requests
        document.addEventListener(
            'click',
            function() {
                if(event.target.matches('a')) {
                    document.body.innerHTML = "Loading next page ...";
                }
            },
            false
        );
    </script>
</body>
</html>

<?php
}
?>
  

Что следует учитывать:

  1. Вам нужно расширить каждую внутреннюю ссылку с fetch_real_page=1
  2. Рано или поздно вам придется иметь дело с дополнительными параметрами $_GET, поэтому вы должны расширить этот код или переключиться на cookies или сеанс, чтобы проверить, является ли запрос вторичным или нет.
  3. В конце пути появится одностраничное приложение на основе javascript / ajax, но я думаю, что это выходит за рамки вашего вопроса.
  4. Остерегайтесь этой нечитаемой смеси тегов PHP и HTML, подобный код не одобряется по уважительным причинам. Это только для демонстрации.

Комментарии:

1. Здравствуйте, спасибо за ваше объяснение. К сожалению, я не очень хорошо знаком с javascript, я искал фразу, которую вы сказали, но я не смог найти хороший пример того, как встроить javascript в код PHP. Пожалуйста, объясните немного больше об этом или приведите пример об этом.