53

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.

7 Answers 7

72

Here is a linear (fastest) solution:

end($a);
$last_id=key($a);
Sign up to request clarification or add additional context in comments.

4 Comments

Nice one! Is end($) necessary if you use []? I've noticed that it works without it as well
Unfortunatelly it is. A simple test shows, that the $array[] = $value; operation does not set the internal pointer of the array at the end of it. It stays where last reset, next, end or similar operation set it. Or at position 0 if it is a new array with new values appended to it.
It's a good thing in my opinion. You can iterate through $array and add more values to it at the same time. Sorry for off-topic.
Starting with PHP 7.3, array_key_last() accomplishes the same thing but without moving the internal pointer and only makes a single function call. Since this is the selected answer, it should be updated. PHP 7.3 was released in 2018.
21

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

1 Comment

Your solution is the same as the chosen answer but more detailed. People are apparently too lazy to read the better answers.
19

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.

5 Comments

That returns the value, not the index. With an array with multiple non-unique values, this can't work.
-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);.
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 No, end takes an array by reference. You can't pass the result of a function directly by reference, hence the warning.
@Christian, this would be solved by $key = end($keys = array_keys($array));. This is a good solution if you are looping through $array and therefore do not want to reset the pointer.
2

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

2 Comments

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 ;-)
Well, it works, with your second example ;-) ;; but, OK, it's only working because you've added a numerical index with the "right" value :-(
1

Just one small line:

$last_key = array_key_last($a);

Official PHP Docs

Comments

0

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

$last_id = array_pop(array_keys($a));

4 Comments

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.
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()?
This triggers an E_STRICT message since array_pop() requires a variable to be passed by reference.
@MrWhite True! I tried assigning to a variable inside the call (eg; array_pop($_ = array_keys($a))), but it didn't work either. The only solution is the error suppression operator (a bit ugly but kinda justified): @array_pop(array_keys($a))
0

On arrays with numeric keys from 0 to n-1 I always use:

$key = array_push($array, $value)-1;

It doesn't get any faster or simpler I guess. If someone got something like this that works for other arrays please let me know.

3 Comments

I know it doesn't fit your special needs, but I came here from searching google and thought someone else coming here the same way would be pleased to find it ;)
-1 This answer is wrong. array_push returns the new count of elements in the array. Your method will only work if there are no missing keys.
@Waldermort Of course I has this limit that's why I wrote "On arrays with numeric keys from 0 to n-1". That doesn't make it wrong. Maybe I should have made this more clear ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.