huidong

首页 | 会员登录 | 关于争取 2022 寒假做出汇东网 Ver3.0.0 !
搜索文章


之前我发现,php未执行完所有代码前(或输出缓冲区满了之前),都不会输出echo语句的内容。如果说想让php代码每隔一段时间就输出一段内容,必然要使用到sleep函数,然而sleep是阻塞函数,php代码要执行完所有sleep后才会一次性把所有echo的内容全输出。


还有一种情况是:echo的内容太多了,达到了缓冲区大小的极限,而php还没执行完,此时也会先输出内容。

php缓冲区的大小一般是1MB,网上有教程查看缓冲区大小。

网上有办法说是输出内容后,再输出一些空内容,使缓冲区大小达到极限,输出内容。我觉得太不靠谱了,输出那么多内容毫无益处,而且不同的php端的缓冲区大小可能不同,这样写出来的代码移植性不高。


后来就是看到输出缓冲区内容的一个函数,flush();


于是我就使用echo 语句输出内容,flush语句把缓冲区内容输出,sleep语句延时,再用js语句清屏再echo再flush,就是下面的代码:

<?php

    echo "hello<br/>aa";
    
    // 在php未执行完时就先输出内容,使用flush函数
    flush();
    sleep(3);
    
    // js清屏
    echo "<script>document.body.innerHTML = '';</script>";
    
    echo "yes";

?>

按此原理实现动态改变网页内容。


上述代码之前是可以正常运行的,昨天突然不行了,网上一查要在flush()前加上ob_flush()才行,有人说这样之后无论在什么地方都能输出了。

然而凡事有例外,我这就不行。


可能是我的php版本太老了(五点几的版本)?


但是我也懒得下新的。


那咋整啊。磨了半天,突然这段代码又成功输出内容了,有时可以有时不行。


这也太不稳定了吧,这样不行的。


我的需求大概是这样的:

<?php

    while(true)
    {
        echo "a";
        
        ob_flush();
        flush();
        
        sleep(1);
    }

?>


上面这段代码预期的执行效果是每隔一秒输出一个a,然而,ob_flush和flush都没有输出内容。


而且由于死循环的存在,php执行超过60s,服务器自动报错,停止执行。


后来我还找到了一个函数

set_time_limit(0);

这个语句可以取消php运行时间的限制,但是仍然无法解决输出不了内容的问题。


仔细想想,我是要隔一段时间执行一段php代码,但是在之前的方案中我是用了sleep语句和flush语句来实现的,但是只要能达到目的,不一定要用flush语句啊!

而且原来的代码还有一个弊端:php代码未执行完之前,就算flush输出了内容,浏览器的标签页上面还是会显示一直在加载,很不好看。


我一拍脑袋啊,马上就给出了解决方案(其实第二天才实现):使用js做定时器,网页可以正常运行,标签页不会保持加载状态,

js的定时器到时间就自动唤醒php代码,php代码不就可以定时执行了嘛!


哇,这个办法不错。


网上一查,js的定时器是setInterval和setTimeout,这两个有区别。


前者是一个保持运作的定时器,时间一到就执行一次语句,如此往复。后者只响应一次。

引用W3C的一句话:

setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。


那么我的需求当然得用setInterval来实现喽。


setInterval用法(来自菜鸟教程 https://www.runoob.com/w3cnote/js-timer.html ):

setInterval(code,millisec,lang)

     

参数描述
code必需。要调用的函数或要执行的代码串。
millisec必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。
lang可选。 JScript | VBScript | JavaScript


也就是说:

<script>
    setInterval("js代码", 定时器时长);
</script>


接下来,有了定时器,如何用js唤醒php代码?


可以用iframe嘛。


设置一个iframe在网页中,给它一个id。

定时器中的js代码设置为重新加载这个iframe,也就是下面这样:

<script>
    setInterval("document.getElementById('iframe标签的id').contentWindow.location.reload(true)",定时器长度);
</script>


iframe的src设置为一个php页面,这样下来,每隔一段时间,js定时器就会刷新某个指定的php页面,可以让这个php页面执行一些代码,然后通过session来传递一些值。


如果这个后台php不需要显示在前端,可以把iframe的width,height,frameborder什么的都设置为0,这样就显示不出来了。


差不多就是这样了,讲的这么清楚,该不会有人不知道具体怎么写吧?


js代码都给出来了,自己把iframe补全吧。。。


还有一点,如果说要使php的页面内容定时刷新或者在某条件下刷新,但是不想要整个页面都刷新,只想要某个地方刷新,这一点用js很容易实现,但是如果要用php就有点难受。


可以这样:把要刷新的页面内容写到另一个php页面里,然后在主页面中用iframe显示这个php页面,两个php页面可以用session相互交换数据,而且iframe的属性可以自己调。之后在主页面使用js定时器刷新iframe页面,或者获捕到用户的某操作后用js刷新页面,实现部分内容的刷新。


差不多就是这样了。




返回首页


Copyright (C) 2018-2024 huidong