现在,在你跳过如何不应该混合范围之前:我意识到这一点。但是,这种情况下必须进行范围混合或必须发生主要代码重复 - 周围没有任何内容。而且我更喜欢范围混合。
那就是说,我想要这段代码:
function a() {
$a = "a";
$b = "b";
$c = "c";
}
function b() {
a();
echo $a . $b . $c;
}
b(); // Output: abc
echo $a; // Should raise a notice that $a is undefined
能够作为评论工作。我知道在大多数语言中都不可能 - 我能用Ruby做到这一点;并且想知道你是否可以用PHP做到这一点。
在实际情况下,事先不知道变量的名称。
再一次,这是代码重复或者这个 - 绝对没办法。
此外,如果a
必须是a('b')
之类的东西,那也没关系。
实际上,代码是这样的:
static function renderError($what, $vararray) {
foreach($vararray as $key => $val) { /* this foreach is the code we want to decouple */
$key = 'e_'.$key;
$$key = htmlspecialchars($val);
}
ob_clean();
exit(eval('?>'.file_get_contents(ROOT."/templates/$what.php")));
}
通过E_Render::renderError('NotFound', array( 'requested_url' => '/notfound', 'misspelling' => '/reallynotfound' ));
然后,在templates / NotFound.php中,你会有类似的东西:
<html>
<body>
<?php echo $e_requested_url; ?> could not be found. Did you mean <?php echo $e_misspelling: ?>?
</body>
</html>
我们真的不希望我们的模板作者做更多的事情......如果没有更好的可用,$e['requested_url']
就可以完成。
答案 0 :(得分:6)
这就是为什么我们有OO:
class Foo {
function a() {
$this->a = "a";
$this->b = "b";
$this->c = "c";
}
function b() {
$this->a();
echo $this->a . $this->b . $this->c;
}
}
$f = new Foo;
$f->b(); // Output: abc
echo $a; // Should raise a notice that $a is undefined
可替换地:
function a() {
$a = "a";
$b = "b";
$c = "c";
return compact('a', 'b', 'c');
}
function b() {
extract(a());
echo $a . $b . $c;
}
否则,如果不彻底改变语言,我就没有办法做到这一点。
PS:如果您认为此功能如此重要,为什么不使用Ruby?
答案 1 :(得分:1)
鉴于你施加的限制,没有办法做你所要求的。完全没有理由去做你想做的事情。有很多更好的解决方案。
无论如何,你得到的最接近的是参考:
<?php
function a(&$a, &$b, &$c)
{
$a = 1;
$b = 2;
$c = 3;
}
function b()
{
a($a, $b, $c);
}
?>
答案 2 :(得分:1)
我刚刚运行了这段代码
- var1.php
<?php
function a($vars) {
foreach ($vars as $var => $val) {
$$var = $val;
}
echo eval('?>' . file_get_contents('var2.php') . '<?php ');
};
a(array('a' => 'foo', 'b' => 'bar', 'c' => 'baz'));
- var2.php
<html>
<body>
<div><?= '$a = "' . $a . '"' ?></div>
<div><?= '$b = "' . $b . '"' ?></div>
<div><?= '$c = "' . $c . '"' ?></div>
</body>
</html>
它输出:
$a = "foo"
$b = "bar"
$c = "baz"
原因是,由于eval()
保持当前范围,因此在函数内部本地声明的任何变量也将在eval'ed字符串内部可用。 $ this也一样。
** 更新 **
由于eval()
是 evil 并且应该避免(如同所建议的),这里是使用简单模板重写。这样,您的设计师只需知道可用的变量名称(在规范中):
- var1.php
<?php
function showError($error, $vars) {
$template = file_get_contents("{$error}.php");
$keys = array();
$values = array();
foreach ($vars as $var => $val) {
$keys[] = '@{e_'.$var.'}';
$values[] = $val;
}
echo str_replace($keys, $values, $template);
};
showError('template1', array('value' => 300, 'message' => 'Something foo'));
- template1.php
<html>
<body>
<div>Error <span style="font-weight: bold; color: red;">@{e_value}</span></div>
<div>The message was : <em>@{e_message}</em></div>
</body>
</html>
答案 3 :(得分:0)
为什么你不能从()返回$ a?
function a() {
$a = "a";
return $a;
}
function b() {
$a = a();
echo $a;
}
b(); // Output: a
echo $a; // Should raise a notice that $a is undefined
这不会打破范围。
答案 4 :(得分:0)
我不明白为什么你不能把它们作为数组返回。除了@NullUserException给你的建议,我建议采用以下方法(如果你不采用OOP路线)。
function a() {
$a = "a";
$b = "b";
$c = "c";
return array($a, $b, $c);
}
function b() {
list($a, $b, $c) = a();
echo $a . $b . $c;
}