PHP 日本大会 2024

each

(PHP 4, PHP 5, PHP 7)

each返回数组中的当前键值对并推进数组游标

警告

此函数自 PHP 7.2.0 起已弃用,自 PHP 8.0.0 起移除。强烈建议不要依赖此函数。

描述

each(array|object &$array): array

返回数组中的当前键值对并推进数组游标。

each()执行后,数组游标将指向数组的下一个元素,如果到达数组末尾则指向最后一个元素之后。如果要使用 each 再次遍历数组,则必须使用reset()

参数

array

输入数组。

返回值

返回数组array中的当前键值对。此对以四个元素的数组返回,键为01keyvalue0key元素包含数组元素的键名,1value元素包含数据。

如果数组的内部指针指向数组内容的末尾之后,each()将返回false

示例

示例 #1 each() 示例

<?php
$foo
= array("bob", "fred", "jussi", "jouni", "egon", "marliese");
$bar = each($foo);
print_r($bar);
?>

$bar 现在包含以下键值对

Array
(
    [1] => bob
    [value] => bob
    [0] => 0
    [key] => 0
)

<?php
$foo
= array("Robert" => "Bob", "Seppo" => "Sepi");
$bar = each($foo);
print_r($bar);
?>

$bar 现在包含以下键值对

Array
(
    [1] => Bob
    [value] => Bob
    [0] => Robert
    [key] => Robert
)

each() 通常与list()一起使用来遍历数组,这是一个示例

示例 #2 使用each()遍历数组

<?php
$fruit
= array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');

reset($fruit);
while (list(
$key, $val) = each($fruit)) {
echo
"$key => $val\n";
}
?>

以上示例将输出

a => apple
b => banana
c => cranberry

警告

因为将数组赋值给另一个变量会重置原始数组的指针,所以我们上面的示例如果在循环内将$fruit赋值给另一个变量,则会导致无限循环。

警告

each()也接受对象,但可能会返回意外的结果。因此,不建议使用each()迭代对象属性。

参见

添加注释

用户贡献注释 24 条注释

14
janhsh
2 年前
在 `each()` 函数被弃用后,这里是如何修正你的源代码的方法:

如果你像这样在 while 循环中使用 each():

while (list($Key,$Value)=@each($Array)){
....
}

你必须替换为:

foreach ($Array as $Key => $Value){
....
}

同样的道理。

while (list(,$Value)=@each($Array)){
....
}

将变成:

foreach ($Array as $Value){
....
}
41
wolfeym38 at yahoo dot com
17 年前
关于 foreach 与 while(list) = each 的速度
我编写了一个基准测试脚本,结果清楚地表明 foreach 更快。快得多。即使对于大型数组(特别是对于大型数组)。我测试了 100,000、1,000,000 和 10,000,000 的大小。为了用 1000 万进行测试,我不得不将我的内存限制设置得很高,在它实际工作时,它接近 1GB。

<?php
function getDiff($start, $end) {
$s = explode(' ', $start);
$stot = $s[1] + $s[0];
$e = explode(' ', $end);
$etot = $e[1] + $e[0];
return
$etot - $stot;
}

$lim=10000000;
$arr = array();
for (
$i=0; $i<$lim; $i++) {
$arr[$i] = $i/2;
}

$start = microtime();
foreach (
$arr as $key=>$val);

$end = microtime();
echo
"foreach 耗时 = " . getDiff($start, $end) . ".\n";

reset($arr);
$start = microtime();
while (list(
$key, $val) = each($arr));
$end = microtime();
echo
"list each 耗时 = " . getDiff($start, $end) . ".\n";
?>

以下是部分测试结果:数组大小为 1,000,000
foreach 耗时 = 0.0244591236115.
list each 耗时 = 0.158002853394.
desktop:/media/sda5/mpwolfe/tests$ php test.php
foreach 耗时 = 0.0245339870453.
list each 耗时 = 0.154260158539.
desktop:/media/sda5/mpwolfe/tests$ php test.php
foreach 耗时 = 0.0269000530243.
list each 耗时 = 0.157305955887.

数组大小为 10,000,000
desktop:/media/sda5/mpwolfe/tests$ php test.php
foreach 耗时 = 1.96586894989.
list each 耗时 = 14.1371650696.
desktop:/media/sda5/mpwolfe/tests$ php test.php
foreach 耗时 = 2.02504014969.
list each 耗时 = 13.7696218491.
desktop:/media/sda5/mpwolfe/tests$ php test.php
foreach 耗时 = 2.0246758461.
list each 耗时 = 13.8425710201.

顺便说一下,这些结果是在我认为是 php 5.2 的环境下获得的,测试机器为具有 3GB 内存和 2.8GHz 双核奔腾处理器的 Linux 机器。
17
phpcoder at gmail dot com
5年前
each 函数被弃用是因为它暴露了过多的内部实现细节,阻碍了语言的开发。(“我们不能做 X,因为它会破坏 each()。”)

https://wiki.php.net/rfc/deprecations_php_7_2#each

如果你需要数组指针,请自行维护。这可能也是一个好主意,因为这样它在代码中是可见的。
10
dmikam
3年前
此函数在 PHP 7.2.0 中被标记为已弃用,并在 PHP 8.0.0 中被移除,旧代码的替换如下所示

function legacy_each($array){
$key = key($array);
$value = current($array);
$each = is_null($key) ? false : [
1 => $value,
'value' => $value,
0 => $key,
'key' => $key,
];
next($array);
return $each;
}
7
man13or at hotmail dot fr
4年前
您好,由于 each() 和 list() 经常“背叛”非常旧的应用程序,我建议不要再使用它们了。

如果你想根据关联数组分配变量,
将以下代码

while(list ($key, $value) = each ($my_array)) {
$$key = $value;
}

替换为

foreach ($my_array as $key => $value) {
$$key = $value;
}
12
sjoerd-php at linuxonly dot nl
18年前
使用 foreach 代替 while、list 和 each。Foreach
- 更易于阅读
- 更快
- 不受数组指针的影响,因此不需要 reset()。

使用方法如下
<?php
$arr
= array('foo', 'bar');
foreach (
$arr as $value) {
echo
"值是 $value.";
}

$arr = array('key' => 'value', 'foo' => 'bar');
foreach (
$arr as $key => $value) {
echo
"键: $key, 值: $value";
}
?>
2
Henk Poley
5年前
Rector 有一个自动修复程序('ListEachRector')可以迁移掉 `each()`

https://github.com/rectorphp/rector/blob/master/docs/AllRectorsOverview.md#listeachrector

如果你查看代码示例,你会发现手动操作也很简单。
4
james at gogo dot co dot nz
20年前
值得注意的是,对数组的引用没有自己的数组指针,并且对数组的引用不会重置其数组指针,因此,这按预期工作,每次迭代数组中的前三个项目,而不是第一个项目三次。

<?php
$x
= array(1,2,3);

print_r(each($x));
echo
"\n";

$y =& $x;
print_r(each($y));
echo
"\n";

$z =& $y;
print_r(each($z));
echo
"\n";
?>
3
Sopinon
19年前
如果你想显示数组的整个结构(树),可以使用这个递归解决方案。

<?PHP
$tree
= "";
array_tree($your_array);
echo
$tree;

// 递归函数
function array_tree($array, $index=0){
global
$tree;
$space="";
for (
$i=0;$i<$index;$i++){
$space .= " ";
}
if(
gettype($array)=="array"){
$index++;
while (list (
$x, $tmp) = each ($array)){
$tree .= $space."$x => $tmp\n";
array_tree($tmp, $index);
}
}
}
?>
2
匿名用户
6年前
一个奇怪的被弃用的函数。如果你在一个 foreach 循环之外的集合中跟踪数组指针,你不会关心性能,而此函数的实用性是核心。

相反,你必须调用两个函数:current() 然后 next() 来复制它的行为。
2
michael k (编辑部已知姓名)
17 年前
如果您想迭代一个二维稀疏数组,并希望首先显示每个第一个元素,然后是每个第二个元素,依此类推,您可以使用此代码

$fruits = array ( "fruits" => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third",
10 => "fourth",
)
);

$done = False;
while ($done == False) {
$done = True;

// 重要:&$val 必须是引用(使用 &),
// 否则,$val 的内部计数器将在每次迭代时
// 重置,您将无限循环遍历第一个元素。
// 无限循环。

foreach($fruits as $key => &$val) {

if (list($inner_key, $inner_val) = each(&$val)) {
$done = False;
echo "$key : : $inner_key => $inner_val <br> \n";
}

}
}

注意:这只是一个快速修复,如果您有更好的方法,请分享!
1
wodzuY2k at anronet dot pl
22年前
此函数将帮助您将任何变量转储到 XML 结构中。

// 将变量转储到简单的 XML 结构中
function var_dump_xml($tagname,$variable,$level=0)
{
for($i=0;$i<$level;$i++) $marg.=' ';
if (eregi('^[0-9].*$',$tagname)) $tagname='tag_'.$tagname; // XML 标签不能以数字开头
if (is_array($variable))
{
echo $marg."<$tagname>\n";
while (list ($key, $val) = each ($variable)) var_dump_xml($key,$val,$level+1);
echo $marg."</$tagname>\n";
}
elseif (strlen($variable)>0)
{
echo $marg."<$tagname>".htmlspecialchars($variable)."</$tagname>\n";
};
};

/*
示例

$myVar = array("name"=>"Joe", "age"=>"26", "children"=>array("Ann","Michael"));
var_dump_xml("myVarTag",$myVar);
*/
1
matthew at mhalls dot net
19年前
致 panania at 3ringwebs dot com

如果您确定只接收一行,则 while 循环是冗余的。为了缩短您的代码

$strSQL = "SELECT * FROM table WHERE id=1";
$RecordsetSelect = $db->runQuery ($strSQL);
list($key, $val) = mysql_fetch_row($RecordsetSelect);
echo "$key => $val\n";
mysql_free_result($RecordsetSelect);

只返回一行时,这是一个更优雅的解决方案,但这只是本质上吹毛求疵。它还展示了使用 list 的另一种快捷方式。
-1
massimo dot modica at tin dot it
14年前
如果您忘记在 each() 之前重置数组,则相同的代码在不同的 PHP 版本中可能会产生不同的结果。

<?php

$a
= array(1,2,3);

foreach (
$a AS $k => $v) $a[$k] = 2*$v;

while(list(
$k2, $v2) = each($a)) { echo($v2."\n"); }

?>

在 PHP 5.2.0 中

2
4
6

在 PHP 5.2.6 中

4
6
-1
匿名
22年前
我经常处理二维数组。由于我在正确遍历它们方面遇到了一些麻烦,也许其他人也遇到过这些问题,可以使用这个方法。

它基于一个名为 $array[$x][$y] 的二维数组。在某些(但不一定是所有)(x,y) 位置存在我想要访问的值。请注意,我事先不知道 $x 或 $y 的范围(即它们的最大值和最小值)。

while (list ($x, $tmp) = each ($array)) {
while (list ($y, $val) = each ($tmp)) {
echo "$x, $y, $val";
}
}

因此,对于每个 (x,y) 对的答案可以是(当然,前提是这些值事先存在于您的数组中)

1, 1, 2
2, 2, 0
3, 1, 1
5, 2, 2
5, 1, 2

请注意,只显示具有相应值的 (x,y) 对。

坚持住
Jon Egil Strand
挪威科技大学 (NTNU)
-2
amby2 at izh dot com
19年前
我发现了一种使用 for 语句(而不是下面的大多数示例中使用的 while)遍历关联数组的简洁方法

<?php

for (reset($array); list($key) = each($array);) {
echo
$key;
echo
$array[$key];
}

?>

或者

<?php

for (reset($array); list($key, $value) = each($array);) {
echo
$key;
echo
$value;
echo
$array[$key];
}

?>

使用这种结构,您几乎不会忘记添加 reset($array) 代码行。
-2
tk at turtle-entertainment dot de
23年前
确保使用集成的函数 "unset();" 或 "reset();"——许多人忘记了这一点,并对生成的输出感到疑惑!
-2
13975001197 at 163 dot com
6年前
在 PHP 7.2 中,我们可以使用 foreach() 来替换 each(),例如

foreach($array as $key => $value) {
// 执行某些操作
}
-3
Gillis at dancrea dot com
22年前
我编写了一个简短且非常简单的脚本来搜索关联数组中的一些值,这是一个简化的示例

<?php

$foo
['bob'] = "bob is ugly";
$foo['bill'] = "bill is rich";
$foo['barbie'] = "barbie is cute";
$search = "rich";

echo
"searching the array foo for $search:<br>";
reset ($foo);
while (list (
$key, $val) = each ($foo)) {
if (
preg_match ("/$search/i", $val)) {
print
"A match was found in $key.<br />";
} else {
print
"A match was not found in $key.<br />";
}
}

?>

将输出
在数组 foo 中搜索 rich
在 bob 中未找到匹配项
在 bill 中找到匹配项
在 barbie 中未找到匹配项
-3
php at omit dot ianco dot co dot uk
16年前
我希望能够在循环遍历数组时向其添加元素。foreach 不允许这样做,因为它使用了数组的秘密副本。each 使这成为可能(在 PHP 4 上测试过)。
<?php
$shopping_list
= array('oysters', 'caviare');
reset ($shopping_list);
while (list(
$key, $value) = each ($shopping_list)) {
if (
$value == 'oysters') $shopping_list[] = 'champagne';
elseif (
$value == 'champagne') $shopping_list[] = 'ice';
}
print_r($shopping_list);
// Array ( [0] => oysters [1] => caviare [2] => champagne [3] => ice )
?>
-5
gaviel
13年前
好的,这是一个使用 foreach 迭代多维数组的方法

<?php
$members
= array(
"member1" => array (
"First Name" => "Robert",
"Last Name" => "Burton",
"Age" => "20"
),
"member2" => array (
"First Name" => "Cheska",
"Last Name" => "Vladesk",
"Age" => "21"
),
"member3" => array (
"First Name" => "Gino",
"Last Name" => "Marley",
"Age" => "19"
),
"member4" => array (
"First Name" => "Jake",
"Last Name" => "White",
"Age" => "16"
),
);
$dataSetCount = count($members);
echo
"<h1>共有 $dataSetCount 名成员</h1>";

$i = 0;
foreach (
$members as $each_members) {
$i++;
echo
"<h2>成员 $i</h2>";
foreach (
$each_members as $position => $details) {
echo
"<b>$position</b>" . ": " . $details . "<br />";
}
}
?>
-4
kris at angelanthony dot com
24年前
记住,如果你用`each()`多次迭代一个数组,要使用“reset()”! 例如

while(list($key,$value) = each($array)){
// 代码在此
}

现在$array的内部指针位于数组的末尾,再次尝试像上面那样的迭代将导致“while”块内的代码零次执行。你必须调用“reset($array)”来重置内部数组指针,然后才能从第一个元素再次迭代数组。
-5
nino dot skopac at gmail dot com
9年前
<?php
function each_v2($arr) {
// 与each()相同,但在到达数组末尾时会重置它
static $i = 0;

if (isset(
$arr[$i])) {
// 存在
return $arr[$i++];
} else {
// 将$i重置为0并重复
$i = 0;
return
each_v2($arr);
}
}
?>
-5
ayyappan dot ashok at gmail dot com
8年前
/* 使用each迭代对象 */

class SAI
{
public function __toString()
{
return __CLASS__;
}
}
$a = new SAI();
$b = new SAI();
$c = new SAI();
$d = new SAI();
$e = new SAI();

$objarray = array($a,$b,$c,$d,$e);
reset($objarray);
while (list($key, $val) = each($objarray))
{
echo "$key => $val\n";
}
//结果
0 => SAI
1 => SAI
2 => SAI
3 => SAI
4 => SAI

警告
each() 也接受对象,但可能返回意外的结果。因此,不建议使用each()迭代对象属性。
To Top