首页 > 解决方案 > 如何在使用 ob_flush() 执行 PHP 后使 div 消失

问题描述

我有一个 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执行完成后,加载的文字还在页面上,并没有消失。

请帮我解决这个问题:)

标签: php

解决方案


不,这不是ob_flush()目的。像 PHP 这样的服务器端语言根本不可能。您必须改用javascript。

以下是请求 PHP 网页时发生的大致简化且并非 100% 准确的描述:

  1. 浏览器向服务器发送请求“嘿服务器,给我主页”
  2. 服务器为主页运行 PHP 脚本
  3. 通常,PHP 脚本会生成一些输出。服务器将收集此输出。
  4. 脚本完成后,服务器会说“OK Browser,here is your Home page”,将输出(响应)发送到浏览器,然后关闭连接
  5. 连接现在已关闭,服务器已经忘记浏览器甚至在一秒前请求页面。
  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 参数,所以你必须扩展这段代码,或者切换到 cookie 或 session 来检查请求是否是次要的。
  3. 路的尽头将是一个 javascript/ajax 驱动的单页应用程序,但我认为这超出了您的问题范围。
  4. 当心 PHP 标记和 HTML 的这种不可读的混合,这样的代码是不受欢迎的,有充分的理由。这仅用于演示。

推荐阅读