2010-08-22 29 views
2

现在,在跳转之前,您应该如何不应混合范围:我意识到这一点。但是,这是一种情况,即必须发生范围混合或必须发生主要代码重复 - 周围没有任何东西。我更喜欢范围混合。在PHP中导出变量到以前的范围

这么说,我想这样的代码:

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'));通话

然后,在模板/ NotFound.php,你会碰到这样的:

<html> 
<body> 
<?php echo $e_requested_url; ?> could not be found. Did you mean <?php echo $e_misspelling: ?>? 
</body> 
</html> 

我们真的不想让我们的模板作者做更多的事情......虽然如果没有更好的可用的话,可以完成。

回答

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; 
} 

见:compact()extract()

否则我看不出这样做的方式没有显着改变语言。 PS:如果你觉得这个功能如此重要,那你为什么不用Ruby呢?

+0

保留变量名$ a,$ b,$ c是至关重要的。好吧。 – 2010-08-22 00:54:13

+0

+1你先知道了。您没有声明$ a,$ band $ c作为班级成员? – NAVEED 2010-08-22 00:54:43

+0

@NAVEED不需要。 PHP可以在运行时添加类成员 – NullUserException 2010-08-22 00:58:02

0

为什么不能从a返回$ 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 

这不会破坏范围。

+0

查看编辑的问题。我需要能够声明多个变量,并让它们不在数组中。另外,在实际情况下,我不会知道变量的名称。 – 2010-08-22 00:50:25

+0

好的,你能解释一下)为什么它不能是一个数组,因为你可以返回一个数组,实际上$ a和$ array ['a']之间有什么区别,b)给你的问题提供更多的上下文,因为我还没有看到一个理由范围必须被打破。 – 2010-08-22 00:53:28

+0

如果您事先不知道变量名称,您会如何知道在b()中使用什么?请再次提出问题的更多背景 – 2010-08-22 00:55:40

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; 
} 
1

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

无论如何,你会得到最接近的是通过引用传递:

<?php 
function a(&$a, &$b, &$c) 
{ 
    $a = 1; 
    $b = 2; 
    $c = 3; 
} 

function b() 
{ 
    a($a, $b, $c); 
} 
?> 
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字符串内。与此同样的事情。

** UPDATE **

由于eval(),应避免使用(如好心建议),这是一个使用简单的模板重写。这样一来,你的设计师只需要知道可用的变量名称(规格):

- 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> 
+0

-1用于提示'eval()'和短标签。 – NullUserException 2010-08-22 01:27:42

+0

...没问题,关于评估的公平性。至于短标签,这是你的意见。我正在更新答案,因此根本没有eval()。快乐? – 2010-08-22 01:31:12

+1

短标签是一场噩梦。许多服务器都将它们禁用并让人们无能为力,导致像[this]这样的问题(http://stackoverflow.com/questions/2476072/tags-not-working-in-php-5-3-1)和[this] (http://stackoverflow.com/questions/2476072/tags-not-working-in-php-5-3-1)。而且它们也不符合标准。这是一个愚蠢的“功能”,不应该首先添加。 – NullUserException 2010-08-22 01:38:06