我剛剛剛介紹了PHP中動態變量的概念。對我來說,似乎在程序中使用動態變量會使其難以閱讀/遵循。爲什麼在PHP或其他語言中使用動態變量(變量變量)
任何人都可以向我解釋的好處和/或分享一個真正簡單的現實世界的例子,當PHP中的動態變量可能需要?
如果你想知道什麼動態變量,以及它們是如何工作的檢查this question
我剛剛剛介紹了PHP中動態變量的概念。對我來說,似乎在程序中使用動態變量會使其難以閱讀/遵循。爲什麼在PHP或其他語言中使用動態變量(變量變量)
任何人都可以向我解釋的好處和/或分享一個真正簡單的現實世界的例子,當PHP中的動態變量可能需要?
如果你想知道什麼動態變量,以及它們是如何工作的檢查this question
我已經投票決定關閉這個問題,它是主觀的基礎上(投自縮回),但細想起來,我想我可以給出一個客觀的答案。
靜態變量名稱是一個字符序列,表示一個令牌,底層引擎將其用作標籤來標識該變量代表的值(非常非常規的描述)。
「字符序列」是一個字符串。 A 字符串是表示字符串的表達式。所以從這裏可以推斷,任何表示字符串的表達式都應該足以代表引用變量的標記。並且該表達式本身可以分配給一個變量,並從那裏獲得動態變量名稱。
但這不是你問的。你問:爲什麼?
這不是語言的實現者回答這樣的問題。他們的工作是通過他們的語言提供統一和可預測的編程接口。它是uniform能夠通過一個表達式來表示一個字符序列,而該表達式又可以用一個變量表示。任務完成。
主觀上,我可能會看到從外部源導入某些數據的位置,甚至數據的模式也是動態的。人們可能想用某種通用對象方式來表示它,並且從那裏引出對象的屬性名稱也可能是動態的。這對於解決這個問題是否是一個好的方法是完全主觀的,並且直接取決於開發者的判斷以及代碼審查期間他們的同行的判斷。
另一個例子可能是你繼承了一些「需求必須」和使用動態命名的粗糙的意大利麪條代碼 - 無論出於何種原因 - 可能是一個好方法。
PHP的負擔終止於提供編寫代碼的機制;它不會說代碼的設計質量。這就是代碼審查的目的。
好的答案!感謝您花時間解釋。你有一些偉大的觀點! – ScottyG
當/如果這個問題產生一個有趣的答案時,自動關閉問題有時候會更好。 –
A variable variable
,只是reflection的另一種形式。你基本上在問:「如果你在運行之前不知道,爲什麼要改變一個變量?」。
儘管技術上不盡相同,但您可以將variable variable
看作是另一種hash table
(或在PHP中爲array
)。大多數variable variables
可能會被重寫爲hash table
,您不會感到驚訝。但是如果你需要在運行前後使用變量,那麼hash table
甚至可能更難處理。
一個簡單的用例可能是用戶可以更改的設置。請記住,下面的例子是不安全的,但證明了它的目的。
<?php
/*
Simple way, if you have a limited amount of settings
*/
$settings = array();
$settings["allowAccess"] = 1;
$settings["allowModify"] = 1;
$settings["allowDelete"] = 0;
if ($result = $mysqli->query("SELECT `allowAccess`, `allowModify`, `allowDelete` FROM `user_settings` LIMIT 1"))
{
$row = $result->fetch_array(MYSQLI_ASSOC);
$settings["allowAccess"] = $row["allowAccess"];
$settings["allowModify"] = $row["allowModify"];
$settings["allowDelete"] = $row["allowDelete"];
}
/*
Now consider you have a thousand settings and you dont want to write out every setting manually.
*/
if ($result = $mysqli->query("SELECT * FROM `user_settings` LIMIT 1"))
{
$row = $result->fetch_array(MYSQLI_ASSOC);
foreach($row as $key => $val) {
$settings[$key] = $val;
}
}
/*
Both options work, but everytime you want to use a setting you have to use something like below
*/
if ($settings["allowAccess"] && $settings["allowModify"] && $settings["allowDelete"]) {
unlink($somefile);
}
/*
Perhaps you would rather write
*/
if ($allowAccess && $allowModify && $allowDelete) {
unlink($somefile);
}
/*
Then you can use
*/
if ($result = $mysqli->query("SELECT * FROM `user_settings` LIMIT 1"))
{
$row = $result->fetch_array(MYSQLI_ASSOC);
foreach($row as $key => $val) {
//if you use extract, all columns are extracted, unless you drop them first. But perhaps you need those for something else.
//now I extract the columns that start with allow and keep the columns like id, created, modified, etc. without the need to specify each column manually, which makes it easier if you ever decide to add another setting column. You don't need to update this part of the code.
if (substr($key,0,5)=='allow') {
$$key = $val; //$key = 'allowAccess', $$key == $allowAccess = $val;
}
}
}
?>
這只是一個例子,我發現在XHTML sanitizer for MediaWiki
另一個例如通過Brion Vibber
。他在自己的代碼中使用了很多數組,並且有一次他需要將所有數組全部翻轉。他使用下面的代碼:
<?php
$vars = array('htmlpairs', 'htmlsingle', 'htmlsingleonly', 'htmlnest', 'tabletags',
'htmllist', 'listtags', 'htmlsingleallowed', 'htmlelements');
foreach ($vars as $var) {
$$var = array_flip($$var);
}
?>
現在很明顯,他可以寫下面的代碼,但是真的更容易閱讀?
<?php
$htmlpairs = array_flip($htmlpairs);
$htmlsingle = array_flip($htmlsingle);
$htmlsingleonly = array_flip($htmlsingleonly);
$htmlnest = array_flip($htmlnest);
$tabletags = array_flip($tabletags);
$htmllist = array_flip($htmllist);
$listtags = array_flip($listtags);
$htmlsingleallowed = array_flip($htmlsingleallowed);
$htmlelements = array_flip($htmlelements);
?>
這也引入了另一個用例:如果我想動態地決定哪些數組要翻轉怎麼辦?在variable variable
的方式,我可以將項目推到陣列上,並在時間到來時將它們翻轉。以「正常」方式,我需要一個switch
或if
循環訪問陣列,然後手動添加每個選項。
有趣的例子。它引導我到另一個問題,但爲什麼會使用數組翻轉? – ScottyG
我在[此回答](https://stackoverflow.com/a/16521079/434949)中使用它來比較PHP中兩個字符串的部分相似性。基本上,如果數組包含某個值,則必須檢查很多次才使用它。通過翻轉一次,您就可以使用'array_key_exists'而不是不斷循環整個數組來查看它是否包含該值。但是,儘管這個例子使用'array_flip',你可以在想要做很多變量的時候使用'variable variables',或者當你想動態地分配你想要做的變量。 –
'foreach($ row as $ key => $ val){$$ var = array_flip($$ var); }'提取($ row)'更簡單? – symcbean
它們通常被稱爲變量變量;只是因爲它們存在,並不意味着你必須使用它們......通常我會建議不要使用它們,因爲總會有更好的替代方案 –
在我看來,它使得它難以閱讀/遵循。 –
基於很多問題,人們在這裏試圖弄清楚如何使用變量變量,他們通常應該命名數組鍵,而不是創建不同的變量。 –