我正在努力使自己的大脑围绕缓冲,但是我无法在此站点上找到任何适合我的示例。也不来自php.org。
这就是我正在使用的
ini_set( "output_buffering", "on");
header( 'Content-type: text/html; charset=utf-8' );
$x = 1;
ob_implicit_flush(true);
while ($x < 10) {
ob_end_clean();
ob_start();
echo $x." asdfasdfasdfasdf <br />";
flush();
ob_flush();
sleep(1);
++$x;
}
现在,脚本仅在脚本完成运行后立即将整个脚本打印出来。我已经修改了php.ini文件,并手动打开了输出缓冲,但无济于事。有人可以告诉我我在做什么错吗?
答案 0 :(得分:0)
为了支持我的评论-“我能想到的最近似...”,我整理了一个演示,演示了使用EventStream
的意思-可能比所需的更为复杂但是在询问问题时无法使用输出缓冲。
如果您要复制此文件并创建一个新的php文件,请保存并运行,您应该会看到输出发生的情况。
<?php
if( !empty( $_GET['evtstream'] ) && $_GET['evtstream']==true ){
ob_clean();
set_time_limit( 0 );
ob_end_clean();
function sse( $evtname='evt', $data=null, $retry=1000 ){
if( !is_null( $data ) ){
echo "event:".$evtname."\r\n";
echo "retry:".$retry."\r\n";
echo "data:" . json_encode( $data, JSON_FORCE_OBJECT );
echo "\r\n\r\n";
}
}
header('Access-Control-Allow-Methods: GET');
header('Content-Type: text/event-stream');
$i=1;
$evt=!empty( $_GET['evt'] ) ? $_GET['evt'] : 'tick';
$count=!empty( $_GET['count'] ) ? $_GET['count'] : 10;
while( true ){
if( $i > $count ) break;
/* send some data back for the SSE listener to process */
$payload=array(
'date' => date( DATE_ATOM ),
'count' => $i,
'event' => $evt,
'calculation' => ( rand( 10,999 ) * rand( 300, 5999 ) ) / rand( 0.25, 25 ) #some random task performed by php...
);
call_user_func( 'sse', $evt, $payload );
if( @ob_get_level() > 0 ) for( $i=0; $i < @ob_get_level(); $i++ ) @ob_flush();
@flush();
sleep( 1 );
$i++;
}
/*
Now that the event loop has completed the 10 iterations we
need to prevent the eventsource from re-establishing itself
*/
header('Content-Type: text/html');
header('HTTP/1.1 404 Not Found', true, 404 );
echo 'goodbye';
ob_end_clean();
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Output Buffering: Server Sent Events</title>
</head>
<body>
<h1>Output buffering experiments</h1>
<div></div>
<script>
const EVENT_NAME='ticker';
const MAX_ITERATIONS=10;
let evtsource = new EventSource( location.href + '?evtstream=true&evt='+EVENT_NAME+'&ts=' + ( new Date().getTime() )+'&count='+MAX_ITERATIONS );
let oDiv=document.querySelector( 'div' );
const create=function(data){
let node=document.createElement('div');
node.innerText=data;
return node;
};
const callback=function(e){
let json=JSON.parse( e.data );
let content=Object.keys( json ).map( k => {
return [k,json[k]].join('=')
}).join('&')
oDiv.append( create( content ) );
};
const errorhandler=function(e){
evtsource.close();
oDiv.append( create( 'Terminated' ) );
};
evtsource.addEventListener( EVENT_NAME, callback, false );
evtsource.addEventListener( 'error', errorhandler,false );
</script>
</body>
</html>
否则,您可以看一下output buffering
的另一种用法的示例-您将看到html具有由输出缓冲区回调修改的标头(banana ...)-这种修改如果没有输出缓冲,就不能在实时文档上使用DOMDocument。
<?php
error_reporting( E_ALL );
function callback( $buffer ){
if( !empty( $buffer ) ){
$dom=new DOMDocument;
$dom->loadHTML( $buffer );
$h1 = $dom->getElementsByTagName('h1')->item(0);
$h1->nodeValue='A giraffe is a large mammal from Africa';
return $dom->saveHTML();
}
}
ob_start( 'callback' );
ob_implicit_flush(1);
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Output Buffering Example</title>
</head>
<body>
<h1>Bananas are curvy yellow fruit</h1>
</body>
</html>