views:

71

answers:

4

It's as easy as the title sounds; I need to get the index/key of the last inserted item. Why is this difficult? See the following two code samples:

$a=array();
echo 'res='.($a[]='aaa').' - '.(count($a)-1).'<br>';
echo 'res='.($a[]='bbb').' - '.(count($a)-1).'<br>';
echo 'res='.($a[]='aaa').' - '.(count($a)-1).'<br>';
die('<pre>'.print_r($a,true).'</pre>');

Writes:

res=aaa - 0
res=bbb - 1
res=aaa - 2
Array (
    [0] => aaa
    [1] => bbb
    [2] => aaa
)

Sure, that seems to work fine, but see this:

$a=array();
echo 'res='.($a[]='aaa').' - '.(count($a)-1).'<br>';
echo 'res='.($a[2]='bbb').' - '.(count($a)-1).'<br>';
echo 'res='.($a[]='aaa').' - '.(count($a)-1).'<br>';
die('<pre>'.print_r($a,true).'</pre>');

Writes:

res=aaa - 0
res=bbb - 1       <- wrong!
res=aaa - 2       <- wrong!
Array (
    [0] => aaa
    [2] => bbb    <- real key
    [3] => aaa    <- real key
)

So in short, the popular workaround "count($array)-1" is flawed.

+3  A: 

You can use the end() function to get the last element in an array, and array_keys() to return an array of the array-keys. Confusing. In practice, it works like this:

$key = end(array_keys($array));

Credit goes to hollsk in the comments.

Sam152
That returns the value, not the index. With an array with multiple non-unique values, this can't work.
Christian Sciberras
Of course it can. $key = end(array_keys($array));
hollsk
hollsk - Even though your code is correct, that statement is clearly false. It's like saying "of course you can get moon dust...you just need to be there". Even in your code, end() returns the last value, which happened to be an array of keys.
Christian Sciberras
-1 You shouldn't pass a value to `end`. This raises a strict warning. The correct answer is the one given by VolkerK: `end($array); key($array);`.
Artefacto
The end function takes an array as its first and only parameter, and the array_keys function returns an array. This code is perfectly valid.
Sam152
A: 

Bah, looks like I've found the answer by myself:

$last_id=array_pop(array_keys($a));
Christian Sciberras
Are you sure this is what you want? array_pop will pop the item off the array and then return its value which is perhaps not helpful if you need the full array for anything else later. end with array_keys will do what you want while leaving your array unmolested.
hollsk
That works on a different array than $a. array_keys() returns a new array, and I'm free to do what I want with it since this array is completely temporary. Perhaps you should check the documentation on array_keys()?
Christian Sciberras
+1  A: 

If you are only working with numerical indexes for your array, the last auto-generated index will always be the biggest array key of the array.

So, for auto-generated indexes, using something like max(array_keys($a)) should work.

For example, this :

$a=array();
echo 'res='.($a[]='aaa').' - '.(max(array_keys($a))).'<br>';
echo 'res='.($a[2]='bbb').' - '.(max(array_keys($a))).'<br>';
echo 'res='.($a[]='aaa').' - '.(max(array_keys($a))).'<br>';
die('<pre>'.print_r($a,true).'</pre>');

Would get you :

res=aaa - 0
res=bbb - 2
res=aaa - 3

Array
(
    [0] => aaa
    [2] => bbb
    [3] => aaa
)


But note that this will not work for situations when you are the one specifying the index...

Pascal MARTIN
Which is why I provided the second example. I clearly specified there's the possibility of keys being set, being integer or not. Sorry better luck next time ;-)
Christian Sciberras
Well, it works, with your second example ;-) ;; but, OK, it's only working because you've added a numerical index with the "right" value :-(
Pascal MARTIN
+1  A: 

You can use key($a) together with end($a)

$a=array();
$a[]='aaa'; foo($a);
$a[3]='bbb'; foo($a);
$a['foo']='ccc'; foo($a);
$a[]='ddd'; foo($a);

function foo(array $a) {
  end($a);
  echo 'count: ', count($a), ' last key: ', key($a), "\n";
}

prints

count: 1 last key: 0
count: 2 last key: 3
count: 3 last key: foo
count: 4 last key: 4
VolkerK