192
votes

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?

11
I have not run any benchmarks, no. Should I have before asking?alex
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♦
What about in_array? maettig.com/1397246220DanMan
@DanMan, in_array is O(n) because it checks the values not the keys. They are almost always going to be slower unless your n is extremely small.Pacerier
Why not $array[$key] === null?Pacerier

11 Answers

295
votes

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 exist and value is NULL.

39
votes

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%
22
votes

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.

13
votes

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.

13
votes

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'
6
votes

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

3
votes

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/

2
votes

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

0
votes

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 :)

-1
votes

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]);
});
-2
votes

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();}