返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >如何在PHP中使用foreach
  • 560
分享到

如何在PHP中使用foreach

2023-06-15 07:06:43 560人浏览 独家记忆
摘要

今天就跟大家聊聊有关如何在PHP中使用foreach,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。语言基础foreach 语法结构提供了遍历数组的简单方式。php5之前, forea

今天就跟大家聊聊有关如何在PHP中使用foreach,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

语言基础

foreach 语法结构提供了遍历数组的简单方式。

php5之前, foreach仅能用于数组php5+, 利用foreach可以遍历对象

foreach仅能够应用于数据和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。

有两种语法:

foreach (array_expression as $value) {    // statement}foreach (array_expression as $value) :    // statementendforeach;
foreach (array_expression as $key => $value) {    // statement}foreach (array_expression as $key => $value) :    // statementendforeach;

还能够自定义遍历对象!

foreach开始执行时, 数组内部的指针会自动指向第一个单元. 这意味着不需要在foreach循环之前调用reset()由于foreach依赖内部数组指针, 在循环中修改其值将可能导致意外的行为

可以很容易通过在 $value 之前加上 & 来修改数组元素. 此方法将以引用 赋值, 而不是拷贝一个值.

<?php$arr = [1, 2, 3, 4];foreach($arr as &$value) {    $value = $value * 2;}// $arr is now [2, 4, 6, 8]unset($value); // 最后取消掉引用

$value的引用仅在被遍历的数组可以被引用时才可用(例如是个变量)。

以下代码无法运行:

<?phpforeach (array(1, 2, 3, 4) as &$value) {    echo $value, '-';    $value = $value * 2;    echo $value, PHP_EOL;}

Warning: 数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。

Note: foreach 不支持用 @ 来抑制错误信息的能力

foreach 虽然简单, 不过它可能出现一些意外行为, 特别是代码涉及到引用的时候。

问题研究

问题一: 如下代码运行结果为何不是 2/4/6 ?

<?php$arr = [1, 2, 3];foreach ($arr as $k => &$v) {    $v = $v * 2;}foreach ($arr as $k => $v) {    echo $v, PHP_EOL;}

我们可以认为 foreach($arr as &$v) 结构隐含了如下操作, 分别将数组当前的 赋值给 $k$v. 具体展开形如:

<?phpforeach ($arr as $k => $v) {    $k = currenTKEy();    $v = currentVal();    // 继续运行用户代码}

根据上述理论, 现在我们重新来分析下第一个foreach:

循环备注$arr值
循环 1-1由于$v是一个引用, 因此 $v = &$arr[0], $v = $v * 2 相当于 $arr[0] * 2[2, 2, 3]
循环 1-2$v = &$arr[1][2, 4, 3]
循环 1-3$v = &$arr[2][2, 4, 6]
循环 2-1隐含操作 $v = $arr[0] 被触发, 由于此时 $v 仍是 $arr[2] 的引用, 相当于 $arr[2] = $arr[0][2, 4, 2]
循环 2-2$v = $arr[1], 即$arr[2] = $arr[1][2, 4, 4]
循环 2-3$v = $arr[2], 即$arr[2] = $arr[2][2, 4, 4]

如何解决此类问题呢? PHP手册上有一段提醒:

Warning: 数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。

<?php$arr = [1, 2, 3];foreach ($arr as $k => &$v) {    $v = $v * 2;}unset($v);foreach ($arr as $k => $v) {    echo $v, PHP_EOL;}

从这个问题可以看出, 引用很可能会伴随副作用。如果不希望无意识的修改导致数据内容变更, 最好及时unset掉这些引用。

问题二: 如下代码运行结果为何不是 0=>a 1=>b 2=>c

<?php$arr = ['a', 'b', 'c'];foreach ($arr as $k => $v) {    echo key($arr), "=>", current($arr), PHP_EOL;}foreach ($arr as $k => &$v) {    echo key($arr), "=>", current($arr), PHP_EOL;}

按照手册中的说法, key和current分别是获取数据中当前元素的键值。那为何 key($arr) 一直是0,current($arr) 一直是'a'呢?

先用vld查看编译后的 opcode:

➜  demo /usr/local/Cellar/php/7.2.7/bin/php -dvld.active=1 a.phpFinding entry pointsBranch analysis from position: 0Jump found. (Code = 77) Position 1 = 2, Position 2 = 15Branch analysis from position: 2Jump found. (Code = 78) Position 1 = 3, Position 2 = 15Branch analysis from position: 3Jump found. (Code = 42) Position 1 = 2Branch analysis from position: 2Branch analysis from position: 15Jump found. (Code = 62) Position 1 = -2Branch analysis from position: 15filename:       /Users/jianyong/demo/a.phpfunction name:  (null)number of ops:  17compiled vars:  !0 = $arr, !1 = $v, !2 = $kline     #* E I O op                           fetch          ext  return  operands-------------------------------------------------------------------------------------   2     0  E >   ASSIGN                                                   !0, <array>   4     1      > FE_RESET_R                                       $4      !0, ->15         2    > > FE_FETCH_R                                       ~5      $4, !1, ->15         3    >   ASSIGN                                                   !2, ~5   5     4        INIT_FCALL                                               'key'         5        SEND_VAR                                                 !0         6        DO_ICALL                                         $7         7        ECHO                                                     $7         8        ECHO                                                     '%3D%3E'         9        INIT_FCALL                                               'current'        10        SEND_VAR                                                 !0        11        DO_ICALL                                         $8        12        ECHO                                                     $8        13        ECHO                                                     '%0A'        14      > JMP                                                      ->2        15    >   FE_FREE                                                  $4   7    16      > RETURN                                                   1branch: #  0; line:     2-    4; sop:     0; eop:     1; out1:   2; out2:  15branch: #  2; line:     4-    4; sop:     2; eop:     2; out1:   3; out2:  15branch: #  3; line:     4-    5; sop:     3; eop:    14; out1:   2branch: # 15; line:     5-    7; sop:    15; eop:    16; out1:  -2path #1: 0, 2, 3, 2, 15,path #2: 0, 2, 15,path #3: 0, 15,0=>a0=>a0=>a

PHP7新特性之foreach

  • [x] foreach 循环对数组内部指针不再起作用, 在PHP7之前, 当数据通过foreach迭代时, 数组指针会移动。

<?php$array = [0, 1, 2];foreach ($array as &$val) {    var_dump(current($array));}
版本结果说明
PHP5int(1) int(2) bool(false)数组指针会移动
PHP7int(0) int(0) int(0)数据指针不再移动
  • [x] 按照值进行循环时, 对数组的修改是不会影响循环。

foreach按照值进行循环的时候(by-value), foreach是对该数组的一个拷贝进行操作. 所以在循环过程中修改不影响循环结果

<?php$arr = [0, 1, 2];$ref = &$arr;foreach ($arr as $val) {    var_dump($val);    unset($arr[1]);}
版本结果说明
PHP5int(0) int(2)会将unset的数据跳过
PHP7int(0) int(1) int(2)对数组的改动不影响循环
  • [x] 按照引用进行循环的时候, 对数组的修改会影响循环

<?php$arr = [0, 1, 2];$ref = &$arr;foreach ($arr as &$val) {    var_dump($val);    unset($arr[1]);}
版本结果
PHP5int(0) int(2)
PHP7int(0) int(2)
  • [x] 对简单对象plain(non-Traversable)的循环

在简单对象的循环, 不管是按照值循环还是引用循环, 和按照引用对数组循环的行为是一样的, 不过对位置的管理会更加精确

  • [x] 对迭代对象(Traversable objects)对象行为和之前一致

stackoverflow 上面的解释, Traversable objects is one that implements Iterator or IteratorAggregate interface

如果一个对象实现了 Iterator 或者 IteratorAggregate 接口, 即可称之为迭代对象

看完上述内容,你们对如何在PHP中使用foreach有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网PHP编程频道,感谢大家的支持。

--结束END--

本文标题: 如何在PHP中使用foreach

本文链接: https://lsjlt.com/news/278704.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何在PHP中使用foreach
    今天就跟大家聊聊有关如何在PHP中使用foreach,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。语言基础foreach 语法结构提供了遍历数组的简单方式。php5之前, forea...
    99+
    2023-06-15
  • 如何在Nodejs中使用forEach
    如何在Nodejs中使用forEach?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。利用数组对象方法push/shift可实现队列先进先出特性,例如:>a=[][]>...
    99+
    2023-06-06
  • PHP的foreach()如何使用
    PHP的foreach()如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。PHP的foreach()总共有两种用法,今天我们就将这两种用法分别作了介绍,并...
    99+
    2023-06-17
  • 如何在php中使用foreach遍历二维数组
    今天就跟大家聊聊有关如何在php中使用foreach遍历二维数组,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。PHP开发环境搭建工具有哪些一、phpStudy,是一个新手入门最常用的...
    99+
    2023-06-14
  • 如何在C#中使用foreach语句
    今天就跟大家聊聊有关如何在C#中使用foreach语句,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。C# foreach语句不仅仅只是do...while或者for循环语句的一个变体...
    99+
    2023-06-17
  • 如何在 PHP 中找到 foreach 索引
    在本文中,我们将介绍查找 foreach 索引的方法。 使用 key 变量 使用 index 变量 同时使用 key 和 index 变量 在 PHP 中使用 key 变...
    99+
    2024-02-27
  • C#中foreach如何使用
    本篇文章给大家分享的是有关C#中foreach如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。C# foreach使用1. MySplit 类/// <s...
    99+
    2023-06-17
  • 如何在Vue中使用foreach遍历数组
    今天就跟大家聊聊有关如何在Vue中使用foreach遍历数组,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在js中遍历数组//定义班次详细数组  var ...
    99+
    2023-06-15
  • PHP如何使用foreach()遍历数组
    小编给大家分享一下PHP如何使用foreach()遍历数组,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!方法一:foreach(数组名称 as 自定义变量){}f...
    99+
    2023-06-14
  • php如何使用foreach遍历数组
    这篇文章主要介绍了php如何使用foreach遍历数组,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。foreach遍历数组的方法:1、使用“foreach (数组表达式 as...
    99+
    2023-06-15
  • 在 PHP 中的多维数组中使用 Foreach 循环
    本文将介绍 PHP 中的多维数组。我们还将学习在多维数组中使用 foreach 循环。 在 PHP 中使用 foreach 循环访问多维数组的元素 多维数组在数组中包含一个或多个数组。 一个...
    99+
    2024-02-27
  • 怎么在php中使用foreach遍历类对象
    怎么在php中使用foreach遍历类对象?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。php有什么特点1、执行速度快。2、具有很好的开放性和可扩展性。3、PHP支持多种主...
    99+
    2023-06-14
  • C#中如何使用foreach语句
    C#中如何使用foreach语句,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。C# foreach语句示例说明:要对集合中的内容进行增删改的操作,那么就是要遍历集合,那么C...
    99+
    2023-06-17
  • Linq中如何使用foreach语句
    这篇文章给大家介绍Linq中如何使用foreach语句,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Linq 有很多值得学习的地方,这里我们主要介绍Linq foreach语句,包括介绍foreach循环来强制执行查询...
    99+
    2023-06-17
  • PHP循环中如何使用foreach()方法遍历数组
    这篇文章主要介绍了PHP循环中如何使用foreach()方法遍历数组,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。foreach():for...
    99+
    2024-04-02
  • 怎么在php中使用foreach循环遍历数组
    本篇文章为大家展示了怎么在php中使用foreach循环遍历数组,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。PHP开发环境搭建工具有哪些一、phpStudy,是一个新手入门最常用的开发环境。二、W...
    99+
    2023-06-14
  • php中如何用foreach遍历二维数组
    在PHP中,可以使用foreach循环来遍历二维数组。以下是一个示例:```php$twoDimensionalArray = ar...
    99+
    2023-10-11
    php
  • Vue中如何使用foreach遍历数组
    本篇内容介绍了“Vue中如何使用foreach遍历数组”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在js中遍历数组//定义班次详细数组&n...
    99+
    2023-07-04
  • await在forEach中不起作用如何解决
    这期内容当中小编将会给大家带来有关await在forEach中不起作用如何解决,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。首先引一个很简单题目:给一个数组,每隔1s打印出来.这里我把我一开始在项目中的代...
    99+
    2023-06-06
  • foreach与collection怎么在mybatis 中使用
    foreach与collection怎么在mybatis 中使用?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。foreach的主要用在构建in条件中,它可以在SQL语句中进...
    99+
    2023-05-31
    mybatis foreach collection
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作