在做php循环与跳出总结时,有提到过php常用的循环 。本文主要设计php数组的循环 ,着重会总结foreach的用法,同时也会提到list、each、key等,示例中也会结合while和for做配合调用。
一、foreach循环
1、key、value普通遍历
foreach可以说是php语言单独为遍历数组提供的一种方法(其他语言也可能有),这种遍历方法是php遍历数组的首选。foreach遍历的方式有两种:一种是只出输出value值,一种是输出key和value值。语法表达式为:
//第一种 foreach (array as $value) statement //第二种 foreach (array as $key => $value) statement
示例:
//只输出value值 <?php $arr_age = array("wang"=>18, "li"=>20, "zhang"=>25); foreach ($arr_age as $age) { echo $age,'<br />'; } ?> //输出key和value值 <?php $arr_age = array("wang"=>18, "li"=>20, "zhang"=>25); foreach ($arr_age as $key=>$age) { echo $key,': ',$age,'<br />'; } ?>
2、foreach更改原数组的值
当 foreach 开始执行时,数组内部的指针会自动指向第一个单元,这意味着不需要在 foreach 循环之前调用 reset()。
foreach 所操作的是指定数组的一个拷贝,而不是该数组本身。对返回的数组单元的修改也不会影响原数组(见下面例子),但 foreach 循环运行到结束,原数组的内部指针将指向数组的结尾。数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。
具体请参看官方文档:http://cn2.php.net/manual/zh/control-structures.foreach.php
例:
//该例中原数组的值不变 <?php $arr_age = array("wang"=>18, "li"=>20, "zhang"=>25); foreach ($arr_age as $age) { $age = $age+10; echo $age,'<br />'; } // 输出原数组 print_r($arr_age); ?>
如果想在foreach结束时更改原数组元素的值,可以通过增加&符来完成,还是上面的例子,做法如下:
<?php $arr_age = array("wang"=>18, "li"=>20, "zhang"=>25); foreach ($arr_age as &$age) { $age = $age+10; echo $age,'<br />'; } // 输出时原数组元素的值都会增加10 print_r($arr_age); ?>
3、多维数组下的foreach嵌套
foreach 语法结构只能用于遍历一维数组,要遍历多维数组,一般是将 foreach 嵌套递归使用或者将原数组分割为一维数组再进行 foreach 遍历。
例:
$arr_age = array("wang"=>18, "li"=>20, "zhang"=>array("name"=>"小张", "age"=>25)); foreach ($arr_age as $age) { if(is_array($age)){ foreach ( $age as $detail) { echo $detail,'<br />'; } } else { echo $age,'<br />'; } } ?>
二、for循环数组
for在某些情况下也可以当foreach来用,不过for有其自身的局限性。其限制为:一、所遍历的数组必须是索引数组(即下标为数字的数组),不能是关联数组(下标为字符串的数组);二、for遍历的数组既要满足是索引数组,同时下标又要是连续的整数,如果不是连续的整数则会报错。
例:
//能正常执行,同foreach <?php $arr_age = array(18, 20, 25); $num = count($arr_age); for($i = 0; $i < $num; $i++){ echo $arr_age[$i]."<br />"; } ?> //报错Notice: Undefined offset: 1 in ……on line 13 —— 限制1 <?php $arr_age = array(18, 20, 25); $num = count($arr_age); for($i = 0; $i < $num; $i++){ echo $arr_age[$i]."<br />"; } ?> //报错Notice: Undefined offset: 2 in…… —— 限制2 <?php $array=array(1=>'Google',5=>'Chrome',7=>'Android',9=>'Youtube',12=>'Gmail'); //print_r($array); for($i=0;$i<count($array);$i++){ echo $array[$i],"<br>"; } ?>
三、list函数遍历
list函数的作用是把数组中的值赋给一些变量,list函数有以下特点:
a、list() 仅能用于数字索引的数组并假定数字索引从 0 开始。
b、list() 从最右边一个参数开始赋值。如果你用单纯的变量,不用担心这一点。 但是如果你用了具有索引的数组,通常你期望得到的结果和在 list() 中写的一样是从左到右的,但实际上不是。 它是以相反顺序赋值的。
c、在 list() 执行过程中修改数组(比如使用 list($a, $b) = $b)将会产生不可预知的结果。
例:
<?php //使用list遍历函数 //$arrGoogle=array('brand'=>'google','email'=>'Gmail','WebBrowser'=>'Chrome','phone'=>'Android');//使用关联数组不行 $arrGoogle=array('google','Gmail','Chrome','Android'); list($brand,$email,$webBrowser,$phone)=$arrGoogle; echo $brand,$email,$webBrowser,$phone; ?>
注:如果只是部分取出数组的值,只需 按照这样的写法即可,list(,,$chrome,)=$arrGoogle;这样我们就可以去除chrome的信息,但是注意一定要保证list参数与数组的元素个数相同(所取值前面的个数)。
再给一个官方的示例:
<table> <tr> <th>Employee name</th> <th>Salary</th> </tr> <?php $result = mysql_query("SELECT id, name, salary FROM employees", $conn); while (list($id, $name, $salary) = mysql_fetch_row($result)) { echo " <tr>n" . " <td><a href="info.php?id=$id">$name</a></td>n" . " <td>$salary</td>n" . " </tr>n"; } ?> </table>
更多用示例可以参看官方文档:http://cn2.php.net/list
四、each循环
each函数用来返回数组中当前的键/值对并将数组指针向前移动一步。 在执行 each() 之后,数组指针将停留在数组中的下一个单元或者当碰到数组结尾时停留在最后一个单元。如果要再用 each 遍历数组,必须使用 reset()。
each函数返回4个值,分别为0、1、key、value;其中0和key包含键名,而1和value包含相应的数据 。具体可以根据下面的示例来理解:
<?php //使用each函数遍历数组 $arrGoogle=array('google','Gmail','Chrome','Android'); //第一次使用each取得当前键值对,并且将指针移到下一个位置 $arrG=each($arrGoogle); print_r($arrG); $arrGmail=each($arrGoogle); print_r($arrGmail); $arrChrome=each($arrGoogle); print_r($arrChrome); $arrAndroid=each($arrGoogle); print_r($arrAndroid); //当指针位于数组末尾再次执行函数each,如果是这样再次执行结果返回false $empty=each($arrGoogle); //如果指针无法继续后移返回false if($empty==false){ print '指针以位于数组末尾,无法在向后移,故返回false'; } ?> //输出结果为: Array ( [1] => google [value] => google [0] => 0 [key] => 0 ) Array ( [1] => Gmail [value] => Gmail [0] => 1 [key] => 1 ) Array ( [1] => Chrome [value] => Chrome [0] => 2 [key] => 2 ) Array ( [1] => Android [value] => Android [0] => 3 [key] => 3 ) 指针以位于数组末尾,无法在向后移,故返回false
each经常和list和while混合使用 。具体见下面的例子:
<?php $sports = array( 'football' => 'good', 'swimming' => 'very well', 'running' => 'not good'); while ($elem = each($sports)) { echo $elem['key'].": ".$elem['value']."<br />"; } ?> <?php $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry'); reset($fruit); while (list($key, $val) = each($fruit)) { echo "$key => $valn"; } ?>
具体参看官方文档:http://cn2.php.net/manual/zh/function.each.php
五、key函数获取键名
key() 函数返回数组中内部指针指向的当前单元的键名。 但它不会移动指针。如果内部指针超过了元素列表尾部,或者数组是空的,key() 会返回 NULL。
示例:
<?php $array = array( 'fruit1' => 'apple', 'fruit2' => 'orange', 'fruit3' => 'grape', 'fruit4' => 'apple', 'fruit5' => 'apple'); // this cycle echoes all associative array // key where value equals "apple" while ($fruit_name = current($array)) { if ($fruit_name == 'apple') { echo key($array).'<br />'; } next($array); } ?>
其输出结果为:
fruit1 fruit4 fruit5
其中上面引用的两个函数current和next的用法可以参看官方文档:
current() – 返回数组中的当前单元
next() – 将数组中的内部指针向前移动一位
六、总结
php数组相关的函数很多,其中主要涉及到遍历循环部分的主要为上面提到的几个函数(for应该称之为流程控制语句),但就执行效率而言,foreach效率较高。
本文除参考官方文档外,还参考以下两个页面。
其他数组函数可以参看官方文档。