php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #47330 key return value should be specified
Submitted: 2009-02-06 16:47 UTC Modified: 2009-08-27 04:53 UTC
From: thuejk at gmail dot com Assigned:
Status: Closed Package: Documentation problem
PHP Version: Irrelevant OS: All
Private report: No CVE-ID: None
 [2009-02-06 16:47 UTC] thuejk at gmail dot com
Description:
------------
Currently there is no documented way to check whether an array iterator is pointing beyond the end of the array.

It would be nice if key($array) could be counted on to return null if that was the case.

key does return null in practice, however the documentation does not specify the fact, making me fear that the behaviour could change in the future.

See also http://dk.php.net/manual/en/function.key.php


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-08-26 07:24 UTC] torben@php.net
key() also returns NULL if the array index currently being examined contains NULL, and therefore gives no useful information as to whether the end of the array has been passed or not.

To successfully traverse the array, key() is not the appropriate method. Either of the following will server you better:

foreach ($arr as $key => $val) {
    echo "Got $key => $val\n";
}

or 

reset($arr);
while (list($key, $val) = each($arr)) {
    echo "$key => $val\n";
}


 [2009-08-26 08:35 UTC] thuejk at gmail dot com
Nope, not true. The code

<?php
  $array = Array(0 => null);
  reset($array);
  var_dump(current($array));
  var_dump(key($array));
?>

Prints out
  int(1)
  int(0)

But yes,
<?php
if (each($array) === false) {
  $beyond = true;
} else {
  $beyond = false;
  prev($array);
}
?>
is the same as
<?php
$beyond = key($array) === null;
?>
Just not as handy.

I know about the 
foreach ($arr as $key => $val) {
    echo "Got $key => $val\n";
}
syntax, but sometimes you need the array iterators, like the following function:
<?php
  //A mergesort which preserves keys.
  //The naming is like the "a" in build-in function asort()
  public static function amergesort(Array &$array, $cmp_function='strcmp') {
    // Arrays of size < 2 require no action.
    if (count($array) < 2) return;
    // Split the array in half
    $halfway = count($array) / 2;
    $array1 = array_slice($array, 0,        $halfway,       true);
    $array2 = array_slice($array, $halfway, sizeof($array), true);
    // Recurse to sort the two halves
    self::amergesort($array1, $cmp_function);
    self::amergesort($array2, $cmp_function);
    // If all of $array1 is <= all of $array2, just append them.
    $value1 = end($array1);
    $key1 = key($array);
    reset($array1);
    $value2 = reset($array2);
    $keys2 = key($array2);
    if (call_user_func($cmp_function, $value1, $value2) < 1) {
      $array = $array1;
      //mergesort will renumber numeric keys
      foreach ($array2 as $key2 => $value2) {
        $array[$key2] = $value2;
      }
      return;
    }
    // Merge the two sorted arrays into a single sorted array
    $array = array();
    while (true) {
      $value1 = current($array1);
      $key1 = key($array1);
      $value2 = current($array2);
      $key2 = key($array2);
      if ($key1 === null) {
        //$array1 is empty - append array 2
        do {
          $array[$key2] = $value2;
          $value2 = next($array2);
          $key2 = key($array2);
        } while ($key2 !== null);
        break;
      } else if ($key2 === null) {
        //$array2 is empty - append array 1
        do {
          $array[$key1] = $value1;
          $value1 = next($array1);
          $key1 = key($array1);
        } while ($key1 !== null);
        break;
      } else {
        //compare elements from $array1, $array2 to see which to append
        if (call_user_func($cmp_function, $value1, $value2) < 1) {
          $array[$key1] = $value1;
          next($array1);
        } else {
          $array[$key2] = $value2;
          next($array2);
        }
      }
    }
    return;
  }
?>
 [2009-08-26 08:38 UTC] thuejk at gmail dot com
Umm, sorry, typo, the code 

<?php
  $array = Array(0 => null);
  reset($array);
  var_dump(current($array));
  var_dump(key($array));
?>

of course prints out
  int(null)
  int(0)
 [2009-08-26 08:58 UTC] thuejk at gmail dot com
>key() also returns NULL if the array index currently being examined
>contains NULL, and therefore gives no useful information as to whether
>the end of the array has been passed or not.

And anyway, if theis is a case it is an even worse bug than my original report, since the manual states 

Return Values: Returns the index.

It specifically does NOT say anything about returning null if the array value is null.
 [2009-08-26 16:20 UTC] torben@php.net
You're correct that key() does not return NULL if the array value is NULL, but that's not what I said; I said "array index", not "array value".

That said, I must apologize as I was also incorrect: key() does not in fact return NULL if the array index is NULL; it returns the empty string. That's what I get for posting when I should have gone to bed instead.

Re-opening.


 [2009-08-26 16:26 UTC] thuejk at gmail dot com
Ah, I misunderstood.

Null is not a possible array index, hence my confusion. Array indices are always strings or ints. (as I found out when debugging a face of a float being silently truncated to int when used as an array index...)
 [2009-08-26 16:31 UTC] torben@php.net
Yes, I should have said "defined as NULL" instead of "is NULL". You can define it as NULL but it will be silently converted to the empty string.
 [2009-08-27 04:48 UTC] svn@php.net
Automatic comment from SVN on behalf of torben
Revision: http://svn.php.net/viewvc/?view=revision&revision=287789
Log: Document the fact that key() returns NULL when the array pointer is out of bounds.
Addresses Bug #47330.
 [2009-08-27 04:53 UTC] torben@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.

I went ahead and documented this since it's been the behaviour since the first commit of PHP 4 (PHP 3 had no NULL type).
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Jun 16 12:00:02 2026 UTC