2009-06-16 42 views
5

我一直在PHP開發一段時間,而我還沒有一個任務,我不得不使用變量變量。任何人都可以給我例子,在哪裏使用它們是一個好主意?或者他們是否僅僅爲了娛樂而被包含在語言中?什麼時候在PHP中使用變量變量?

+1

我只是偶爾使用PHP ...什麼時候越過自己對這個heck是PHP中的一個「變量變量」? – 2009-06-16 20:14:16

+3

$ foo = 42; $ bar =「foo」; $$ bar ==> 42 – jrockway 2009-06-16 20:19:10

回答

5

我不得不使用它們的一種情況是URI處理,儘管這種技術可能過時了,並且我承認很久沒有使用它了。

比方說,我們想要以格式domain.tld/controller/action/parameter/s的格式從腳本中提取URI。我們可以使用下面的刪除腳本名稱:

$uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['REQUEST_URI']); 

要提取控制器,動作和參數,從這個我們將不得不使用爆炸的路徑分隔符「/」的字符串值。然而,如果我們開頭或結尾的分隔符,我們將不得不在爆炸空數組值,所以我們應該修剪那些從字符串的開頭和結尾:

$uri_string = trim($uri_string, '/'); 

現在,我們可以爆炸的路徑到一個數組:

$uri_data = explode('/', $uri_string); 

$uri_data[0]現在包含我們的控制器名稱,$uri_data[1]包括操作名稱,並在數組中值超出了是應該傳遞到操作方法參數。

$controller_name = $uri_data[0]; 
$action_name = $uri_data[1]; 

所以,現在我們有了這些名字,我們可以將它們用於許多事情。如果您將控制器保存在相對於站點根目錄的特定目錄中,則可以將此信息用於控制器類require_once。在這一點上,你可以實例,並使用可變的變量調用它:

$controller = new $controller_name(); 
$controller->{$action_name}(); // Or pass parameters if they exist 

有很多安全陷阱的看出來在這種方法中,但是這是我見過利用的一種方式變量變量。

免責聲明:我不是建議你真的使用這段代碼。

9

我通常在代碼味道不好的地方找到它們。也許引用一個靜態配置變量等......但爲什麼通常的關聯數組不是一個更好的解決方案。看起來像是一個等待發生的安全漏洞。

我想你可能能夠有效地在模板中使用它們。

7

千萬不要使用它們;一個「數組」總是一個更好的解決方案。

+1

+1是的 - *任何*數據結構是更好的方法 – Dario 2009-06-16 20:04:56

6

首先,如果您將用戶輸出用於這些目的,那麼這將是一個巨大的安全隱患。內部是這裏唯一有效的用法。

鑑於這一點,我想這是爲了像循環各種變量或發送變量作爲參數。

foreach($name in array('_GET','_POST','_REQUEST')) { 
    array_map('stripslashes',$$name); 
} 
+0

好的例子:) – 2009-06-16 21:34:37

0

除非你用多深度變量(如果你沒有做任何幻想,你將不再需要)的工作,你可能並不需要它們。即使那樣,你也許可以找到另一種方式來寫下同樣的東西,仍然可以得到相同的結果。雖然它可以縮短(並且在某些情況下甚至更容易理解),但我很高興它是該語言的一部分。

2

語言包括你不應該碰到的東西(我甚至在asked a question about it後面),這種情況並不少見,而變量變量可能屬於這個類別的構造之一。僅僅因爲一種語言包含一項功能並不意味着你必須使用它。

有些時候他們可以解決問題(畢竟遞歸在實踐中很少使用,但沒有人會認爲這不是一個基本的構造),但通常任何語言特性都會掩蓋您的代碼正在做什麼,並且可變變量明確地屬於這個範疇,應該極其謹慎。

0

我還沒有找到變量變量的許多用途,但使用變量的方法可以很方便,只要你在做什麼是明確的。例如,在一個簡單的REST服務,你可能會做這樣的事情:

$method = $request->getMethod(); // 'post','get','put','delete' 
try 
{ 
    $response = $resource->$method($request->getInput()); 
} 
catch (BadMethodException $badMethod) 
{ 
    $response = $responseFactory->getError($badMethod); 
} 

有人會說,你可以用switch聲明做同樣(你能),但這種方式適合於可擴展性(如果你決定添加另一種方法類型)並維護在資源上應用方法的抽象。

2

我已經找到了一個相當不錯的..

$php = "templates/php/default.php"; 
$html = "templates/html/default.php"; 
$css = "templates/css/default.php"; 
$js = "templates/js/default.php"; 

現在我問用戶說,他希望PHP或/和HTML的文件..

$userarray = array("php", "css"); 
foreach($userarray as $file){ 
    var_dump($$file); 
} 

輸出:

templates/php/default.php
templates/css/default.php

我試圖範圍靜態變量 self::$file;這樣的話,我記得我可以使用可變變量 self::$$file;將被解釋爲self::$php;

相關問題