在解释之前,我如何检查包含的文件中没有设置哪些变量,或者我应该这样做吗?
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
在过去的几个小时里,我一直在谷歌上搜索,试图弄清楚如何做到这一点。我只是想明确我的问题是 不是 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