发生错误时如何防止ob_start()输出?

时间:2013-02-14 13:52:33

标签: php buffer

请考虑以下示例:

的template.php:

<?php

echo $vars['arr'];

echo " -------- ";

echo $vars['obj'];

?>

test.php的:

<?php
$file = "template.php";
$vars = array( 'arr' => array(), 'obj' => new StdClass() );  

var_dump( json_encode($vars)  );  

function loadFile($file, $vars)
{
    try 
    {
        if (is_array($vars) && !empty($vars)) {
            extract($vars);
        }

        ob_start();
        include $file;
        return ob_get_clean();
    } 
    catch (Exception $e) 
    {
        return false;
    }
}

loadFile($file, $vars);

?>

此代码将输出:

string(19) "{"arr":[],"obj":{}}"
PHP Catchable fatal error:  Object of class stdClass could not be converted to string in template.php

这里的问题是,在template.php中我认为$ vars是一个数组()但是其中一个元素是一个对象,你可以从json输出中看到。

在模板中添加一个简单的检查以验证ekement是否是一个数组将解决问题,但是我需要这个到多个元素,元素,所以,不是很好=)所以,我试图找到一种在绑定模板和$ vars时防止错误的方法。

谢谢

4 个答案:

答案 0 :(得分:2)

解析时只需关闭error_reporting:

$old_level = error_reporting(0); // no errors, preserve old error reporting level
ob_start();
include $file;
$content = ob_get_clean();
error_reporting($old_level); // reset error reporting level
return $content;

注意:这只会隐藏不是非常关键的错误。

为了捕获 Catchable致命错误,请参阅此问题:How can I catch a "catchable fatal error" on PHP type hinting?

您需要使用set_error_handler注册错误处理程序:

function handleError($errno, $errstr, $errfile, $errline) {
  // handle error

  // return true, so the normal php handler doesn't get called
  return true;
}
set_error_handler('handleError');

如果要将处理程序干净地集成到也设置error_handler的其他代码中,您可以考虑使用restore_error_handler

之后恢复错误处理程序

答案 1 :(得分:0)

您可以先尝试检查值是否为对象,然后使用PHP函数转换为数组。

注意,代码的这一部分:

if (is_array($vars) && !empty($vars)) {
    extract($vars);
}

在那之后,如果我正确地读取你的代码,你有一个可能被称为$ vars的变量,它可能是一个对象。所以,你可以这样做:

if (is_object($vars)) {
    $vars = get_object_vars($vars);
}

那应该把它转换成你需要的。当然,您可能需要进行一些实验以确保它适合您的场景。谢谢!

答案 2 :(得分:0)

您可以在类中使用__toString()方法来避免错误。您可以使用您需要的任何值设置__toString()方法,也可以返回一个数组。 http://www.php.net/manual/en/language.oop5.magic.php#object.tostring

另一个选择是使用array_walk:

function checkObj(&$vars){ 
if (is_object($vars)) {
    $vars = get_object_vars($vars);
}
} 
array_walk($vars, "checkObj"); 

答案 3 :(得分:0)

由于您使用的是ob_start(),因此您可以向其传递一个将检查是否存在任何错误的回调。它甚至应该与致命错误一起使用。在你的回调中使用类似“error_get_last”的东西来检查任何错误,如果它不是null则返回false,如下所示:

警告:我没有测试过这段代码,但我自己也使用类似的东西。

<?php
    $file = "template.php";
    $vars = array( 'arr' => array(), 'obj' => new StdClass() );

    var_dump( json_encode($vars)  );

    function loadFile($file, $vars)
    {
        try
        {
            if (is_array($vars) && !empty($vars)) {
                extract($vars);
            }

            ob_start('errorHandler');
            include $file;
            return ob_get_clean();
        }
        catch (Exception $e)
        {
            return false;
        }
    }

    function errorHandler($pBuffer)
    {
        $lastError = error_get_last();
        // Uh-oh, an error has occurred.
        if ($lastError !== NULL)
        {
            return FALSE;
        }
        // No problems.
        return $pBuffer;
    }

    loadFile($file, $vars);

?>