isset() 和 array_key_exists() 有啥区别? [复制]

Posted

技术标签:

【中文标题】isset() 和 array_key_exists() 有啥区别? [复制]【英文标题】:What's the difference between isset() and array_key_exists()? [duplicate]isset() 和 array_key_exists() 有什么区别? [复制] 【发布时间】:2011-03-13 18:16:16 【问题描述】:

以下两个函数调用如何比较:

isset($a['key'])

array_key_exists('key', $a)

【问题讨论】:

现在如果值为 null 或空,则 isset 返回 FALSE。即使数组索引值为空,array_key_exists 也会返回 true。之前 isset 即使数组索引值为空也会返回 TRUE,因此它可以用来检查数组键是否存在。 【参考方案1】:

函数isset()更快,检查http://www.php.net/manual/en/function.array-key-exists.php#82867

【讨论】:

True 但您必须记住,如果变量设置为“null”的值,isset() 将返回 false sandbox.onlinephpfunctions.com/code/…【参考方案2】:

两者并不完全相同。我不记得确切的区别,但它们在What's quicker and better to determine if an array key exists in PHP? 中有很好的概述。

普遍的共识似乎是尽可能使用 isset,因为它是一种语言结构,因此速度更快。但是,应该在上面概述差异。

【讨论】:

两者的速度差异应该可以忽略不计。 我在大循环中不太确定。您可能仍然是对的,我需要进行基准测试,但是小额节省可以在循环中累加。对于大多数实际用途,正如您所说,差异可以忽略不计。【参考方案3】:

array_key_exists 肯定会告诉你一个键是否存在于数组中,而isset 只会在键/变量存在而不是null 时返回true。。 p>

$a = array('key1' => 'フーバー', 'key2' => null);

isset($a['key1']);             // true
array_key_exists('key1', $a);  // true

isset($a['key2']);             // false
array_key_exists('key2', $a);  // true

还有一个重要的区别:isset$a 不存在时不会抱怨,而array_key_exists 会抱怨。

【讨论】:

我希望我能理解中文:) @Zacky 日语。它只是说'foobar'。 我一直主张只使用isset(),因为我认为NULL应该总是与NO VALUE或NOT SET完全一样,以避免歧义。 还要注意对 ArrayAccess 实现(包括 ArrayObject)的影响。由于 array_key_exists 仅适用于数组,从 5.3.0 开始,如果在 ArrayAccess 对象上使用它会失败并生成警告,即使 $obj['key'] 确实存在。 isset() 尊重对象和数组,所以如果你遵循“如果它像鸭子一样走路”的心态,使用 isset() 可以让你将类似数组的变量视为数组。 @Wilt 你想让我在 600 个字符的评论中解释日语的工作原理吗? :) 上面写着“fūbā”,与日语中的“foobar”最接近。【参考方案4】:

处理数组时的主要区别在于array_key_exists 在值为null 时返回true,而isset 在数组值为null 时将返回false

请参阅 PHP 文档站点上的 isset。

【讨论】:

isset 返回 false 而不是 null 已更正,当然 deceze 现在有更完整的答案。【参考方案5】:

array_key_existsisset 之间,虽然两者都非常快[O(1)]isset 明显更快。如果此检查发生数千次,您可能需要使用isset

需要注意的是,它们并不相同——当数组键存在但值为null时,isset将返回falsearray_key_exists将返回true。如果值可能是null,则需要使用array_key_exists


如 cmets 中所述,如果您的值可能是 null,则快速选择是:

isset($foo[$key]) || array_key_exists($key, $foo)

【讨论】:

不能强调这一点。只是花了一整天的时间来弄清楚为什么一个脚本需要 300 多秒才能执行。切换到 isset(),现在执行不到 3 秒。 @celwell,如果简单地将array_key_exists 切换到isset 会给您带来 297 秒的速度提升,我严重怀疑您实际上在其他地方还有其他问题。 你对执行时间的比较把我吓坏了,我不得不使用 array_key_exists,如果你的比较是真的,那么这意味着当我们转移到生产服务器时我陷入了困境:(跨度> 检查if (isset($foo[$key]) || array_key_exists($key, $foo)) 应该得到与array_key_exists 相同的结果,但如果您知道您的数据将有很少的键指向null,则速度会更快 基准测试(100000 次运行):array_key_exists():205 毫秒 is_set():35 毫秒 isset() || array_key_exists():48 毫秒【参考方案6】:

@ 运算符补充(作为代数好奇心)@deceze 答案,并指出使用@ 的“更好”的情况......如果你需要(没有日志和)微性能优化:

array_key_exists:如果数组中存在键,则为真; isset:如果键/变量存在而不是null,则为true [faster than array_key_exists]; @$array['key']:如果键/变量存在而不是(null 或 '' 或 0),则为 true; [这么慢?]
$a = array('k1' => 'HELLO', 'k2' => null, 'k3' => '', 'k4' => 0);

print isset($a['k1'])? "OK $a[k1].": 'NO VALUE.';            // OK
print array_key_exists('k1', $a)? "OK $a[k1].": 'NO VALUE.'; // OK
print @$a['k1']? "OK $a[k1].": 'NO VALUE.';                  // OK
// outputs OK HELLO.  OK HELLO. OK HELLO.

print isset($a['k2'])? "OK $a[k2].": 'NO VALUE.';            // NO
print array_key_exists('k2', $a)? "OK $a[k2].": 'NO VALUE.'; // OK
print @$a['k2']? "OK $a[k2].": 'NO VALUE.';                  // NO
// outputs NO VALUE.  OK .  NO VALUE.

print isset($a['k3'])? "OK $a[k3].": 'NO VALUE.';            // OK
print array_key_exists('k3', $a)? "OK $a[k3].": 'NO VALUE.'; // OK
print @$a['k3']? "OK $a[k3].": 'NO VALUE.';                  // NO
// outputs OK . OK . NO VALUE.

print isset($a['k4'])? "OK $a[k4].": 'NO VALUE.';            // OK
print array_key_exists('k4', $a)? "OK $a[k4].": 'NO VALUE.'; // OK
print @$a['k4']? "OK $a[k4].": 'NO VALUE.';                  // NO
// outputs OK 0. OK 0. NO VALUE

PS:您可以更改/更正/补充此文本,它是一个 Wiki。

【讨论】:

注意,使用@ 运算符永远更好。 @Bracketworks,“从不”(?)它是科学或编程的一个强词,即使对于爱因斯坦或牛顿......对我来说,这只是一个小性能问题。我使用它是因为$x = @$_GET['x'];$x = array_key_exists('x',$_GET)? $_GET['x']: ''; 更短。请参阅this question 以自行决定。 不,使用@ 运算符确实“永远”不会更好,尤其是在取消引用数组时。 isset()array_key_exists() 传达代码的意图,不要滥用已经固有的误用运算符。显然你不需要说服我,但如果你能提供一个实例,其中@ 运算符的性能明显更好,或者比替代方案更简洁地传达代码的意图,我很乐意改变我的语气. @Peter Krauss:当您使用自定义错误处理程序时会怎样?我的日志将填充“密钥不存在”。而且,通常,框架使用自定义错误处理程序。更不用说如果您不在 error_reporting(0) 中,您的 apache 错误日志将被填满。 回答@machineaddict 和其他人:该文本是一个Wiki,并且是为了“代数好奇心”......请编辑它以更改/更正/补充(例如通过指示何时填充error_log文件@ 出现和何时不出现)。【参考方案7】:

PHP 函数array_key_exists() 确定数组元素是否存在特定键或数字索引。但是,如果您想确定 key 是否存在并与null)。 array_key_exists()无法返回有关键/索引值的信息。

【讨论】:

【参考方案8】:

回答一个老问题,因为这里没有答案似乎解决了“警告”问题(解释如下)

基本上,在这种检查数组中是否存在键的情况下,isset

判断表达式(数组)是否已定义,键是否已设置 如果 var 未定义,而不是数组,则不会发出警告或错误... but 如果该键的值为 null,则返回 false

array_key_exists

顾名思义,告诉数组中是否存在键 如果数组参数不是数组but 会给出警告

那么我们如何检查一个键是否存在,变量中的哪个值可能为空

可能是也可能不是数组 (或者类似地是一个多维数组,其键检查发生在 dim 2 并且 dim 1 值可能不是 1st dim 的数组(等等...))

没有得到警告,当它的值为 null 时不会丢失现有的键(PHP 开发人员的想法也是一个有趣的问题,但肯定与 SO 无关)。当然我们也不想使用@

isset($var[$key]);            // silent but misses null values
array_key_exists($key, $var); // works but warning if $var not defined/array

似乎is_array 应该包含在等式中,但如果未定义$var,它会发出警告,因此这可能是一个解决方案:

if (isset($var[$key]) || 
    isset($var) && is_array($var) && array_key_exists($key, $var)) ...

如果测试主要针对非空值,这可能会更快。否则对于大部分为空值的数组

if (isset($var) && is_array($var) && array_key_exists($key, $var)) ...

会做的。

【讨论】:

以上是关于isset() 和 array_key_exists() 有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

PHP 中数组函数 isset 效率比 array_key_exists 更高

深入理解PHP之isset和array_key_exists对比

php array_key_exists() 与 isset() 的区别

php array_key_exists, !empty 和 isset 无缘无故失败?

3-7 PHP内置函数之间的性能测试 microtime()测试isset()和array_key_exists执行时间

PHP isset, array_key_exists配合使用, 并解决效率问题