PHP Conference Japan 2024

reset

(PHP 4, PHP 5, PHP 7, PHP 8)

reset将数组的内部指针设置为其第一个元素

描述

reset(数组|对象 &$array): 混合

reset()array 的内部指针倒回第一个元素,并返回第一个数组元素的值。

参数

array

输入数组。

返回值

返回第一个数组元素的值,如果数组为空则返回 false

警告

此函数可能返回布尔值 false,但也可能返回一个计算结果为 false 的非布尔值。请阅读关于 布尔值 的部分以了解更多信息。使用 === 运算符 来测试此函数的返回值。

变更日志

版本 描述
8.1.0 对象 调用此函数已弃用。请先使用 get_mangled_object_vars()对象 转换为 数组,或者改用实现 Iterator 接口的类的提供的 方法,例如 ArrayIterator
7.4.0 SPL 类的实例现在被视为没有属性的空对象,而不是调用与此函数同名的 Iterator 方法。

示例

示例 #1 reset() 示例

<?php

$array
= array('第一步', '第二步', '第三步', '第四步');

// 默认情况下,指针位于第一个元素
echo current($array) . "<br />\n"; // "第一步"

// 跳过两步
next($array);
next($array);
echo
current($array) . "<br />\n"; // "第三步"

// 重置指针,从第一步重新开始
reset($array);
echo
current($array) . "<br />\n"; // "第一步"

?>

备注

注意: 空数组的返回值与第一个元素为 布尔 false 的数组的返回值无法区分。要正确检查可能包含 false 元素的数组的第一个元素的值,请先检查数组的 count(),或者在调用 reset() 后检查 key() 是否不为 null

参见

  • current() - 返回数组中的当前元素
  • each() - 返回数组中的当前键值对并前进数组游标
  • end() - 将数组的内部指针设置为其最后一个元素
  • next() - 前进数组的内部指针
  • prev() - 倒回数组内部指针
  • array_key_first() - 获取数组的第一个键

添加备注

用户贡献的备注 11 条备注

milo at mdlwebsolutions dot com
12 年前
陷阱:如果您的第一个元素为 false,则您不知道它是否为空。

<?php

$a
= array();
$b = array(false, true, true);
var_dump(reset($a) === reset($b)); //bool(true)

?>

所以不要依赖 false 返回值来判断数组是否为空。
turabgarip at gmail dot com
3 年前
由于 reset() 除了重置其内部指针外还会返回数组的第一个“值”;当它与 key() 组合使用或单独使用时,它将返回不同的结果。例如:

<?php

$products
= array(
'饼干' => array('饼干1' => 'cobis', '饼干2' => 'probis'),
'巧克力' => array('coco1' => 'cococ', 'coco2' => 'prococ'),
);

echo
key(reset($products['饼干'])); // 致命错误

reset($products['饼干']);
echo
key($products['饼干']); // 将打印 '饼干1'

?>

这是完全正常的,因为在第一种方法中,reset() 返回了“饼干”元素的第一个“值”,即“cbosi”。因此 key(string) 将导致致命错误。而在第二种方法中,您只是重置了数组,而没有使用返回值;而是重置了指针,然后提取了数组的第一个键。

如果您的数组具有更多维度,它可能不会导致致命错误,但是当您组合使用 reset() 和 key() 或连续使用它们时,您将获得不同的结果。
Bartek Ferek
8 年前
至于获取数组的第一个键,先重置然后取键要比重置 ARRAY_KEYS 的结果(如 gardnerjohng at gmail dot com 所建议的那样)效率更高。

<?php
reset
($someArray);
echo
key($someArray);
?>

这将给出相同的结果,但速度要快得多。数组越大,性能越好。在包含 100 个元素的数组上进行了测试,结果速度提高了 16 倍。
arne dot ludwig at posteo dot de
9 年前
回应 gardnerjohng 关于检索数组的第一个 _键_ 的备注

要检索数组的第一个 _键_,您可以组合使用 reset() 和 key()。

<?php
$properties
= array(
'colour' => 'grey',
'flavour' => 'rubber',
'name' => 'Mouse Ball',
'texture' => 'rubbery'
);

reset($properties);
echo
key($properties); // => 'colour'
?>

我更喜欢这个方案,因为它不需要创建键数组。这应该(未经测量)会提高大型数组的性能。
Mladen Janjetovic
11年前
请注意,这里不能使用指针。在这种情况下,它会重置迭代计数器。
foreach($array as $key=>&$value) {...}


请改用标准的foreach循环
foreach($array as $key=>$value) {...}
Alexandre Koriakine
19年前
这种方法也适用于重置多维数组

reset($voo2['moder']);
while (list($key, $value) = each ($voo2['moder'])) {

reset($voo2['moder'][$key]);
while (list($key1, $value1) = each ($voo2['moder'][$key])) {
#执行你想要的操作
}

}
leaetherstrip at inbox dot NOSPAMru
20年前
请注意,reset()不会影响多维数组的子数组。

例如:

<?php
$arr
= array(
1 => array(2,3,4,5,6),
2 => array(6,7,8,9,10)
);

while(list(
$i,) = each($arr))
{
echo
"IN \$arr[$i]<br>";

while(list(
$sub_i,$entry) = each($arr[$i]))
{
echo
"\$arr[$i][$sub_i] = $entry<br>";
}
}

reset($arr);

// 再次执行相同的操作
while(list($i,) = each($arr))
{
echo
"IN \$arr[$i]<br>";

while(list(
$sub_i,$entry) = each($arr[$i]))
{
echo
"\$arr[$i][$sub_i] = $entry<br>";
}
}
?>

将输出

IN $arr[1]
$arr[1][0] = 2
$arr[1][1] = 3
$arr[1][2] = 4
$arr[1][3] = 5
$arr[1][4] = 6
IN $arr[2]
$arr[2][0] = 6
$arr[2][1] = 7
$arr[2][2] = 8
$arr[2][3] = 9
$arr[2][4] = 10
IN $arr[1]
IN $arr[2]
arne dot slabbinck at duo dot be
9 年前
信息

以下代码在5.4.45版本中会发出严格警告

return reset(array_keys($result['node']));

"严格警告:只有变量才能通过引用传递"

所以应该是

$keys = array_keys($result['node']);
return reset($keys);
kendsnyder at gmail dot com
14年前
不要使用`reset()`来获取关联数组的第一个值。它在普通数组中运行良好,但在迭代器对象中运行结果出乎意料。http://bugs.php.net/bug.php?id=38478
m dot lebkowski+php at gmail dot com
18年前
Colin,有一个更好的(在我看来)方法来解决你的问题。
<?
// ...
foreach($a as $k => &$d){} // 注意"&"
// ...
?>
这是PHP5中新增的功能,在foreach循环中使用引用。这样PHP就不会复制数组,因此内部指针不会被重置。
Colin
18年前
我在PHP 5.0.5中遇到一个问题,它在没有任何明显原因的情况下重置了数组的子数组。问题在于对父数组执行foreach()操作时,PHP会复制子数组,这样做会重置原始数组的内部指针。

以下代码演示了子数组的重置

<?
$a = array(
'a' => array(
'A', 'B', 'C', 'D',
),
'b' => array(
'AA', 'BB', 'CC', 'DD',
),
);

// 将$a的指针设置为'b',并将'b'的指针设置为'CC'
reset($a);
next($a);
next($a['b']);
next($a['b']);
next($a['b']);

var_dump(key($a['b']));
foreach($a as $k => $d)
{
}
var_dump(key($a['b']));
?>

这两个var_dump的结果分别是3和0。显然,通过对$a进行foreach循环,$a['b']的内部指针被重置了。

每次foreach循环迭代$a的'a'和'b'键时,它都会将$a['a']和$a['b']复制到$d中,这重置了$a['a']和$a['b']的内部指针,尽管没有进行明显的更改。

解决方案是改为迭代$a的键。

<?
foreach(array_keys($a) as $k)
{
}
?>

并使用$a[$k](或创建$a[$k]的别名$d并处理使用别名的后果)。

出于好奇,我在一个虚拟对象上实现Iterator接口,并调用一个全局对象来进行实际的迭代(也为了应对PHP缺乏C风格的指针,当对对象进行$a = $b操作时,当修改时$a中的数据与$b中的数据不一致)。由于我有许多表示不同数据集的虚拟对象,我选择将每个数据集存储为包含在全局对象中的子数组。为了使此工作,每个虚拟对象必须存储一个键(可以自由复制而不会出现问题),在虚拟对象上调用rewind、key、current、next和valid时,它会将该键传递给全局对象。

不幸的是,我的键不能仅仅是一个简单的字符串或数字(如果是的话,它可以直接索引该对象的数据子数组并避免问题),而是一个字符串数组。相反,我必须迭代(使用foreach循环)每个子数组并将键与存储在子数组中的变量进行比较。

因此,通过这种方式使用foreach循环,并且PHP重置子数组的指针,最终导致无限循环。

实际上,这可以通过PHP即使在复制后也能维护数组的内部指针来解决。
To Top