• 售前

  • 售后

热门帖子
入门百科

PHP关于foreach复制知识点总结

[复制链接]
123457757 显示全部楼层 发表于 2021-10-26 13:54:33 |阅读模式 打印 上一主题 下一主题
PHP的foreach是一个非常整洁和切中关键的语言结构。仍然有些人不喜欢使用它,因为他们以为它是缓慢的。一个通常命名的原因是foreach复制它迭代的数组。
因此,一些人发起写:
  1. $keys = array_keys($array);
  2. $size = count($array);
  3. for ($i = 0; $i < $size; $i++) {
  4.   $key  = $keys[$i];
  5.   $value = $array[$key];
  6.   // ...
  7. }
复制代码
而不是更直观和直接:
  1. foreach ($array as $key => $value) {
  2.   // ...
  3. }
复制代码
这里有两个题目:
Microoptimization是欠好的。通常,它只会浪费您的时间,不会带来任何可度量的性能改进。
foreach的复制举动比大多数人以为的要复杂一些。通常情况下,“优化”的版本会比原始版本慢。
foreach什么时间复制?
foreach是否复制数组以及复制的数量取决于三件事:
是否引用了迭代数组、它的refcount有多高以及迭代是否通过引用完成。
没有引用,refcount == 1
在下面的代码中,$array没有被引用,并且refcount为1。在这种情况下,foreach不会复制数组(证实)——这与流行的观点相反,即foreach总是复制没有引用的迭代数组。
  1. test();
  2. function test() {
  3.   $array = range(0, 100000);
  4.   foreach ($array as $key => $value) {
  5.     // ...
  6.   }
  7. }
复制代码
原因很简朴:为什么要如许做?foreach修改$array的唯一地方是它是内部数组指针。这是预期的举动,因此不必要预防。
未引用,refcount > 1
下面的代码看起来非常类似于前面的代码。唯一的区别是数组如今作为参数传递。这似乎是一个无关紧要的区别,但它确实改变了foreach的举动:
它如今将复制数组结构,而不是值(证实;假如你想知道这只是复制的结构,比力一下这个和谁人脚本。第一个只复制结构,第二个两个都复制)。
  1. $array = range(0, 100000);
  2. test($array);
  3. function test($array) {
  4.   foreach ($array as $key => $value) {
  5.     // ...
  6.   }
  7. }
复制代码
乍一看这大概有点奇怪:
为什么当数组通过参数传递时,它会复制,但假如它是在函数中定义的,它就不会复制了?原因是数组zval如今在多个变量之间共享:函数外部的$array变量和函数内部的$array变量。假如foreach在不复制数组结构的情况下迭代数组,那么它不仅会改变函数中$array变量的数组指针,还会改变函数外$array变量的指针。因此foreach必要复制数组结构(即散列表)。另一方面,这些值仍然可以共享zvals,因此不必要复制。
引用
下一种情况与前一种情况非常相似。唯一的区别是数组是通过引用传递的。在这种情况下,数组将不会被复制(证实)。
  1. $array = range(0, 100000);
  2. test($array);
  3. function test(&$array) {
  4.   foreach ($array as $key => $value) {
  5.     // ...
  6.   }
  7. }
复制代码
在这种情况下,相同的推理适用于前一种情况:外部$数组和内部$数组共享zvals。不同的是,它们如今是引用(isref == 1),因此在这种情况下,对内部数组的任何更改都将对外部数组举行。以是假如内部数组的数组指针改变了,外部数组的数组指针也应该改变。这就是foreach不必要复制的原因。
迭代通过引用
上面的例子都是按值迭代的。对于引用迭代,应用相同的规则,但是附加值引用更改数组值的复制举动(关于结构复制的举动保持稳固)。
情况“未引用,refcount == 1”没有改变。引用迭代意味着假如$值有任何变革,我们想要改变原始数组,如许数组就不会被复制(证实)。
“被引用”的情况也保持稳固,在这种情况下,对$value的更改应该会更改引用迭代数组的所有变量(证实)。
只有“未引用,refcount > 1”的情况发生了变革,因为如今必要复制数组结构及其值。数组结构,因为否则函数外部的$array变量的数组指针会改变,而对$value的改变也会改变外部的$array值(证实)。
总结
当且仅当迭代数组未被引用且具有refcount > 1时,foreach将复制数组结构
foreach还将复制数组值,前提是且仅当上一个点应用并且迭代是通过引用完成时

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作