244

Consider these 2 examples...

$key = 'jim';

// example 1
if (isset($array[$key])) {
    // ...
}

// example 2    
if (array_key_exists($key, $array)) {
    // ...
}

I'm interested in knowing if either of these are better. I've always used the first, but have seen a lot of people use the second example on this site.

So, which is better? Faster? Clearer intent?

Pacerier
  • 86,231
  • 106
  • 366
  • 634
alex
  • 479,566
  • 201
  • 878
  • 984
  • I have not run any benchmarks, no. Should I have before asking? – alex Mar 31 '09 at 06:27
  • 4
    `isset` will never behave exactly like `array_key_exists`, the code example that supposedly makes it behave identically throws a Notice if the key doesn't exist. – deceze Jul 09 '10 at 08:30
  • What about `in_array`? http://maettig.com/1397246220 – DanMan Sep 02 '14 at 08:58
  • 1
    @DanMan, `in_array` is [`O(n)`](http://stackoverflow.com/questions/1459739/php-serverhttp-host-vs-serverserver-name-am-i-understanding-the-ma/1459794#comment46040847_1459794) because it checks the values not the keys. They are almost always going to be slower unless your `n` is extremely small. – Pacerier Mar 08 '15 at 19:45
  • Why not `$array[$key] === null`? – Pacerier Oct 02 '17 at 02:17
  • @Pacerier They key can be defined and set to `null`, so I guess it's a different check. – alex Oct 04 '17 at 07:46

11 Answers11

376

isset() is faster, but it's not the same as array_key_exists().

array_key_exists() purely checks if the key exists, even if the value is NULL.

Whereas isset() will return false if the key exists and value is NULL.

danronmoon
  • 3,814
  • 5
  • 34
  • 56
Richard Levasseur
  • 14,562
  • 6
  • 50
  • 63
  • 20
    Do you have specific resources claiming isset is faster? – Francesco Pasa Jul 28 '16 at 07:02
  • 3
    @Francesco Pasa Just think about it a little bit. `isset` is not an array search function, it only checks the presence of a variable in the symbol table and will not iterate over the array. `array_key_exists` on the other hand will iterate/search for the keys in the first dimension of the specified array. – Rain Apr 22 '20 at 03:16
  • 6
    @Rain I'm pretty sure `array_key_exists()` will only check if the key is in the array, which means it won't do a search since it's a hash table. – Francesco Pasa Apr 22 '20 at 06:02
  • 4
    yeah, thinking about it more, `isset` has to do more work, because it has to check whether the key exists AND whether it has a value. That said, I'm sure that when *typing*, `iset` is faster, so that's what I'm going for ;) – Stijn de Witt Apr 11 '22 at 19:21
51

If you are interested in some tests I've done recently:

https://stackoverflow.com/a/21759158/520857

Summary:

| Method Name                              | Run time             | Difference
=========================================================================================
| NonExistant::noCheckingTest()            | 0.86004090309143     | +18491.315775911%
| NonExistant::emptyTest()                 | 0.0046701431274414   | +0.95346080503016%
| NonExistant::isnullTest()                | 0.88424181938171     | +19014.461681183%
| NonExistant::issetTest()                 | 0.0046260356903076   | Fastest
| NonExistant::arrayKeyExistsTest()        | 1.9001779556274      | +209.73055713%
Community
  • 1
  • 1
Populus
  • 7,470
  • 3
  • 38
  • 54
  • 3
    IMPORTANT: the arrayKeyExists timing was discovered to be very wrong -- it was checking value not key -- follow that link for the revised timing in 7.1, which is *much* better. (Would also be better in earlier php versions, if Populus redid that test.) – ToolmakerSteve Apr 25 '19 at 17:13
37

With Php 7 gives the possibility to use the Null Coalescing Operator.

The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.

So now you can assign a default value in case the value is null or if the key does not exist :

$var = $array[$key] ?? 'default value'
John
  • 4,711
  • 9
  • 51
  • 101
  • I'm about to update some legacy code and planning to change both undefined array key's and stuff wrapped in if(isset($array['key'])) { $value = $array['key']; } using the ?? method. I assume this method should outperform isset and is the cleanest way to write this but curious on thoughts on this now especially under php 8+. Any downside to this method? – Spencer Fraise Apr 15 '22 at 18:12
  • @SpencerFraise it's ok to use this. But now with PHP 8 you can use the nullsafe operator : `$session?->user?->getAddress()?->country` it's another logic to implement in your code – John Apr 17 '22 at 08:59
  • thanks! I'll stick with the ?? method for now to ensure we still have some backwards compatibility but good to know we can use the nullsafe op on 8+. – Spencer Fraise Apr 18 '22 at 19:02
22

Well, the main difference is that isset() will not return true for array keys that correspond to a null value, while array_key_exists() does.

Running a small benchmark shows that isset() it's faster but it may not be entirely accurate.

alex
  • 479,566
  • 201
  • 878
  • 984
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 1
    Can you run the benchmark again with the more correct "(isset($array[$i]) || $array[$i] === null)"? – Tomalak Mar 31 '09 at 06:36
  • Oh, and would you post an indication how much performance difference the two variants show? Thanks! – Tomalak Mar 31 '09 at 06:40
  • Did you consider leaving out the `$arraykeyexists_result[]` lines? That’s irrelevant in this case. – Gumbo Mar 31 '09 at 06:43
  • 1
    @Tomalak, I ran the example you suggested, and it states that array_key_exists() is faster than isset() with the || operator. http://codepad.org/5qyvS93x – alex Mar 31 '09 at 06:53
  • Tomalak: that is not more correct. They have different results, and you should use the correct one for readability. – OIS Mar 31 '09 at 07:27
  • 1
    Up from the dead... but I also re-ran the benchmark, and made a tweak so the second for loop has to initialize it's own counter and to clear the result array. It shows "isset || null" being faster. http://codepad.org/Np6oPvgS – KyleWpppd Jan 19 '12 at 21:28
  • 3
    @Tomalak, `isset($array[$i]) || $array[$i] === null` doesn't make sense because it will return `true` for every case. You'll never get false from `isset($array[$i]) || $array[$i] === null` regardless of the inputs. – Pacerier Mar 08 '15 at 22:06
17

I wanted to add my 2 cents on this question, since I was missing a middle way out.

As already told isset() will evaluate the value of the key so it will return false if that value is null where array_key_exists() will only check if the key exists in the array.


I've ran a simple benchmark using PHP 7, the results shown is the time it took to finish the iteration:

$a = [null, true];

isset($a[0])                            # 0.3258841  - false
isset($a[1])                            # 0.28261614 - true
isset($a[2])                            # 0.26198816 - false

array_key_exists(0, $a)                 # 0.46202087 - true
array_key_exists(1, $a)                 # 0.43063688 - true
array_key_exists(2, $a)                 # 0.37593913 - false

isset($a[0]) || array_key_exists(0, $a) # 0.66342998 - true
isset($a[1]) || array_key_exists(1, $a) # 0.28389215 - true
isset($a[2]) || array_key_exists(2, $a) # 0.55677581 - false

array_key_isset(0, $a)                  # 1.17933798 - true
array_key_isset(1, $a)                  # 0.70253706 - true
array_key_isset(2, $a)                  # 1.01110005 - false

I've added the results from this custom function with this benchmark as well for completion:

function array_key_isset($k, $a){
    return isset($a[$k]) || array_key_exists($k, $a);
}

As seen and already told isset() is fastest method but it can return false if the value is null. This could give unwanted results and usually one should use array_key_exists() if that's the case.

However there is a middle way out and that is using isset() || array_key_exists(). This code is generally using the faster function isset() and if isset() returns false only then use array_key_exists() to validate. Shown in the table above, its just as fast as plainly calling isset().

Yes, it's a bit more to write and wrapping it in a function is slower but a lot easier. If you need this for performance, checking big data, etc write it out full, otherwise if its a 1 time usage that very minor overhead in function array_key_isset() is negligible.

Xorifelse
  • 7,878
  • 1
  • 27
  • 38
7

there is a difference from php.net you'll read:

isset() does not return TRUE for array keys that correspond to a NULL value, while array_key_exists() does.

A very informal test shows array_key_exists() to be about 2.5 times slower than isset()

Brane
  • 3,257
  • 2
  • 42
  • 53
Scott Evernden
  • 39,136
  • 15
  • 78
  • 84
3

Combining isset() and is_null() give the best performance against other functions like: array_key_exists(), isset(), isset() + array_key_exists(), is_null(), isset() + is_null(), the only issue here is the function will not only return false if the key doesn't exist, but even the key exist and has a null value.

Benchmark script:

<?php
  $a = array('a' => 4, 'e' => null)

  $s = microtime(true); 
  for($i=0; $i<=100000; $i++) { 
    $t = (isset($a['a'])) && (is_null($a['a'])); //true 
    $t = (isset($a['f'])) && (is_null($a['f'])); //false
    $t = (isset($a['e'])) && (is_null($a['e']));; //false 
  } 

  $e = microtime(true); 
  echo 'isset() + is_null() : ' , ($e-$s)."<br><br>";
?>

Credit: https://web.archive.org/web/20140222232248/zomeoff.com/php-fast-way-to-determine-a-key-elements-existance-in-an-array/

TiLogic
  • 199
  • 1
  • 2
  • 10
H Aßdøµ
  • 2,925
  • 4
  • 26
  • 37
1

As to "faster": Try it (my money is on array_key_exists(), but I can't try it right now).

As to "clearer in the intent": array_key_exists()

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • 4
    isset() is actually significantly faster if you don't care about the null behavior (see http://www.randombenchmarks.com/?p=29). – Matt Kantor Jul 31 '09 at 14:46
0

I wanted to add that you can also use isset to search an array with unique elements. It is lot faster than using in_array, array_search or array_key_exists. You can just flip the array using array_flip and use isset to check if value exists in the array.

<?php

$numbers = [];
for ($i = 0; $i < 1000000; $i++) {
    $numbers[] = random_int("9000000000", "9999999999");
}

function evaluatePerformance($name, $callback)
{
    global $numbers;
    $timeStart = microtime(true);

    $result = $callback("1234567890", $numbers) ? 'true' : 'false';

    $timeEnd = microtime(true);
    $executionTime =  number_format($timeEnd - $timeStart, 9);

    echo  "{$name} result is {$result} and it took {$executionTime} seconds. <br>";
}

// Took 0.038895845 seconds.
evaluatePerformance("in_array", function ($needle, $haystack) {
    return in_array($needle, $haystack);
});

// Took 0.035454988 seconds.
evaluatePerformance("array_search", function ($needle, $haystack) {
    return array_search($needle, $haystack);
});

$numbers = array_flip($numbers);

// Took 0.000024080 seconds.
evaluatePerformance("array_key_exists", function ($needle, $haystack) {
    return array_key_exists($needle, $haystack);
});

// Took 0.000013113 seconds.
evaluatePerformance("isset", function ($needle, $haystack) {
    return isset($haystack[$needle]);
});
Ravi Patel
  • 2,136
  • 3
  • 32
  • 48
0

Obviously the second example is clearer in intent, there's no question about it. To figure out what example #1 does, you need to be familiar with PHP's variable initialization idiosyncracies - and then you'll find out that it functions differently for null values, and so on.

As to which is faster - I don't intend to speculate - run either in a tight loop a few hundred thousand times on your PHP version and you'll find out :)

Mihai Limbășan
  • 64,368
  • 4
  • 48
  • 59
-2

Your code, isset($array[$i]) || $array[$i] === null, will return true in every case, even if the key does not exists (and yield a undefined index notice). For the best performance what you'd want is if (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}

Niclas Larsson
  • 1,317
  • 8
  • 13
Gator
  • 5
  • 1