2010-08-22 41 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