php实现bigpipe
PHP 实现
2023-09-14 08:57:28 时间
BigPipe是facebook发明的一种页面加载技术。其实也不是什么新技术了,也有很多文章进行说明。但是在网上,具体讲如何使用php实现bigpipe的文章很少,并且有些文章还不很准确。bigpipe的核心思想是并行,服务器生成数据和浏览器渲染数据的并行。
在实现bigpipe时有几点注意:
1.如果使用nginx作为web服务器,那么nginx可能会缓冲php的输出。即便是调用了flush方法,相应内容也会被nginx缓冲,而不会输出到浏览器。
2.某些浏览器也会有缓冲,如在接收的数据小于一定值的时候,不会对代码进行渲染。
详细介绍请查看 《从php的缓冲区说起》
以下是一个demo示例代码:
?php header("Transfer-Encoding","chunked"); ini_set("output_buffering",0); html xmlns="http://www.w3.org/1999/xhtml" head meta http-equiv="Content-Type" content="text/html; charset=utf-8" / title php实现BigPipe /title style type="text/css" body { font-size:12px; text-align:left; #head { width:100%; height:40px; background:#8CAADE; font-weight:bold; color:#FFFFFF; line-height:40px; text-align:center; font-size:16px; #body { margin:5px auto 5px auto; width:800px; border:solid 1px #8CAADE; padding:10px; line-height:30px; #left { float:left; width:50%; border:0px; line-height:23px; #right { float:right; width:50%; border:0px; line-height:23px; #result { width:800px; height:30px; text-align:center; #bottom { margin-top:5px; width:800px; height:30px; text-align:center; display:none; #bottom a { color:red; text-decoration:none; /style script function update(id, content) { document.getElementById(id).innerHTML = content; /script /head ?php ob_flush(); flush(); body div id="head" php实现BigPipe /div div id="body" div 本demo旨在演示php的并发处理在bigpipe中的应用。因此,在一些细节上实现的比较简单。但是,demo完全体现了bigpipe的并行数据处理和并行加载。 br/ 慢动作体现的是后端php串行处理时的效果。 /div div id="cost_time" /div ?php * @purpose: 使用curl并行处理url * @return: array 每个url获取的数据 * @param: $urls array url列表 * @param: $callback string 需要进行内容处理的回调函数。示例:func(array) function curl($urls = array(), $callback = ) $response = array(); if (empty($urls)) { return $response; $chs = curl_multi_init(); $map = array(); foreach($urls as $url){ $cookie_file = "/temp/".md5($url).".txt"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 2); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_NOSIGNAL, true); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER[HTTP_USER_AGENT]); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); curl_multi_add_handle($chs, $ch); $map[strval($ch)] = $url; if (($status = curl_multi_exec($chs, $active)) != CURLM_CALL_MULTI_PERFORM) { if ($status != CURLM_OK) { break; } //如果没有准备就绪,就再次调用curl_multi_exec while ($done = curl_multi_info_read($chs)) { $info = curl_getinfo($done["handle"]); $error = curl_error($done["handle"]); $result = curl_multi_getcontent($done["handle"]); $url = $map[strval($done["handle"])]; $rtn = compact(info, error, result, url); if (trim($callback)) { $callback($rtn); $response[$url] = $rtn; curl_multi_remove_handle($chs, $done[handle]); curl_close($done[handle]); //如果仍然有未处理完毕的句柄,那么就select if ($active 0) { curl_multi_select($chs, 0.5); //此处会导致阻塞大概0.5秒。 while($active); //还有句柄处理还在进行中 curl_multi_close($chs); return $response; //使用方法 function deal($data){ $url_info = parse_url($data["url"]); $content_id = "content_".md5($data["url"]); if ($data["error"] == "") { $content = $url_info["host"]." 能正常打开"; echo " script update($content_id, $content) /script } else { $content = $url_info["host"]." 访问失败。具体错误原因:".$data["error"]; echo " script update($content_id, $content) /script //因为浏览器有缓冲,即获取数据后,不会马上渲染。当获取数据大于一个值时开始渲染。 echo str_repeat( ,1024); ob_flush(); flush(); if ($_GET["m"] == "slow") { sleep(1); $keyword = "一淘网"; $google_urls = array( http://www.google.com.br,//巴西 http://www.google.ch,//瑞士 http://www.google.nl,//荷兰 http://www.google.com.au,//澳大利亚 http://www.google.co.in,//印度 http://www.google.ro,//罗马尼亚 http://www.google.co.th,//泰国 http://www.google.com.sa,//沙特阿拉伯 http://www.google.co.jp,//日本 http://www.google.com.my,//马来西亚 http://www.google.ca,//加拿大 http://www.google.com.tw,//中国台湾 $google_num = 10;//从google网址中取几个 $keys = array_rand($google_urls,$google_num); $urls[] = "http://www.baidu.com/s?wd=".urlencode($keyword); $urls[] = "http://www.etao.com"; for ( $i = 0; $i $google_num; $i++) { $urls[] = $google_urls[$keys[$i]]."/search?sclient=psy-ab hl=en site= source=hp q=".urlencode($keyword); //生成占位div foreach($urls as $url){ echo " div id=content_".md5($url)." {$url} 检测中 /div //除了浏览器web服务器可能也会缓冲,如nginx的fastcgi_buffers。 echo str_repeat( ,1024); ob_end_flush(); ob_flush(); flush(); //开始获取搜索数据 $start = microtime(true); curl($urls, "deal"); $cost_time = microtime(true) - $start; echo " script update(cost_time, 耗时{$cost_time}秒 a href=\?m=slow\ 查看慢动作 /a ) /script /div /body /html
相关文章
- 【说站】php中__isset方法的使用
- jQuery + Php 文章页内容批注评论功能实现
- mac下使用brew配置nginx+php+mysql+PostgreSQL
- [Linux] PHP程序员玩转Linux系列-怎么安装使用详解编程语言
- PHP与MySQL数据库结合优势明显(phpmysql优点)
- 器使用Linux快速启动PHP服务器(linux启动php服务)
- 从MySQL到PHP:展示表格数据(php显示mysql表)
- PHP中的MySQL转义码简介(php转义mysql)
- PHP如何关闭MySQL数据库连接(php关闭mysql连接)
- PHP和Redis的默契合作:探究性能优化(phpredis性能)
- 安装Linux实现一键安装PHP环境(linux一键php)
- PHP与MSSQL联手谱写新篇章(php大马 mssql)
- PHP实现MSSQL数据库分页功能(php分页类 mssql)
- PHP与MSSQL联合 处理日期数据(php mssql 日期)
- PHP与MySQL的更新:让Web应用更稳定!(php mysql 更新)
- PHP实现稳定支持Redis的精彩瞬间(让php支持redis)
- php访问查询mysql数据的三种方法
- php学习之流程控制实现代码
- php获取服务器信息的实现代码
- 探讨php中遍历二维数组的几种方法详解
- php将mysql数据库整库导出生成sql文件的具体实现
- php中替换字符串中的空格为逗号','的方法
- php魔术方法详解
- PHP计算百度地图两个GPS坐标之间距离的方法