452

How do the following two function calls compare:

isset($a['key'])

array_key_exists('key', $a)
Zacky112
  • 8,679
  • 9
  • 34
  • 36
  • 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. – cristy Jan 26 '16 at 03:16

8 Answers8

585

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.

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
deceze
  • 510,633
  • 85
  • 743
  • 889
  • 65
    I wish I understood chineese :) – Zacky112 Jul 09 '10 at 10:30
  • 245
    @Zacky Japanese. And it just says 'foobar'. – deceze Jul 09 '10 at 12:03
  • 24
    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. – jgivoni Mar 27 '12 at 09:50
  • 17
    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. – Mark Apr 11 '12 at 20:40
  • 2
    If you're ever in doubt of what is better on performance side here is a benchmark test of those two functions. http://juliusbeckmann.de/blog/php-benchmark-isset-or-array_key_exists.html – Alexxandar Oct 17 '12 at 16:20
  • ... and preffer `isset()` because is faster! See http://stackoverflow.com/a/700264/287948 or Alex link above or Patrick below, all confirm that is faster. – Peter Krauss Jul 30 '13 at 10:09
  • 2
    @jgivoni 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**. – Daniel Aug 08 '13 at 08:30
  • @Daniel - 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. – jgivoni Aug 09 '13 at 09:37
  • 2
    `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. – deceze Aug 09 '13 at 09:41
  • @Zacky My Japanese is not great, but how can it say `foobar` if character 2 and 4 are the same. – Wilt Apr 01 '15 at 08:03
  • 13
    @Wilt 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. – deceze Apr 01 '15 at 08:05
  • 1
    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. – ReverseEMF Apr 11 '15 at 02:52
  • @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. – deceze Apr 11 '15 at 10:55
  • 1
    Here is an example in PHP: http://codepad.org/iMEOiKWK – Armin Apr 13 '15 at 10:06
  • @deceze Appears you're right! I tested and nothing in the log. It was a decade or two ago, so maybe this was fixed?! – ReverseEMF May 27 '15 at 16:05
  • @jgivoni 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. –  Oct 30 '15 at 13:07
  • @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. – jgivoni Nov 02 '15 at 17:15
  • 4
    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. – Nate Jan 06 '16 at 18:58
  • 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. – danielson317 Jan 19 '16 at 17:41
  • 1
    @danielson317 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. – deceze Jan 19 '16 at 18:23
  • 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). – pilat Jul 03 '20 at 12:52
  • 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. – Syed Imran Ertaza Jun 17 '23 at 15:28
143

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)
Patrick Fisher
  • 7,926
  • 5
  • 35
  • 28
  • 18
    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. – celwell Jul 12 '13 at 01:21
  • 27
    @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. – Pacerier Mar 08 '15 at 14:41
  • 4
    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 :( – Metabolic Feb 18 '16 at 13:33
  • 12
    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 `null` – flagg19 Jul 21 '16 at 09:43
  • 16
    Benchmark (100000 runs): `array_key_exists()`: 205 ms `is_set()`: 35ms `isset() || array_key_exists()`: 48ms – Marek Skiba Nov 09 '16 at 08:59
  • 1
    `isset($foo[$key]) && $foo[$key] !== null` might be better depending on your use case – dtbarne Sep 20 '18 at 21:40
  • 2
    @dtbarne `isset($foo[$key])` implies `$foo[$key] !== null`, so this test makes no sense! – BenMorel Feb 07 '19 at 13:45
  • That's true. Honestly no clue what I was thinking when I said that. – dtbarne Feb 08 '19 at 14:31
  • Or simply use: `isset($foo[$key]) || array_key_exists($key, $foo)` – ale5000 Mar 27 '19 at 10:50
  • More benchmark info from @MarekSkiba comment is here (where it was copied from): https://www.php.net/manual/en/function.array-key-exists.php#107786 – Martin Oct 13 '20 at 12:02
18

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().

Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
Matijs
  • 2,533
  • 20
  • 24
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.

Déjà vu
  • 28,223
  • 6
  • 72
  • 100
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.

Anthony Rutledge
  • 6,980
  • 2
  • 39
  • 44
7

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

Anax
  • 9,122
  • 5
  • 34
  • 68
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.

Community
  • 1
  • 1
Peter Krauss
  • 13,174
  • 24
  • 167
  • 304
  • 10
    Note, it is **never** better to use the `@` operator. – Dan Lugg May 16 '13 at 17:06
  • @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](http://stackoverflow.com/q/1032161/287948) in order to decide by yourself. – Peter Krauss May 21 '13 at 12:22
  • 3
    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. – Dan Lugg May 21 '13 at 12:58
  • @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)`. – machineaddict Jul 10 '14 at 07:51
  • Answering @machineaddict 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). – Peter Krauss Jul 10 '14 at 16:19
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.

Community
  • 1
  • 1
TNi
  • 16,070
  • 3
  • 22
  • 20
  • 1
    The speed difference between the two should be negligible. – Gordon Jul 09 '10 at 09:05
  • 1
    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. – TNi Jul 09 '10 at 10:00