【问题标题】:ob_start gets interrupted when error occur发生错误时 ob_start 被中断
【发布时间】:2013-07-12 06:40:31
【问题描述】:

所以ob_start() 应该捕获输出,直到另一个缓冲区函数被调用,如ob_get_clean()ob_get_contents()ob_get_flush()

但是当缓冲区读取器内部抛出异常时,它将通过停止读取器并回显输出而不是继续捕获它来影响读取器。这是我要防止的。

假设这是我的脚本:

<?php
    error_reporting(0);
    try {
        ob_start();
            echo "I don't wanna output this what so ever, so want to cache it in a variable with using ob_ functions";
            $unlink = unlink('some file that does not exist');
            if(!$unlink) throw new Exception('Something really bad happen.', E_ERROR); //throwing this exception will effect the buffer
        $output = ob_get_clean();
    } catch(Exception $e) {
        echo "<br />Some error occured: " . $e->getMessage();
        //print_r($e);
    }
?>

此脚本将输出:

I don't wanna output this what so ever, so want to cache it in a variable with using ob_ functions
Some error occurred: Something really bad happen.

当它假设只是打印时

Some error occurred: Something really bad happen.

我做错了什么,有解决办法吗?

【问题讨论】:

  • 尝试将ob_start()移出try...catch块。
  • @vinodadhikary 感谢您的评论,这可能有效,但也会导致错误消息被缓冲。我不希望这种情况发生。

标签: php buffer


【解决方案1】:

我的猜测是,即使在您的 catch 块内,输出缓冲仍然处于活动状态。但是,脚本以活动输出缓冲结束,因此 PHP 会自动显示输​​出缓冲区。

因此您可以尝试在异常处理程序中调用ob_clean()

【讨论】:

  • 你完全正确,我不敢相信我没有想到这一点!非常感谢。
【解决方案2】:

你可以这样做:

<?php
    error_reporting(0);
    $currentBuffers = '';
    try {
        ob_start();
        echo "I don't wanna output this what so ever, so want to cache it in a variable with using ob_ functions";
        $unlink = unlink('some file that does not exist');
        if(!$unlink) throw new Exception('Something really bad happen.', E_ERROR); //throwing this exception will effect the buffer
        $output = ob_get_clean();
    } catch(Exception $e) {
        $currentBuffers = ob_get_clean();
        ob_end_clean(); // Let's end and clear ob...
        echo "<br />Some error occured: " . $e->getMessage();
        //print_r($e);
    }

    // Do something to $currentBuffer

    // Maybe start again?
    ob_start();
    echo "foo";
    $currentBuffers .= ob_get_clean();
    //echo $currentBuffers;
        ob_end_clean();
?>

【讨论】:

    【解决方案3】:

    我知道这是一个老问题,但我想为将来偶然发现它的人付出两分钱。

    我遇到的问题是,尽管捕获了异常,但缓存没有被清除。还是打印出来了。

    对我来说,解决方案是添加一个额外的 catch 块来捕捉 throwable:

    try
    {
        ob_start();
            // some stuff
        ob_end_clean(); // or any other function
    }
    catch (\Throwable $e)
    {
        ob_end_clean();
        throw new \Exception($e->getMessage());
    } 
    catch (\Exception $e)
    {
        ob_end_clean();
        throw $e;
    }
    

    由于异常是可抛出的,所以第二个 catch 块不是强制性的,但我添加了它以确保

    【讨论】:

      猜你喜欢
      • 2013-01-30
      • 2022-01-20
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      • 2015-04-21
      • 2017-05-23
      • 1970-01-01
      • 2018-11-04
      相关资源
      最近更新 更多