Tan*_*nax 1 php flush ob-start
我编写了一个 MVC 框架,并且使用 ob_start('error_handler') 来捕获致命错误。这太棒了!
在 boot.php 中
// Start the error-logging
ob_start( 'error_logging' );
// Run the request
Request::run( URL::getInstance()->init()->formatURL() );
// Flush and disable output-buffering
ob_end_flush();
Run Code Online (Sandbox Code Playgroud)
错误记录功能:
function error_logging( $output )
{
// Get the last error
$trace = error_get_last();
// Initialize our final array of fields explaining the error
$final = array();
// Check if the error does not exist, return the original output unedited
if( !isset( $trace ) ) return $output;
// Loop through or error and build our array
foreach( $trace as $info => $value ) $final[$info] = $value;
// Initialize our Error-class
$error = Error::factory();
// Handle the error with the fields and build our error-message
$newOutput = $error->handle( $final['type'] , $final['message'], $final['file'], $final['line'] );
// Check if the new output is null, if yes set output to the original output, otherwise set it to the new output
$output = ( $newOutput === null ) ? $output : $newOutput;
// Return the output
return $output;
}
Run Code Online (Sandbox Code Playgroud)
再说一遍,这可以很好地处理所有错误!我不使用任何刷新或错误类中的任何内容。
现在,我有一个使用 ob_start 的控制器,因为某种方法的运行时间相当长,我希望向用户反馈正在发生的情况以及脚本的作用。我为此使用 ob_flush() 。
但是,在实现 ob_start('error_logging'); 后 ob_flush 似乎不起作用。他们等到整个脚本完成(大约需要 8 分钟)。
为什么?
我如何冲洗的一个例子是这样的:在控制器方法中:
$this->login->execute();
Run Code Online (Sandbox Code Playgroud)
在登录::执行:
public function execute( $site = 'mobile' )
{
ob_start();
$this->debug->log('--------------------------------------------<br />');
$this->debug->log( 'Logging into site: ' . ucfirst( $site ) . '<br />' );
// Initiate cookies
if( $site == 'full' )
$this->_initCookies();
// Set up the URL
$url = Config::get( $site ) . Config::get( 'url_login' );
curl_setopt( $this->curl->get(), CURLOPT_URL, $url );
// CURL-values
curl_setopt( $this->curl->get(), CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt( $this->curl->get(), CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $this->curl->get(), CURLOPT_POST, 1 );
curl_setopt( $this->curl->get(), CURLOPT_POSTFIELDS, Config::get( 'postfields' ) );
curl_setopt( $this->curl->get(), CURLOPT_COOKIEFILE, 'resources/tmp/cookies.txt');
curl_setopt( $this->curl->get(), CURLOPT_CONNECTTIMEOUT, 10 );
curl_setopt( $this->curl->get(), CURLOPT_TIMEOUT, 40 );
curl_setopt( $this->curl->get(), CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.1) Gecko/20100101 Firefox/6.0.1');
// Get the page returned after we've logged in
$this->login_html = str_get_html( curl_exec( $this->curl->get() ) );
// Validate the page returned to see if we successfully logged in
$this->_validateLogin( $site );
$this->debug->log('--------------------------------------------<br />');
ob_end_flush();
// Return $this
return $this;
}
Run Code Online (Sandbox Code Playgroud)
每个 $this->debug->log() 调用都会刷新输出,如下所示:
public function log( $string )
{
if( $this->active() || $this->logging() )
{
echo str_repeat("<!-- AGENT SMITH -->", 500);
echo $string;
ob_flush();
flush();
}
}
Run Code Online (Sandbox Code Playgroud)
知道为什么它不能正确冲洗吗?如果您需要查看更多代码,请告诉我,我会提供!
谢谢
::::::::解决方案::::::::::
我必须保存第一个缓冲区(error_logging),结束它,启动新的缓冲区,做我的事情,然后结束那个缓冲区,再次启动第一个缓冲区并回显保存的输出。
为它开了一堂课:
class Tanaxia_Buffer
{
public static $instance = null;
private $main = null;
private $previousOutput = "";
public static function getInstance()
{
if( Buffer::$instance === null )
Buffer::$instance = new Buffer();
return Buffer::$instance;
}
public function set_main( $ob )
{
$this->main = $ob;
}
public function start( $main = null )
{
if( $main !== null )
$this->set_main( $main );
ob_start( $this->main );
}
public function end( $type = 'clean' )
{
switch( $type )
{
case 'flush': ob_end_flush(); break;
case 'clean': ob_end_clean(); break;
}
}
public function start_separate()
{
$this->previousOutput = ob_get_contents();
ob_end_clean();
ob_start();
}
public function end_separate( $type = 'flush' )
{
switch( $type )
{
case 'flush': ob_end_flush(); break;
case 'clean': ob_end_clean(); break;
}
ob_start( $this->main );
echo $this->previousOutput;
empty( $this->previousOutput );
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
启动文件
// Start the error-logging
Buffer::getInstance()->start( 'error_logging' );
// Run the request
Request::run( URL::getInstance()->init()->formatURL() );
// Flush and disable output-buffering
Buffer::getInstance()->end( 'flush' );
Run Code Online (Sandbox Code Playgroud)
登录::执行():
public function execute( $site = 'mobile' )
{
Buffer::getInstance()->start_separate();
// Everything in between
Buffer::getInstance()->end_separate();
// Return $this
return $this;
}
Run Code Online (Sandbox Code Playgroud)
完美运作!但不支持多个嵌套的 ob_start,因为它只保存 1 个先前的输出。虽然可以修复,但现在没有必要!
我猜测这与嵌套调用有关ob_start()。我假设您想让它们保持嵌套,但是如果在您的execute()函数中您调用ob_end_flush()或ob_end_clean()在启动下一个输出缓冲区之前,它是否会按照您想要的方式刷新?像这样的东西:
public function execute( $site = 'mobile' )
{
// save existing contents of output buffer
$previousOutput = ob_get_contents();
// wipe the output buffer itself
ob_end_clean();
// start a new output buffer
ob_start();
/* SNIP all the code that wouldn't change */
// flush the function's output buffer
ob_end_flush();
// restart the old output buffer
ob_start("error_logging");
// take whatever was in the old buffer and make sure it shows up in the new one
echo $previousOutput;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4454 次 |
| 最近记录: |