2010-01-17 187 views
2

我写了一个简单的数组,我用它来打印一个html列表选项集,并带有一个选定的元素。 如果我尝试在我的页面中打印多个列表,我的问题开始,因为只有第一个列表打印正确,为什么?为什么这个PHP函数调用只能工作一次?

<?php 


$units = array (
'0' => 'Units', 
'kJ' => 'Kilojoule: kJ', 
'g' => 'Grams: g', 
'mg' => 'Milligrams: mg', 
'mcg' => 'Micrograms: mcg, µg'); 

function unit_select_option ($attributes, $code = "") { 
    global $units; 
    $html = "<select title=\"Kilojoule: kJ;&#13;Grammi: g;&#13;Milligrammi: mg;&#13;Microgrammi: mcg, µg;\" $attributes>\r"; 

    while (list($key, $name) = each($units)) { 
     if ($key == "0") { 
      $html .= " <option title=\"$name\" value='$key'>$name</option>\r"; 
     } else if ($key == $code) { 
      $html .= " <option title=\"$name\" selected=\"selected\" value='$key'>$key</option>\r"; 
     } else { 
      $html .= " <option title=\"$name\" value='$key'>$key</option>\r"; 
     } 
    } 
    $html.= "</select>\r"; 
    return $html; 
} 

print unit_select_option ('class="units_select"', "g"); 
print unit_select_option ('class="units_select"', "mg"); 
print unit_select_option ('class="units_select"', "mcg"); 
?> 

该代码应该不是什么奇怪的,但我还没有找到问题,因为该页面没有返回任何错误。

html code: 
<select title="Kilojoule: kJ;&#13;Grammi: g;&#13;Milligrammi: mg;&#13;Microgrammi: mcg, µg;" class="units_select"> 
    <option title="Unit&agrave;" value='0'>Unit&agrave;</option> 
    <option title="Kilojoule: kJ" value='kJ'>kJ</option> 
    <option title="Grammi: g" selected="selected" value='g'>g</option> 
    <option title="Milligrammi: mg" value='mg'>mg</option> 
    <option title="Microgrammi: mcg, µg" value='mcg'>mcg</option> 
</select> 
<select title="Kilojoule: kJ;&#13;Grammi: g;&#13;Milligrammi: mg;&#13;Microgrammi: mcg, µg;" class="units_select"> 
</select> 
<select title="Kilojoule: kJ;&#13;Grammi: g;&#13;Milligrammi: mg;&#13;Microgrammi: mcg, µg;" class="units_select"> 
</select> 

回答

2

each()来自:

返回当前键和值的对 从数组和推进阵列 光标。

each()后已经执行,阵列 光标将所述阵列的所述下一个 元件上离开,或过去的最后 元件如果它撞击 阵列的端部。如果要使用每个数组遍历数组 ,则必须使用reset()

所以:

function unit_select_option ($attributes, $code = "") { 
    global $units; 
    $html = "<select title=\"Kilojoule: kJ;&#13;Grammi: g;&#13;Milligrammi: mg;&#13;Microgrammi: mcg, µg;\" $attributes>\r"; 
    reset($units); 
    while (list($key, $name) = each($units)) { 
    if ($key == "0") { 
     $html .= " <option title=\"$name\" value='$key'>$name</option>\r"; 
    } else if ($key == $code) { 
     $html .= " <option title=\"$name\" selected=\"selected\" value='$key'>$key</option>\r"; 
    } else { 
     $html .= " <option title=\"$name\" value='$key'>$key</option>\r"; 
    } 
    } 
    $html.= "</select>\r"; 
    return $html; 
} 

我倾向于避免each(),因为它的非重入,这意味着,如果你的循环中调用别的,用它在同一个阵列,它会影响你的外呼叫。不好。你往往会更好只使用一个foreach循环:

function unit_select_option ($attributes, $code = "") { 
    global $units; 
    $html = "<select title=\"Kilojoule: kJ;&#13;Grammi: g;&#13;Milligrammi: mg;&#13;Microgrammi: mcg, µg;\" $attributes>\r"; 
    foreach ($units as $key => $name) { 
    if ($key == "0") { 
     $html .= " <option title=\"$name\" value='$key'>$name</option>\r"; 
    } else if ($key == $code) { 
     $html .= " <option title=\"$name\" selected=\"selected\" value='$key'>$key</option>\r"; 
    } else { 
     $html .= " <option title=\"$name\" value='$key'>$key</option>\r"; 
    } 
    } 
    $html.= "</select>\r"; 
    return $html; 
} 

和你避免所有这些问题。

+0

好的,如果你还给我一个我的代码的优化版本,你必须得到奖励,谢谢你的帮助 – vitto 2010-01-17 13:53:52

3

each()推进内部数组游标。因为$ units是一个全局变量,所以你第一次调用unit_select_option()会将光标移动到$单位的末尾,并保留给后续调用。

您需要在unit_select_option()的末尾使用reset($units);倒带您的阵列。

PHP文件:reset

+0

更快的正确答案应该是赢家!那为什么我永远不会赢,或者应该是最清楚的? – vitto 2010-01-17 13:46:26

+0

哦谢谢大家的帮助! – vitto 2010-01-17 13:46:55

1

其他答案应该已经解决了你的问题。

我想补充一点,PHP有foreach结构,所以代替while循环中,您可以只写

foreach ($unit as $key => $name) { 
    ... 
} 

如果使用foreach你不需要reset()

3

,应重置数组指针:采用复位()

但是你为什么不使用foreach循环?

foreach($units as $key => $name){ ... } 

而且不要使用全局,它是邪恶的。在函数体中声明$ units数组为static。

+0

+1诅咒 - 你打败了我。 :-) – 2010-01-17 13:50:13

1

好的,正如其他人所说的问题是因为你没有重置全局数组。

但是,我会试图不使用全局,而是每次都将它传递给unit_select_option。 (数组和对象在最近版本的PHP中通过引用传递,所以没有理由不这样做,它通常被认为是更好的编程习惯。)

其次,你在while循环中做了一些奇怪的事情 - 我还以为一个foreach迭代器将使在这种情况下更多的意义,因为这样的:

foreach($units as $key => $value) 

只是一个想法。 :-)