【问题标题】:Is this foreach loop responsible for god killing cats?这个 foreach 循环对上帝杀死猫负责吗?
【发布时间】:2011-07-24 00:09:22
【问题描述】:

取自https://stackoverflow.com/questions/4891301/top-bad-practices-in-php

这种类似的代码也是杀猫吗?

foreach (file("longFile.txt") as $line) {
    // ouch! Kitten killed
}

??

对于那些不知道我在说什么的人:

PHP 每次转到下一行文件时是否都会获取 longFile.txt?谈论这段代码:

foreach (file("longFile.txt") as $line) {
        // something
}

【问题讨论】:

  • 实际上转到下一行文件比将其完全加载到内存中要好,对吧?请参阅我的回答如何使用 PHP 做到这一点。

标签: php file foreach


【解决方案1】:

在链接的问题中,for 循环通过在每次迭代中调用 count 来导致性能下降。 foreach 使用内部指针遍历传递给它的数组。

在您的示例中,file() 将被调用一次,结果数组将传递给 foreach,后者将遍历它,从而保存小猫。六一快乐!

【讨论】:

  • 在第一种情况下杀死小猫的区别在哪里(链接答案)?因为它是 foreach(){} 而不是 for(){} 或者因为那个 file() 而不是 count() ?
  • 在链接的问题中,for 循环在每次迭代时调用 count 会导致性能下降。 foreach 使用内部指针遍历传递给它的数组。这就像给一个 for 循环提供猫薄荷。
  • uff,小狗和小猫都得救了 :) 星期六快乐!
【解决方案2】:

它不应该杀死任何小猫,因为,为了让 PHP 获取文件的下一行,它必须知道文件指针从上一行被拉出后的位置。您只是在推进迭代器,它维护对文件对象的引用。

另外,打开这样的文件是不好的做法;你应该有一个变量来存储它并在完成后关闭它。

【讨论】:

  • 是的,我知道,但是,在我之前的问题中,有人回答了这个代码。
  • 除非我对 PHP 的了解非常有缺陷,否则从概念上讲,foreach 循环就是将迭代器推进到语句左侧的for 循环。按照这个逻辑,它不应该是谋杀猫科动物。您可以自己验证这一点,方法是在代码运行时检查文件句柄的数量。
  • 文件在file()返回数组之前关闭。最多它会使用大量内存来杀死小狗,而不是小猫。两者都做,PETA 就会对你不利。
  • @ChetSimpson:所以你认为这是在杀死动物? :( 与 for(){} 循环和 count() 相同?
【解决方案3】:

您想使用 Duff 设备展开循环:http://de.wikipedia.org/wiki/Duff%E2%80%99s_Device。在每次迭代中不使用 count() 的情况下,这将比 foreach 更快,然后比 for 循环更快,并且它会比连接和 rtrim 字符串更快,但与使用 implode() 相同。

【讨论】:

    【解决方案4】:

    那个文件真的很大吗?考虑:

    foreach(new SplFileObject($path) as $line) {
        // neither kill puppies nor kittens
    }
    

    foreach 始终在具体迭代器上工作。如果您传递的是array

    除非引用了数组,否则 foreach 对指定数组的副本而不是数组本身进行操作。 (ref)

    所以array 或函数调用也不会在每次foreach 前进时执行。

    相关:How to store and reset a PHP array pointer?

    【讨论】:

      【解决方案5】:

      没有。小猫死亡的原因有很多,但 foreach 循环不是其中之一。

      【讨论】:

        猜你喜欢
        • 2013-02-10
        • 1970-01-01
        • 2011-05-13
        • 2011-03-30
        • 1970-01-01
        • 1970-01-01
        • 2014-06-04
        • 2020-11-24
        • 2021-01-05
        相关资源
        最近更新 更多