PHP foreach只返回键

Ran*_*ash 36 php arrays foreach

理论上的问题可能没有任何意义但仍然存在,也许有一个聪明的答案.

我想迭代数组并获取它的键和它们的东西.我做的一个简单例子:

foreach($array as $key => $value) {
    $other_array[$key] = 'something';
}
Run Code Online (Sandbox Code Playgroud)

现在,在此范围内未使用的PHP Mess Detector尖叫声$value.因此,我在想,也许这不是访问keys我的最佳方式array.

知道如何做到这一点,没有不必要地取出values我的array?它是否有任何重大的性能影响...或者我可能只是偏执狂,应该继续下去而不浪费任何人的时间与愚蠢的问题:).

inq*_*uam 59

你可以这样做

foreach(array_keys($array) as $key) {
 // do your stuff
}
Run Code Online (Sandbox Code Playgroud)

这将使foreach迭代一个由数组中的键而不是实际数组组成的数组.请注意,从性能角度来看,它可能并不是更好.

  • 从我所看到的foreach()是使用迭代器实现的,因此只调用一次返回数组的函数.然后它使用指向现有结果集的迭代器来继续每个项目.所以*foreach(array_keys()......*是完全安全的 (3认同)
  • 我做了一些测试,并且`foreach(array_keys($ arr)为$ key)`比`foreach($ arr as $ key => $ val)慢约50%到60%.但它是正确的,你把`array_keys($ arr)`放在哪里没有区别.(使用255个元素的数组进行测试,使用php 5.6.0进行100000轮测试) (3认同)
  • 不,我记得如果评估一次就会进入 foreach 的数组。就像 *foreach(array("a", "b", "c") as $letters)* 不会在每次迭代时创建一个新数组。如果那是不正确的,那么确定,在 foreach 之前创建一个 $keys 变量......你有任何参考指向 foreach 在每次迭代中评估数组的事实吗? (2认同)
  • @inquam感谢您的见解!这来自我的JavaScript经验,其中`for(var i = 0; i <abc.indexOf('aa'); i ++)`将在每次迭代中调用indexOf.我想我的想法是所有语言都会这样做 - 我很高兴他们没有! (2认同)

Abc*_*hen 12

只是忽略这条消息.

在PHP中,您使用的方式foreach是最快的.是的,您应该避免使用未使用的变量,但在这种情况下,您无法避免它,而不会失去一些性能.

例如foreach(array_keys($arr) as $key)慢约50%至60%的
foreach($arr as $key => $notUsed).

phpmd的这个问题已经被报告在这里和那里也已经拉要求在这里.

在phpmd更新之前,你也可以使用这个小黑客

/src/main/php/PHPMD/Rule/UnusedLocalVariable.php方法中的文件collectVariables(..)(在我的情况下为第123行)替换

if ($this->isLocal($variable))
Run Code Online (Sandbox Code Playgroud)

通过

if ($this->isLocal($variable) && !($this->isChildOf($variable, 'ForeachStatement') && $variable->getName() === '$notUsed'))
Run Code Online (Sandbox Code Playgroud)

这将阻止phpmd报告foreach循环内的$notUsed 任何位置.

更新: 上面的建议假定PHP 5.6(撰写此答案时的相关版本).但是时间过去了,现在使用PHP 7.2它似乎是另一种方式.一如既往,它取决于确切的用例,但对于小于100.000键的关联数组,存储array_keys($arr)在变量中并在foreach循环中使用它更快.


小智 5

这是有效的 PHP 代码,不要修复代码,而是修复 PHP MD。PHP MD 2.2中有一个配置 并且需要这个规则:

<properties>
    <property
        name="allow-unused-foreach-variables"
        description="Allow unused variables in foreach language constructs."
        value="false" />
</properties>
Run Code Online (Sandbox Code Playgroud)