在解释之前,我如何检查包含的文件中没有设置哪些变量,或者我应该这样做吗?

How can I check which variables aren't set in an included file, prior to interpretation, or should I?

在过去的几个小时里,我一直在谷歌上搜索,试图弄清楚如何做到这一点。我只是想明确我的问题是 不是 this issue or that issue,因为我不想检查 inside被设置。我正在尝试检查外部,看看它们是否在被解释之前设置/传递给包含的文件,或者至少有意义地解释到抛出错误的程度。让我解释一下。

一些背景知识

我正在为我工​​作的公司创建一个供内部使用的实用程序包。我选择了两种方式之一呈现模板:包括它们或输出呈现的字符串。

public function render($context = array()) {
    do_action(self::TAG_CLASS_NAME.'_render_view', $this, $context);
    if ( empty( $this->html ) ) {

        ob_start();
        $this->checkContext($context);
        extract( $context );
        require_once $this->getFullPath();
        $renderedView = ob_get_contents();

        ob_end_clean();

        $this->html = $renderedView;

        return $renderedView;
    } else {
        return $this->html;
    }
}

public function includeView($context = array()) {
    do_action(self::TAG_CLASS_NAME.'_include_view', $this, $context);
    extract( $context );
    include $this->getFullPath();
}

问题

render 方法内部,我开始了一些输出缓冲。这样我就可以让解释器评估代码并将 HTML 作为字符串输出(不接受 eval() 命中。在我的单元测试中,我尝试了如果我遗漏 context 是在模板内部。例如:如果我有一个 context 数组,它看起来像:

$context = array(
    'message' => 'Morning'
);

以及如下所示的关联模板:

<?php echo "Hello ".$name."! Good ".$message; ?>

或者这个

<p>Hello <?php echo $name; ?>! Good <?php echo $message; ?></p>

格式如何无关紧要,只要 context 变量正确传递给它即可。无论如何,在 context 中遗漏 $name 将导致 "Undefined variable: $name" E_NOTICE 消息。这是有道理的。 你如何 'capture' 在创建通知之前未定义的变量?

我试过使用:

$rh = fopen($this->getFullPath(), 'r');
$contents = fread($rh, filesize($this->getFullPath()));
fclose($rh);

其中 $contents 输出:

"<?php echo sprintf("Hello %s, Good %s.", $name, $greeting); ?>"

下一个合乎逻辑的步骤(无论如何对我来说,因此是问题)是提取该字符串中的变量。因此,我简要地开始了创建正则表达式以匹配该字符串并捕获变量的道路,但最终还是到了这里,因为我觉得我在重复工作。我的意思是,PHP 解释器已经有效地做到了这一点,因此必须有一种方法来利用内置功能。也许?

说了这么多,我想做一些类似于这个伪代码的事情:

protected function checkContext($context) {
    require $filename;
    $availVars = get_defined_vars()
    if ( $availVars !== $context ) {
        setUnDefinedVar = null
    }
}

话虽如此,这甚至可能不是正确的方法,但什么才是呢?我是否让解释器在包含文件时因未定义的变量而失败?如果我让它失败,我是否会将自己暴露在任何安全漏洞之下? 注意: 我没有通过 $_GET$_POST.

在模板中设置任何变量

非常感谢任何答案。提前谢谢你。

我建议在 class 中使用 getter 和 setter。可能有更好的解决方案,但这就是我的做法。由于您正在尝试访问全局范围内的变量,因此您可以将以下方法添加到调用包含文件的 class 中:

public function __get($variable)
{
    if (array_key_exists( $variable, $GLOBALS ))
        return $GLOBALS[$variable];

    return null;
}

所以现在在包含的文件中,您可以使用

访问变量

$this->{$variableName}

在您的具体情况下,它看起来像...

<?php echo "Hello ".$this->name."! Good ".$this->message; ?>

但是请注意,如果请求的变量是在调用 class 的范围内定义的,那么将返回该特定的成员变量。没有在全局范围内定义。

可以在此处找到关于此重载运算符的更好解释 PHP Magic Methods