What's the difference between isset() and array_key_exists()? [duplicate]
Asked Answered
php
M

8

457

How do the following two function calls compare:

isset($a['key'])

array_key_exists('key', $a)
Mary answered 9/7, 2010 at 8:14 Comment(1)
now isset returns FALSE if the value is null or empty. array_key_exists returns true even if the array index value is empty. previously isset returns TRUE even if the array index value is empty, so it can be used to check wether an array key exists.Wileywilfong
G
591

array_key_exists will definitely tell you if a key exists in an array, whereas isset will only return true if the key/variable exists and is not null.

$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

There is another important difference: isset doesn't complain when $a does not exist, while array_key_exists does.

Glairy answered 9/7, 2010 at 8:19 Comment(22)
I wish I understood chineese :)Mary
@Zacky Japanese. And it just says 'foobar'.Glairy
I always advocate only using isset() because I think that NULL should always mean exactly the same as NO VALUE or NOT SET, to avoid ambiguousness.Rhatany
Also note the implication to ArrayAccess implementations (including ArrayObject). Since array_key_exists only works on arrays, as of 5.3.0, it will fail and generate a warning if used on an ArrayAccess object, even if $obj['key'] does actually exist. isset() respects objects and arrays, so if you follow the "if it walks like a duck" mentality, using isset() lets you treat array-like variables as arrays.Bathroom
If you're ever in doubt of what is better on performance side here is a benchmark test of those two functions. juliusbeckmann.de/blog/…Slackjawed
... and preffer isset() because is faster! See https://mcmap.net/q/81472/-what-39-s-quicker-and-better-to-determine-if-an-array-key-exists-in-php or Alex link above or Patrick below, all confirm that is faster.Sainfoin
@Rhatany I have to disagree, null is still a value (or more like a state) and therefor should null always be treated as such. I almost never use isset due to the fact that one does not really know if the index exists or not.Ammonal
@Ammonal - My point is exactly that (unfortunately) in PHP null can sometimes be regarded as a 'value' and sometimes just like the absence of a value (like a function returning nothing). To mitigate this ambiguity and avoid confusion (when reading someone else's code and going "I wonder what he meant here..."), I would like to recommend the use of isset over array_key_exists, when applicable.Rhatany
null may be a regular value, but it means "no value" or "none of the above". null is not a useful value in itself, since it can only have exactly one value: null. As such it can only have exactly one meaning: "nothing". So if isset says "you have no value here", then it should be practically irrelevant whether that's because there's no such variable (i.e. no value) or because the variable is null (i.e. no value). That's the ideal you should strive for, but the practice can certainly be more nuanced.Glairy
@Zacky My Japanese is not great, but how can it say foobar if character 2 and 4 are the same.Cense
@Cense You want me to explain how Japanese works in a 600 character comment? :) It says "fūbā", which is as close as you'll get to "foobar" in Japanese.Glairy
I stopped using isset() in cases where I explicitly want to test for the existence of a key in an array, because in that case isset() logs a missing key notice if the key isn't there. Apparently, isset() is faster than array_key_exists(), but IMHO array_key_exists() is cleaner and more conducive to the program logic and, thus, worth the time hit, in most cases. Also, isset() can generate a false negative in the case where the key DOES exist and points to a NULL value.Playboy
@Reverse isset should not log anything, that's very unusual, I'd ask for code to reproduce this. If you don't want to use it because you need to distinguish between null and nonexistent, that's perfectly legitimate.Glairy
Here is an example in PHP: codepad.org/iMEOiKWKGalliard
@Glairy Appears you're right! I tested and nothing in the log. It was a decade or two ago, so maybe this was fixed?!Playboy
@Rhatany when working with databases and tables that may allow null, null is a legitimate value. isset() is wrong in this case, and should be altered to actually test if a variable exists. isset() should not be concerned about the value.Plimsoll
@HugoZink Null means the same in database context as in PHP: Absence of a real value. deceze's comment above (Aug. 9, '13) also explains it very well. If you're unsure whether a specific column exists in your table, by all means use ´array_key_exists´. But if you want to know the column value for a specific row, it should be irrelevant if the value is null because it was set to null or because the column does not exist. If not, your problem is elsewhere.Rhatany
I don't get why people seem to think one has to be better than the other. They're different; they answer different questions. Most of the time I use isset because I want to use the variable if it's available and has a value. But, in certain cases, null is a valid value. For instance, distinguishing between true (positive), false (negative), and null (not set). I also use array_key_exists somewhat frequently to check if a key is present in a set of options, and then set a default value if not present so later code won't trigger errors for undefined keys.Interlocutory
I stumbled upon this because I was trying to understand why someone would write the line if (isset($data[$name]) || array_key_exists($name, $data)) And the last comment of this answer clarifies. The line makes sure the variable $data exists before testing it's subvalues exist.Pickerel
@Pickerel For this I'd certainly write isset($data) && array_key_exists($name, $data), otherwise it's pretty pointless. Preferably you wouldn't even need isset at all if you initialized your variables properly.Glairy
Special thanks for mentioning that "another important difference"! By the way, I often use isset to check some "deep" props, like isset($webhook['leads']['update'][0]['id']) without worrying that even the $webhooks variable can be non-existing. Missing something like this in JavaScript (remember those if (webhook && webhook.leads && webhook.leads.update && webhook.leads.update[0] && webhook.leads.update[0].id) — when you have to check each level in order to avoid errors).Nonprofessional
This answer is good. I also need to share that the complexity of those function array_key_exists and isset( $array[$index] ) is O(n) but really close to O(1), though isset() is faster.Terramycin
A
144

Between array_key_exists and isset, though both are very fast [O(1)], isset is significantly faster. If this check is happening many thousands of times, you'd want to use isset.

It should be noted that they are not identical, though -- when the array key exists but the value is null, isset will return false and array_key_exists will return true. If the value may be null, you need to use array_key_exists.


As noted in comments, if your value may be null, the fast choice is:

isset($foo[$key]) || array_key_exists($key, $foo)
Assiduity answered 1/3, 2012 at 19:19 Comment(10)
could not stress this enough. just spent all day figuring out why a script was taking over 300s to execute. switched to isset(), now executes in less than 3s.Epicureanism
@celwell, I seriously suspect you actually have another problem somewhere else if simply switching array_key_exists to isset will give you a 297 seconds speed improvement.Fetter
Your comparison of execution time scared the shit out of me, I am compelled to use array_key_exists and if your comparison is true then it means I am in deep shit when we move to production servers :(Tamworth
checking if (isset($foo[$key]) || array_key_exists($key, $foo)) should give the same results as array_key_exists but faster if you know that your data will have few keys pointing to nullPropagate
Benchmark (100000 runs): array_key_exists(): 205 ms is_set(): 35ms isset() || array_key_exists(): 48msSpoofery
isset($foo[$key]) && $foo[$key] !== null might be better depending on your use caseDeckard
@Deckard isset($foo[$key]) implies $foo[$key] !== null, so this test makes no sense!Poster
That's true. Honestly no clue what I was thinking when I said that.Deckard
Or simply use: isset($foo[$key]) || array_key_exists($key, $foo)Iceman
More benchmark info from @MarekSkiba comment is here (where it was copied from): php.net/manual/en/function.array-key-exists.php#107786Pate
I
19

The main difference when working on arrays is that array_key_exists returns true when the value is null, while isset will return false when the array value is set to null.

See the PHP documentation for isset().

Impressionism answered 9/7, 2010 at 8:22 Comment(2)
isset returns false and not null.Cleave
Corrected, though of course deceze has the more complete answer by now.Impressionism
A
15

Answer to an old question as no answer here seem to address the 'warning' problem (explanation follows)

Basically, in this case of checking if a key exists in an array, isset

  • tells if the expression (array) is defined, and the key is set
  • no warning or error if the var is not defined, not an array ...
  • but returns false if the value for that key is null

and array_key_exists

  • tells if a key exists in an array as the name implies
  • but gives a warning if the array parameter is not an array

So how do we check if a key exists which value may be null in a variable

  • that may or may not be an array
  • (or similarly is a multidimensional array for which the key check happens at dim 2 and dim 1 value may not be an array for the 1st dim (etc...))

without getting a warning, without missing the existing key when its value is null (what were the PHP devs thinking would also be an interesting question, but certainly not relevant on SO). And of course we don't want to use @

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

It seems is_array should be involved in the equation, but it gives a warning if $var is not defined, so that could be a solution:

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

which is likely to be faster if the tests are mainly on non-null values. Otherwise for an array with mostly null values

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

will do the work.

Amie answered 23/4, 2015 at 8:48 Comment(0)
P
11

The PHP function array_key_exists() determines if a particular key, or numerical index, exists for an element of an array. However, if you want to determine if a key exists and is associated with a value, the PHP language construct isset() can tell you that (and that the value is not null). array_key_exists()cannot return information about the value of a key/index.

Pingpingpong answered 29/5, 2014 at 19:59 Comment(0)
A
7

Function isset() is faster, check http://www.php.net/manual/en/function.array-key-exists.php#82867

Amalekite answered 9/7, 2010 at 8:17 Comment(2)
True but you have to keep in mind that isset() will return false if the variable is set but to the value of "null"Sipple
sandbox.onlinephpfunctions.com/code/…Erased
S
4

Complementing (as an algebraic curiosity) the @deceze answer with the @ operator, and indicating cases where is "better" to use @ ... Not really better if you need (no log and) micro-performance optimization:

  • array_key_exists: is true if a key exists in an array;
  • isset: is true if the key/variable exists and is not null [faster than array_key_exists];
  • @$array['key']: is true if the key/variable exists and is not (null or '' or 0); [so much slower?]
$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: you can change/correct/complement this text, it is a Wiki.

Sainfoin answered 9/7, 2010 at 8:14 Comment(5)
Note, it is never better to use the @ operator.Thimbu
@Bracketworks, "Never"(?) it is a strong word for Science or Programming, even for Einstein or Newton... For me it is a little performance problem only. I use it because is short to say $x = @$_GET['x'];, than $x = array_key_exists('x',$_GET)? $_GET['x']: '';. See this question in order to decide by yourself.Sainfoin
No, it really is "never" better to use the @ operator, especially when dereferencing arrays. isset() or array_key_exists() communicate the intent of the code, and don't misuse an already inherently misusable operator. Obviously you don't need to convince me, but if you can provide an instance in which the @ operator is measurably better in performance, or communicates the intent of the code more succinctly than an alternative, I'll gladly change my tone.Thimbu
@Peter Krauss: what about when you use custom error handler? my logs will fill with "key does not exist". And, usually, frameworks use custom error handlers. Not to mention that your apache error log will fill if you are not in error_reporting(0).Lemuelah
Answering @Lemuelah and others: the text is a Wiki, and is for "algebraic curiosity"... Please edit it to change/correct/complement (ex. by indicating when error_log file is filled with @ occurrences and when not).Sainfoin
B
0

The two are not exactly the same. I couldn't remember the exact differences, but they are outlined very well in What's quicker and better to determine if an array key exists in PHP?.

The common consensus seems to be to use isset whenever possible, because it is a language construct and therefore faster. However, the differences should be outlined above.

Brotherhood answered 9/7, 2010 at 8:18 Comment(2)
The speed difference between the two should be negligible.Jeanettajeanette
I am not as sure in large loops. You might still be right, and I would need to benchmark, but small savings can add up in loops. For most practical uses, the difference is, like you say, negligible.Brotherhood

© 2022 - 2024 — McMap. All rights reserved.