array_key_exists($key, $array) 用于检查指定的 $key 是否存在于 $array 中。如果 $key 存在,则返回 true,否则返回 false。
这个函数的优势在于它会考虑到数组中所有的键,不管值是 null 或者是 false,都可以正确判断。例如:
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-literal">null</span></span><span>, </span><span><span class="hljs-string">'b'</span></span><span> => </span><span><span class="hljs-number">0</span></span><span>];
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">array_key_exists</span></span><span>(</span><span><span class="hljs-string">'a'</span></span><span>, </span><span><span class="hljs-variable">$array</span></span><span>)); </span><span><span class="hljs-comment">// true</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">array_key_exists</span></span><span>(</span><span><span class="hljs-string">'b'</span></span><span>, </span><span><span class="hljs-variable">$array</span></span><span>)); </span><span><span class="hljs-comment">// true</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">array_key_exists</span></span><span>(</span><span><span class="hljs-string">'c'</span></span><span>, </span><span><span class="hljs-variable">$array</span></span><span>)); </span><span><span class="hljs-comment">// false</span></span><span>
</span></span>
当你在一个循环中频繁调用 array_key_exists 时,它可能会对性能产生负面影响,尤其是在处理大数组时。原因如下:
查找操作的时间复杂度:array_key_exists 的查找操作时间复杂度是 O(1),这意味着它在每次查找时的效率是常数级别的。但如果你在循环中进行多次调用,这个常数时间可能会累加,尤其是在循环次数非常大的情况下。
重复检查相同的键:如果在一个循环里对同一个数组进行多次键存在性检查,PHP 会重复执行这些检查,浪费了不必要的计算资源。
举个例子:
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-string">'b'</span></span><span> => </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-string">'c'</span></span><span> => </span><span><span class="hljs-number">3</span></span><span>];
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$array</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => </span><span><span class="hljs-variable">$value</span></span><span>) {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">array_key_exists</span></span><span>(</span><span><span class="hljs-variable">$key</span></span><span>, </span><span><span class="hljs-variable">$array</span></span><span>)) {
</span><span><span class="hljs-comment">// 执行某些操作</span></span><span>
}
}
</span></span>
在上面的代码中,array_key_exists 在每次循环时都会被调用,而在这个特定的场景下,$key 在数组中肯定存在,因此这种检查是多余的。
针对上述性能问题,下面提出几种优化方案。
如果你已经知道数组的键是存在的,完全不需要再次检查。例如,直接使用循环中的 $key 即可,无需调用 array_key_exists。
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-string">'b'</span></span><span> => </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-string">'c'</span></span><span> => </span><span><span class="hljs-number">3</span></span><span>];
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$array</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => </span><span><span class="hljs-variable">$value</span></span><span>) {
</span><span><span class="hljs-comment">// 直接使用 $key,避免调用 array_key_exists</span></span><span>
</span><span><span class="hljs-comment">// 执行某些操作</span></span><span>
}
</span></span>
如果需要在循环中检查多个键的存在性,可以在循环外部先获取数组的所有键,然后通过 in_array 或其他方式进行一次性检查。这避免了多次调用 array_key_exists。
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-string">'b'</span></span><span> => </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-string">'c'</span></span><span> => </span><span><span class="hljs-number">3</span></span><span>];
</span><span><span class="hljs-variable">$keys</span></span><span> = </span><span><span class="hljs-title function_ invoke__">array_keys</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>); </span><span><span class="hljs-comment">// 获取所有的键</span></span><span>
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$keys</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span>) {
</span><span><span class="hljs-comment">// 可以直接操作 $array[$key]</span></span><span>
}
</span></span>
isset() 是一个常用的函数,通常用于检查数组中的值是否为 null 或未定义。如果你只关心键是否存在,并且值不为 null,使用 isset() 会比 array_key_exists 更高效,因为 isset() 直接检查数组值是否设置,而 array_key_exists 会检查是否有该键,甚至考虑 null 值。
<span><span><span class="hljs-variable">$array</span></span><span> = [</span><span><span class="hljs-string">'a'</span></span><span> => </span><span><span class="hljs-literal">null</span></span><span>, </span><span><span class="hljs-string">'b'</span></span><span> => </span><span><span class="hljs-number">2</span></span><span>];
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$array</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$key</span></span><span> => </span><span><span class="hljs-variable">$value</span></span><span>) {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-keyword">isset</span></span><span>(</span><span><span class="hljs-variable">$array</span></span><span>[</span><span><span class="hljs-variable">$key</span></span><span>])) {
</span><span><span class="hljs-comment">// 执行某些操作</span></span><span>
}
}
</span></span>
在一些特殊的场景下,如果数组非常庞大,性能问题可能不仅仅是 array_key_exists 的问题,而是与数据结构本身的选择有关。在这种情况下,你可以考虑使用其他数据结构,比如 SplObjectStorage 或者 其他哈希表,这些数据结构在性能方面可能有更好的表现。
虽然 array_key_exists 是一个非常实用的函数,但在循环中频繁调用它可能会影响性能。通过避免重复检查、提前提取键、选择合适的函数(如 isset)以及使用合适的数据结构,可以有效提升 PHP 代码的执行效率。在实际开发中,务必根据具体的应用场景来选择最优的解决方案,以确保程序在处理大量数据时仍然保持高效。