0

请考虑以下示例:

模板.php:

<?php

echo $vars['arr'];

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

echo $vars['obj'];

?>

测试.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 是一个 array() 但是其中 1 个元素是一个 Object,正如您从 json 输出中看到的那样。

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

谢谢

4

4 回答 4

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;

注意:这只会隐藏不是很严重的错误。

为了捕获可捕获的致命错误,请参阅以下问题:如何在 PHP 类型提示中捕获“可捕获的致命错误”?

您需要使用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_handlers 的其他代码中,您可以考虑使用restore_error_handler恢复错误处理程序

于 2013-02-14T14:03:28.250 回答
0

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

请注意,这部分代码:

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

之后,如果我正确阅读了您的代码,您就有一个可能称为 $vars 的变量,它可能是一个对象。所以,你可以这样做:

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

那应该将其转换为您需要的。当然,您可能需要进行一些试验以确保它适合您的场景。谢谢!

于 2013-02-14T14:31:42.433 回答
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"); 
于 2013-02-14T20:18:16.457 回答
0

由于您使用的是 ob_start(),因此您可以向它传递一个回调来检查任何错误。它甚至可以处理致命错误。在你的回调中使用类似“error_get_last”的东西来检查任何错误,如果它不为空,则返回 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);

?>
于 2013-04-11T03:47:46.840 回答