2011-10-20 26 views
0

MVCフレームワークを作成しましたが、ob_start( 'error_handler')を使用しても致命的なエラーをキャッチすることができます。これは素晴らしい作品です! boot.phpでPHP ob_startが2回呼び出され、正しくフラッシュされません

// 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(); 

ERROR_LOGGING機能は:

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; 

} 

繰り返しますが、これはすべてのエラーを処理するのに結構な作品!私は、エラークラス内で何かフラッシュや何も使用しません。

ob_startを使用するコントローラは、特定のメソッドの実行時間がかなり長いため、ユーザーに何が起こっているのか、スクリプトが何をしているのかをフィードバックします。私はこれのためにob_flush()を使用しています。

ただし、このob_start( 'error_logging')を実装した後は、 ob_flushは機能していないようです。スクリプト全体が終了するまで待ちます(約8分かかります)。

なぜですか?コントローラ-方法で ::ログインで

$this->login->execute(); 

::実行します。

私は紅潮しています方法の例は、このようなものです

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; 

} 

それぞれの$ this - >デバッグ - > log()コールは、次のように出力をフラッシュします。

public function log($string) 
{ 

    if($this->active() || $this->logging()) 
    { 

     echo str_repeat("<!-- AGENT SMITH -->", 500); 
     echo $string; 

     ob_flush(); 
     flush(); 

    } 

} 

なぜそれが正しくフラッシュされないのでしょうか? もっとコードを表示する必要がある場合は教えてください!

おかげ

:::::::: SOLUTION ::::::::::

私は最初のバッファ(ERROR_LOGGING)を保存し、それを終了し、新しいを開始しなければなりませんでした1つ、私のものをして、それを終了し、最初のバッファを再び開始し、保存された出力をエコーし​​ます。

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); 

    } 

} 

使用法:

boot.php

// 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'); 

ログイン::実行():

public function execute($site = 'mobile') 
{ 

    Buffer::getInstance()->start_separate(); 

    // Everything in between 

    Buffer::getInstance()->end_separate(); 

    // Return $this 
    return $this; 

} 
完璧に動作

はそれのためのクラスをやりました! ob_startのいくつかのネストされたob_startをサポートしません。なぜなら、以前の出力を1つしか保存しないからです。しかし、今は必要ではないが修正することができます!

答えて

4

私はそれがネストされたob_start()呼び出しと関係があると推測しています。私はそれらを入れ子にしておきたいと思っていますが、​​関数の中で、次の出力バッファを開始する前に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; 
} 
+0

ハハ!とてもうまく働いた:Dはメインポストを解決して解決するだろう!どうもありがとうございます! – Tanax

関連する問題