首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将变量导出到PHP的前一个作用域

将变量导出到PHP的前一个作用域
EN

Stack Overflow用户
提问于 2010-08-22 00:46:10
回答 5查看 4.5K关注 0票数 3

现在,在讨论如何不混合作用域之前:我意识到了这一点。然而,在这种情况下,要么必须发生范围混合,要么必须发生主要的代码重复--而不是围绕在它周围。我更喜欢混合镜。

话虽如此,我想要这个代码:

代码语言:javascript
复制
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')之类的东西,那也是可以的。

实际上,守则是这样的:

代码语言:javascript
复制
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中,您将得到如下内容:

代码语言:javascript
复制
<html>
<body>
<?php echo $e_requested_url; ?> could not be found. Did you mean <?php echo $e_misspelling: ?>?
</body>
</html>

我们真的不希望我们的模板作者做比that...although $e['requested_url']更能做的事情,如果没有更好的东西可用的话。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-08-22 00:52:35

这就是为什么我们有OO:

代码语言:javascript
复制
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

另一种选择是:

代码语言:javascript
复制
function a() {
    $a = "a";
    $b = "b";
    $c = "c";

    return compact('a', 'b', 'c');
}

function b() {
    extract(a());
    echo $a . $b . $c;
}

见:compact()extract()

否则,我看不出在不彻底改变语言的情况下这样做的方法。

PS:如果你觉得这个特性很重要,为什么不直接使用Ruby呢?

票数 8
EN

Stack Overflow用户

发布于 2010-08-22 01:12:03

考虑到你施加的限制,没有办法去做你要求的事情。永远不会有一个很好的理由去做你想做的事情。有很多更好的解决方案。

不管怎么说,你能得到的最接近的就是引用:

代码语言:javascript
复制
<?php
function a(&$a, &$b, &$c)
{
  $a = 1;
  $b = 2;
  $c = 3;
}

function b()
{
  a($a, $b, $c);
}
?>
票数 1
EN

Stack Overflow用户

发布于 2010-08-22 01:26:16

我刚运行了这个代码

-- var1.php

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<html>
   <body>
      <div><?= '$a = "' . $a . '"' ?></div>
      <div><?= '$b = "' . $b . '"' ?></div>
      <div><?= '$c = "' . $c . '"' ?></div>
   </body>
</html>

它的产出是:

代码语言:javascript
复制
$a = "foo"
$b = "bar"
$c = "baz"

原因是,由于eval()保留了当前范围,在函数中在本地声明的任何变量也将在eval‘’ed字符串中本地可用。$this也是如此。

** 更新 **

由于eval()是邪恶的,应该避免(正如善意地建议的那样),这里有一个使用简单模板的重写。这样,设计人员只需知道可用的变量名(在规范中):

-- var1.php

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3539636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档