PHP中foreach复制功能怎么实现,复制的数量取决什么
Admin 2022-07-06 群英技术资讯 335 次浏览
PHP的foreach是一个非常整洁和切中要害的语言结构。仍然有些人不喜欢使用它,因为他们认为它是缓慢的。一个通常命名的原因是foreach复制它迭代的数组。
因此,一些人建议写:
$keys = array_keys($array); $size = count($array); for ($i = 0; $i < $size; $i++) { $key = $keys[$i]; $value = $array[$key]; // ... }
而不是更直观和直接:
foreach ($array as $key => $value) { // ... }
这里有两个问题:
Microoptimization是不好的。通常,它只会浪费您的时间,不会带来任何可度量的性能改进。
foreach的复制行为比大多数人认为的要复杂一些。通常情况下,“优化”的版本会比原始版本慢。
foreach什么时候复制?
foreach是否复制数组以及复制的数量取决于三件事:
是否引用了迭代数组、它的refcount有多高以及迭代是否通过引用完成。
没有引用,refcount == 1
在下面的代码中,$array没有被引用,并且refcount为1。在这种情况下,foreach不会复制数组(证明)——这与流行的观点相反,即foreach总是复制没有引用的迭代数组。
test(); function test() { $array = range(0, 100000); foreach ($array as $key => $value) { // ... } }
原因很简单:为什么要这样做?foreach修改$array的唯一地方是它是内部数组指针。这是预期的行为,因此不需要预防。
未引用,refcount > 1
下面的代码看起来非常类似于前面的代码。唯一的区别是数组现在作为参数传递。这似乎是一个无关紧要的区别,但它确实改变了foreach的行为:
它现在将复制数组结构,而不是值(证明;如果你想知道这只是复制的结构,比较一下这个和那个脚本。第一个只复制结构,第二个两个都复制)。
$array = range(0, 100000); test($array); function test($array) { foreach ($array as $key => $value) { // ... } }
乍一看这可能有点奇怪:
为什么当数组通过参数传递时,它会复制,但如果它是在函数中定义的,它就不会复制了?原因是数组zval现在在多个变量之间共享:函数外部的$array变量和函数内部的$array变量。如果foreach在不复制数组结构的情况下迭代数组,那么它不仅会改变函数中$array变量的数组指针,还会改变函数外$array变量的指针。因此foreach需要复制数组结构(即散列表)。另一方面,这些值仍然可以共享zvals,因此不需要复制。
引用
下一种情况与前一种情况非常相似。唯一的区别是数组是通过引用传递的。在这种情况下,数组将不会被复制(证明)。
$array = range(0, 100000); test($array); function test(&$array) { foreach ($array as $key => $value) { // ... } }
在这种情况下,相同的推理适用于前一种情况:外部$数组和内部$数组共享zvals。不同的是,它们现在是引用(isref == 1),因此在这种情况下,对内部数组的任何更改都将对外部数组进行。所以如果内部数组的数组指针改变了,外部数组的数组指针也应该改变。这就是foreach不需要复制的原因。
迭代通过引用
上面的例子都是按值迭代的。对于引用迭代,应用相同的规则,但是附加值引用更改数组值的复制行为(关于结构复制的行为保持不变)。
情况“未引用,refcount == 1”没有改变。引用迭代意味着如果$值有任何变化,我们想要改变原始数组,这样数组就不会被复制(证明)。
“被引用”的情况也保持不变,在这种情况下,对$value的更改应该会更改引用迭代数组的所有变量(证明)。
只有“未引用,refcount > 1”的情况发生了变化,因为现在需要复制数组结构及其值。数组结构,因为否则函数外部的$array变量的数组指针会改变,而对$value的改变也会改变外部的$array值(证明)。
总结
当且仅当迭代数组未被引用且具有refcount > 1时,foreach将复制数组结构
foreach还将复制数组值,前提是且仅当上一个点应用并且迭代是通过引用完成时
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
sleep()是PHP的内置函数。用来延迟给定的秒数来执行程序。该函数只接受一个参数,必须传输该参数。$seconds参数表示以秒为单位的延迟时间。
CakePhp作为主流的基于MVC架构的php框架,能够实现快速编写项目代码。使用方式如下:1、$uses来声明;2、转换成对象;3、cakephp 查询。
这篇文章主要介绍了PHP架构及原理知识点以及相关实例讲解,需要的朋友们参考下。
在laravel中,软删除指的是数据表记录并未真的从数据库中删除,而是将表记录的表示状态标记为软删除,这样在查询时就可以进行过滤,让对应表记录看上去像是被“删除”了。
php将数据库导入mysql的方法:1、通过CMD导入MySQL数据库;2、通过Navicat for MySQL导入MySQL数据库;3、通过PHP执行SQL文件导入MySQL数据库。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008