2012-01-03 78 views
0

有一天,我被賦予了這個龐大的數組集合,並被告知用一堆或選擇/單選按鈕創建一個HTML頁面,所以我寫了一些簡單的函數來簡化事情。在簡單的PHP函數中使用變量

這是我的函數來生成非常大的HTML選擇。

function genSelect($name) { 
    $selectReturn = '<select name="'.$name.'">'; 
     foreach(${$name} as $value=>$text){ 
      $selectReturn .= '<option value="'.$value.'"'; 
      if($evalThis->loaded_settings[$name]['value']==$value) 
       $selectReturn .= ' SELECTED '; 
      $selectReturn .= '>'.$text.'</option>'; 
     } 
    $selectReturn .= '</select>'; 
return $selectReturn; 
} 

這似乎並沒有工作,因爲${$name}只是像我期望它太不叫什麼/工作。我已經在我通過函數調用傳遞數組的地方工作,但它一直在竊聽我在做這個代碼中的變量變量時做了什麼錯誤。

編輯:爲了給一些上下文,這是在joomla視圖中加載構建巨大的用戶界面進入設置。這個函數在一個lib文件中,並且與另一個包含我使用的所有數組的文件一起被裝入一個require_once。數據庫僅保存這些設置的當前值,並且數組包含各種選擇/無線電/下拉菜單的所有可能選項,並且由於語言/翻譯原因而被集中在單獨的文件中。

澄清人們詢問的一些問題,$name只包含所用數組的名稱以及HTML選擇/收音機/複選框輸入的名稱。 $evalThis是包含數據庫當前擁有的值的數組。

+0

你能舉一個例子,說明$ name中的數據是什麼樣的? – FlipMcF 2012-01-03 22:35:53

+1

我只是問:'$ evalThis'做了什麼?這聽起來有點「邪惡」。 – PeeHaa 2012-01-03 22:38:25

+0

試試這個:'$ evalThis = new stdClass(); $ evalThis-> loaded_settings = array('abc'=> array('value'=> 1));' – 2012-01-03 22:49:05

回答

1

它看起來像一個存儲在$ name中的名稱的數組在全局上下文中定義,而不是在此函數中定義。

$somearr = array('x', 'y'); 
function genSelect($name) { 
    $selectReturn = '<select name="'.$name.'">'; 

    foreach(${$name} as $value=>$text){ 
     $selectReturn .= '<option value="'.$value.'"'; 
     if($evalThis->loaded_settings[$name]['value']==$value) 
      $selectReturn .= ' SELECTED '; 
     $selectReturn .= '>'.$text.'</option>'; 
    } 

    $selectReturn .= '</select>'; 
    return $selectReturn; 
} 
echo genSelect('somearr'); //doesnt work, somearr is global 


$somearr = array('x', 'y'); 
function genSelect($name) { 
    global $somearr; 
    $selectReturn = '<select name="'.$name.'">'; 

    foreach(${$name} as $value=>$text){ 
     $selectReturn .= '<option value="'.$value.'"'; 
     if($evalThis->loaded_settings[$name]['value']==$value) 
      $selectReturn .= ' SELECTED '; 
     $selectReturn .= '>'.$text.'</option>'; 
    } 

    $selectReturn .= '</select>'; 
    return $selectReturn; 
} 
echo genSelect('somearr'); //works, note 'global $somearr' line at the beginning of genSelect 

一般來說,當不需要/至少證明對齊時,使用函數/數組的變量名是非常糟糕的設計。如果我是你,我只想重寫方法

function genSelect($array, $name) { ... } 

echo genSelect($someArr, 'someArr'); 

它可能看起來像typying的重複,但最好不要有你的方法依賴於全球範圍。 順便說一句,你的$ evalThis var也超出了函數範圍。

+2

使用[PHP DOM](http://php.net/manual/en/book.dom.php )用PHP創建HTML! – noob 2012-01-03 22:38:08

+0

原諒我,如果這是一個愚蠢的問題,我還是PHP新手。 如果將加載包含所有數組的文件的require_once從其當前位置移入函數內,直​​接位於加載包含此函數的文件的「require_once」之上,那麼這意味着'$ {$ name} ? – Spunkie 2012-01-04 02:07:37

+0

我不確定你指的是哪個代碼,但是如果你在函數內部做了'require_once',那麼包含文件中具有'全局'作用域的任何東西都會在函數範圍內。不建議儘管包含在一個函數中;而是包含函數並在需要時調用它們。還要注意,即使在不同的作用域中,require_once(或者include_once)也不會做任何事情,如果之前已經包含了相同的文件。 – 2012-01-04 09:55:28

1

問題是${$name}未在函數範圍內定義。你會需要或者引用全局變量是這樣的:

$GLOBALS[$name] // bad 

或在函數的頂部添加此:

global ${$name}; // worse 

警告:這是可怕的。不要這樣做:-)我建議只是像你之前提到的那樣傳遞數組。

+0

首先回答誰是正確的(至少關於全球部分)。還沒有驗證你的答案:) – PeeHaa 2012-01-03 22:36:00

+2

如果使用globals是選擇的解決方案(人們不希望),你也可以直接使用'$ GLOBALS [$ name]'而不是定義'$ {$ name}'全球第一。 – Bart 2012-01-03 23:30:09

+0

@Bart:你絕對正確。我會修改我的答案以反映這一點。謝謝。 – FtDRbwLXw6 2012-01-04 13:54:40