php源码分享网站运行不了,php网站源码下载

大家好,今天来为大家解答php源码分享网站运行不了这个问题的一些问题点,包括php网站源码下载也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~

以前在写PHP接口的时候,有时候为了方便就直接在浏览器上测试,通过echo打印内容进行调试。不过有些地方打印的“日志”数据太多,一下子看不过来,就想着先sleep一下再输出。

当时不太会搜索,找到的各种方法都不行,每次都是延迟后输出全部结果,并不会一点一点输出。

代码差不多长这样:

<?php\nob_start();\nfor($i=0;$i<10;$i++){\necho&34;;\nechostr_pad(&39;,4096).&34;;\nob_flush();\nflush();\nsleep(1);\n}\nob_end_flush();\n

实际运行结果是前端等待10秒后,一次性打印全部内容。

最近深入学习了网络原理后,突然想到这个问题,想着会不会是因为TCP协议里的Nagle算法的缘故,于是就再次试了一下,结果依然是失败。不过现在我的搜索能力和以前大不相同,经过多番查找和实验,终于成功了。

这个其实和Nagle算法关系不大,毕竟网上给的例子很多都会在输出的末尾加上一大堆空字符串,这远远超出了超出了窗口大小,而且延迟确认应答也有时间限制,最大延迟0.5秒发送确认应答,很多操作系统设置为0.2秒左右,换句话说,最多0.5秒,后端就会将数据发送给前端,从而实现稍带应答。但现实情况是网页等待的时间是所有sleep的总和,而且网页是一次性打印出所有内容的,因此和它无关。

真正的原因是输出缓冲区,后端发送的数据只有等缓冲区满了才会真正发送给前端,而这个缓冲区多达四层,甚至可以更多。只要其中一个缓冲区未满,数据就发送不出去,前端就不会立即看到结果,这就是我为何一直失败的原因。那么多层缓冲区,总有一个你没设置好,然后就被卡住了。

下面我们就来一个一个地攻克这些难关。

1、PHP默认缓冲区(DefaultOutputLayer)

除了HTTP首部外,不管你是用print还是用echo等打印内容,都会先存储在这个缓存区中,只有缓冲区满了,才会输出到下一个缓冲区中。

可以在php.ini配置中设置output_buffering=Off以关闭缓冲区,我试过用ini_set函数进行设置是无效的。

你也可以使用ob_flush强制刷新缓冲区。

2、SAPIBuffer

PHP-FPM实现了SAPI接口,PHP默认缓冲区输出的内容会被PHP-FPM进程缓存。

php.ini配置中设置implicit_flush=On可以自动刷新缓冲区,这个同样无法用ini_set进行修改。

使用flush函数强制刷新缓冲区也可以起到同样的效果。

这里有一个地方要注意,当output_buffering=On时,对implicit_flush进行修改是无效的,只能使用flush方法强制刷新缓冲区。

3、Nginx缓冲区

在Nginx配置文件中设置fastcgi_bufferingoff可以禁用缓冲区,也可以在PHP脚本中添加header(&39;)禁用缓冲区。

4、浏览器缓存

到了这里,数据已经通过HTTP协议发送给了前端(浏览器),但浏览器并不会立即显示,其本身同样会缓存数据。可以在控制台中使用curl-Nurl进行测试。或者在数据尾部添加一些空字符,强行填满缓冲区。

实际我测试的时候特别奇怪,在命令行上使用curl是没有问题的,但是在Chrome浏览器中,访问时并不会立即显示内容,而这并非因为浏览器缓存,因为当我在程序中加入ob_flush后,浏览器是会立即打印内容的,而我所打印的内容只有三个字节,这浏览器缓存肯定是没有用到的。这样看来output_buffering=Off并没有生效,可是如果你把这个配置去掉的话,那不管你加不加ob_flush,浏览器都不会立即输出结果。另外去掉Accept-Encoding头同样可以立即输出结果,确实奇怪。

其实大家也不用过于纠结,现实也不会有这么奇葩的需求,真要遇到了,多测试一下就行了。

UserOutputLayers

除了应用本身自带的缓存,我们也可以使用ob_start创建缓冲区。

多次调用ob_start会创建多个缓冲区,它们就像连在一起的漏斗,上一层慢了,就会把数据刷新到下一层。

flush只能刷新最顶层的缓冲区,不管它是不是满的。

ob_end_flush在刷新完顶层缓冲区后会关闭该缓冲区,这样多次调用后就可以把数据刷新到SAPI缓冲区。

一些框架所使用的模板语言就是利用自定义的缓冲区,将数据收集起来,再使用ob_get_contents和ob_end_clean将数据从缓冲区中读取出来,最后才打印数据。

代码

最后我们来看下完整代码,方便需要的时候直接拷贝。

<?php\n\n//PHP输出缓冲区关闭\n//配置php.ini,这个ini_set(&34;,&34;)是无法修改的\n//output_buffering=Off;\n//可用ob_flush()刷新\n\n//关闭SAPI的缓冲区\n//配置php.ini,这里ini_set(&39;,1)设置无效\n//implicit_flush=On\n//可用flush()刷新\n\n//关闭nginx缓冲区\nheader(&39;);\n//或在Nginx配置文件中设置fastcgi_bufferingoff\n\necho&39;;//少于三个字符也不行\nob_flush();//在浏览器中运行要加这个\n//flush();//保险起见,最好flush一下\nsleep(3);\necho&39;;\n\n//测试\n//curl可以禁用缓存,建议用这个测试,当然最好的方式是cli+日志文件\n//curl-Nhttp://php.test.com/test.php\n\n

说明

命令行CLI下运行是不会有缓冲区这个问题的,默认都是关闭的,除非用户主动创建。

切忌在生产环境里关闭缓冲区,服务器炸锅了我可不负责。

以上结果在不同的PHP版本中可能会有不同的表现,以实际运行结果为准,下面是我的测试环境数据:

Docker版本:19.03.5

PHP版本(运行于Docker内):v7.4.6

Openresty版本(运行于Docker内):1.15.8.3

Chrome版本:87.0.4280.88(正式版本)(x86_64)

总结

这个我研究了很久,各种修改代码和配置,搞得我都想**了,sunof*****.

最后,作为一个PHPer,我想说,PHP是最好的语言,没有之一,哈哈。

喜欢的朋友欢迎点赞,让更多的人看到。

关于php源码分享网站运行不了,php网站源码下载的介绍到此结束,希望对大家有所帮助。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平