ChatGPT解决这个技术问题 Extra ChatGPT

What's the best way to get the last element of an array without deleting it?

Ok,

I know all about array_pop(), but that deletes the last element. What's the best way to get the last element of an array without deleting it?

EDIT: Here's a bonus:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');

or even

$array = array('a', 'b', 'c', 'd');
unset($array[2]);
echo $array[sizeof($array) - 1]; // Output: PHP Notice:  Undefined offset:  2 in - on line 4
Believe it or not popping it and putting it back on is one of the fastest ways I benchmarked doing this. $val=$array[]=array_pop($array); echo $val;
This question resulted in many options. To help myself choose, I did some comparison of most notable / distinct options and shared the results as a separate answer. (:@user2782001 suggested my favorite so far in the comment above.:) Thanks to all for contributing!
@TheodoreRSmith When PHP 7.3 is released you could consider making (this suggestion by Quasimodo's clone the 'accepted answer' (for your consideration)...

F
Flimm

Try end:

$myLastElement = end($yourArray);

Note that this doesn't just return the last element of the passed array, it also modifies the array's internal pointer, which is used by current, each, prev, and next.

For PHP >= 7.3.0:

If you are using PHP version 7.3.0 or later, you can use array_key_last, which returns the last key of the array without modifying its internal pointer. So to get the last value, you can do:

$myLastElement = $yourArray[array_key_last($yourArray)];

Use $myLastElement = end(array_values($yourArray)); and now you don't need to call reset().
@DavidMurdoch Perhaps, but it sure does churn the RAM and CPU, creating the temp array for the array values...
If your server is consuming too much RAM so that calling one simple extra function is a deal breaker, I suggest you re-examine your server's configuration and resources.
end(array_values()) will give a E_STRICT: "Only variables should be passed by reference"
Add additional parenthesis to avoid the strict warning: end((array_values($yourArray)))
P
Paul van Leeuwen

The many answers in this thread present us with many different options. To be able to choose from them I needed to understand their behavior and performance. In this answer I will share my findings with you, benchmarked against PHP versions 5.6.38, 7.2.10 and 7.3.0RC1 (expected Dec 13 2018).

The options (<<option code>>s) I will test are:

option .1. $x = array_values(array_slice($array, -1))[0]; (as suggested by rolacja)

option .2. $x = array_slice($array, -1)[0]; (as suggested by Stoutie)

option .3. $x = array_pop((array_slice($array, -1))); (as suggested by rolacja)

option .4. $x = array_pop((array_slice($array, -1, 1))); (as suggested by Westy92)

option .5. $x = end($array); reset($array); (as suggested by Iznogood)

option .6. $x = end((array_values($array))); (as suggested by TecBrat)

option .7. $x = $array[count($array)-1]; (as suggested by Mirko Pagliai)

option .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; (as suggested by thrau)

option .9. $x = $array[] = array_pop($array); (as suggested by user2782001)

option 10. $x = $array[array_key_last($array)]; (as suggested by Quasimodo's clone ; available per PHP 7.3)

(functions mentioned: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset)

The test inputs (<<input code>>s) to combine with:

null = $array = null;

empty = $array = [];

last_null = $array = ["a","b","c",null];

auto_idx = $array = ["a","b","c","d"];

shuffle = $array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";

100 = $array = []; for($i=0;$i<100;$i++) { $array[] = $i; }

100000 = $array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }

For testing I will use the 5.6.38, 7.2.10 and 7.3.0RC1 PHP docker containers like:

sudo docker run -it --rm php:5.6.38-cli-stretch php -r '<<<CODE HERE>>>'

Each combination of the above listed <<option code>>s and <<input code>>s will be run on all versions of PHP. For each test run the following code snippet is used:

<<input code>>  error_reporting(E_ALL);  <<option code>>  error_reporting(0); $before=microtime(TRUE); for($i=0;$i<100;$i++){echo ".";for($j=0;$j<100;$j++){  <<option code>>  }}; $after=microtime(TRUE); echo "\n"; var_dump($x); echo round(($after-$before)/(100*100)*1000*1000*1000);

For each run this will var_dump the last retrieved last value of the test input and print the average duration of one iteration in femtoseconds (0.000000000000001th of a second).

The results are as follows:

/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
||                                                                      ||                            T  E  S  T     I  N  P  U  T     -     5  .  6  .  3  8                            ||                             T  E  S  T     I  N  P  U  T     -     7  .  2  .  1  0                           ||                             T  E  S  T     I  N  P  U  T     -     7  .  3  .  0  R  C  1                     ||
||                                                                      ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||
||============================OPTIONS - ERRORS==========================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||
||  2.  $x = array_slice($array, -1)[0];                                ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||       W1 + W3 |             - |             - |             - |             - |             - |             - ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||       W1 + W3 |             - |             - |             - |             - |             - |             - ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  5.  $x = end($array); reset($array);                                ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||       W4 + W5 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||
||  6.  $x = end((array_values($array)));                               ||       W2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  7.  $x = $array[count($array)-1];                                   ||             - |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||            W6 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||
||  9.  $x = $array[] = array_pop($array);                              ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||
|| 10.  $x = $array[array_key_last($array)];                            ||            F1 |            F1 |            F1 |            F1 |            F1 |            F1 |            F1 ||            F2 |            F2 |            F2 |            F2 |            F2 |            F2 |            F2 ||            W8 |            N4 |            F2 |            F2 |            F2 |            F2 |            F2 ||
||========================OPTIONS - VALUE RETRIEVED=====================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  2.  $x = array_slice($array, -1)[0];                                ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  5.  $x = end($array); reset($array);                                ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  6.  $x = end((array_values($array)));                               ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  7.  $x = $array[count($array)-1];                                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  9.  $x = $array[] = array_pop($array);                              ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||
||=================OPTIONS - FEMTOSECONDS PER ITERATION=================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||           803 |           466 |           390 |           384 |           373 |           764 |     1.046.642 ||           691 |           252 |           101 |           128 |            93 |           170 |        89.028 ||           695 |           235 |            90 |            97 |            95 |           188 |        87.991 ||
||  2.  $x = array_slice($array, -1)[0];                                ||           414 |           349 |           252 |           248 |           246 |           604 |     1.038.074 ||           373 |           249 |            85 |            91 |            90 |           164 |        90.750 ||           367 |           224 |            78 |            85 |            80 |           155 |        86.141 ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||           724 |           228 |           323 |           318 |           350 |           673 |     1.042.263 ||           988 |           285 |           309 |           317 |           331 |           401 |        88.363 ||           877 |           266 |           298 |           300 |           326 |           403 |        87.279 ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||           734 |           266 |           358 |           356 |           349 |           699 |     1.050.101 ||           887 |           288 |           316 |           322 |           314 |           408 |        88.402 ||           935 |           268 |           335 |           315 |           313 |           403 |        86.445 ||
||  5.  $x = end($array); reset($array);                                ||           715 |           186 |           185 |           180 |           176 |           185 |           172 ||           674 |            73 |            69 |            70 |            66 |            65 |            70 ||           693 |            65 |            85 |            74 |            68 |            70 |            69 ||
||  6.  $x = end((array_values($array)));                               ||           877 |           205 |           320 |           337 |           304 |         2.901 |     7.921.860 ||           948 |           300 |           336 |           308 |           309 |           509 |    29.696.951 ||           946 |           262 |           301 |           309 |           302 |           499 |    29.234.928 ||
||  7.  $x = $array[count($array)-1];                                   ||           123 |           300 |           137 |           139 |           143 |           140 |           144 ||           312 |           218 |            48 |            53 |            45 |            47 |            51 ||           296 |           217 |            46 |            44 |            53 |            53 |            55 ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||           494 |           593 |           418 |           435 |           399 |         3.873 |    12.199.450 ||           665 |           407 |           103 |           109 |           114 |           431 |    30.053.730 ||           647 |           445 |            91 |            95 |            96 |           419 |    30.718.586 ||
||  9.  $x = $array[] = array_pop($array);                              ||           186 |           178 |           175 |           188 |           180 |           181 |           186 ||            83 |            78 |            75 |            71 |            74 |            69 |            83 ||            71 |            64 |            70 |            64 |            68 |            69 |            81 ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           370 |           223 |            49 |            52 |            61 |            57 |            52 ||
 \=========================================================================================================================================================================================================================================================================================================================================================================================================================/ 

The above mentioned Fatal, Warning and Notice codes translate as:

F1 = Fatal error: Call to undefined function array_key_last() in Command line code on line 1
F2 = Fatal error: Uncaught Error: Call to undefined function array_key_last() in Command line code:1
W1 = Warning: array_slice() expects parameter 1 to be array, null given in Command line code on line 1
W2 = Warning: array_values() expects parameter 1 to be array, null given in Command line code on line 1
W3 = Warning: array_pop() expects parameter 1 to be array, null given in Command line code on line 1
W4 = Warning: end() expects parameter 1 to be array, null given in Command line code on line 1
W5 = Warning: reset() expects parameter 1 to be array, null given in Command line code on line 1
W6 = Warning: array_keys() expects parameter 1 to be array, null given in Command line code on line 1
W7 = Warning: count(): Parameter must be an array or an object that implements Countable in Command line code on line 1
W8 = Warning: array_key_last() expects parameter 1 to be array, null given in Command line code on line 1
N1 = Notice: Undefined offset: 0 in Command line code on line 1
N2 = Notice: Only variables should be passed by reference in Command line code on line 1
N3 = Notice: Undefined offset: -1 in Command line code on line 1
N4 = Notice: Undefined index:  in Command line code on line 1

Based on this output I draw the following conclusions:

newer versions of PHP perform better with the exception of these options that became significantly slower: option .6. $x = end((array_values($array))); option .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];

option .6. $x = end((array_values($array)));

option .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];

these options scale best for very large arrays: option .5. $x = end($array); reset($array); option .7. $x = $array[count($array)-1]; option .9. $x = $array[] = array_pop($array); option 10. $x = $array[array_key_last($array)]; (since PHP 7.3)

option .5. $x = end($array); reset($array);

option .7. $x = $array[count($array)-1];

option .9. $x = $array[] = array_pop($array);

option 10. $x = $array[array_key_last($array)]; (since PHP 7.3)

these options should only be used for auto-indexed arrays: option .7. $x = $array[count($array)-1]; (due to use of count) option .9. $x = $array[] = array_pop($array); (due to assigning value losing original key)

option .7. $x = $array[count($array)-1]; (due to use of count)

option .9. $x = $array[] = array_pop($array); (due to assigning value losing original key)

this option does not preserve the array's internal pointer option .5. $x = end($array); reset($array);

option .5. $x = end($array); reset($array);

this option is an attempt to modify option .5. to preserve the array's internal pointer (but sadly it does not scale well for very large arrays) option .6. $x = end((array_values($array)));

option .6. $x = end((array_values($array)));

the new array_key_last function seems to have none of the above mentioned limitations with the exception of still being an RC at the time of this writing (so use the RC or await it's release Dec 2018): option 10. $x = $array[array_key_last($array)]; (since PHP 7.3)

option 10. $x = $array[array_key_last($array)]; (since PHP 7.3)

A bit depending on whether using the array as stack or as queue you can make variations on option 9.


Very great answer, one comment though: for associative arrays option 9 cannot be used too, because we are assigning back to an auto-indexed key instead of the previous key name.
Nice summary! Please add my answer using the new PHP 7.3. function $array[array_key_last($array)]; to your benchmark. And please give me some notification when done. I'ld like to see the performance results in comparison.
@sz it was mainly produced with a lot of stubbornness and patience but the general selection and multi-line edit functions of Sublime text editor helped. regenerating it took almost a day, so if I need to do it again I will probably write something that converts the output of all 210 docker executions to a table automatically :-)
@quasimodos-clone I regenerated the whole table based on latest released PHP 5, 7 and your RC. I suppose we will want to generate it again coming December when it is actually released. Thanks for bringing this new function to everybody's attention.
Three years later, I changed the Accepted Answer to your's! AMAZING WORK!
r
rolacja

Short and sweet.

I came up with solution to remove error message and preserve one-liner form and efficient performance:

$lastEl = array_values(array_slice($array, -1))[0];

-- previous solution

$lastEl = array_pop((array_slice($array, -1)));

Note: The extra parentheses are needed to avoid a PHP Strict standards: Only variables should be passed by reference.


After exactly 5 years, 6 months and 2 days, you have submitted a more superior answer!! Thank you! and thank Stack Overflow!!
Greet answer, but adding the extra parentheses feels a little hackisch. Also phpStorm will mark this as an error. Extra info for adding extra parentheses (phpsadness.com/sad/51). To overcome the error, you could make this a '2-liner': $array = array_slice($array, -1); $lastEl = array_pop($array); Personally i think this is better (without the parser 'bug')
You can use dereferencing like this: array_slice($array, -1)[0]
You can't if you have strings as index in array
This answer still needs at least two checks to avoid PHP notices. 1. check if the array_size() > 1 2. Check if the array is actually an array. I still stick to the answer by @Iznogood as PHP's in-built end() function already does all the hard-work in a more efficient manner.
S
Stoutie

What's wrong with array_slice($array, -1)? (See Manual: http://us1.php.net/array_slice)

array_slice() returns an array. Probably not what you are looking for. You want the element.


Use array_slice($array, -1)[0] to get the element.
This is the answer. "end" Changing the internal pointer of the array? Asking for trouble, and very hard to read!
Love this approach, although as @Pang points out, it's not quite complete. reset(array_slice($array, -1)) is another approach (that won't cause an error if array_slice() returns anything "smaller" than a single-element array)
The best approach as you can directly modify the element: array_slice($array, -1)[0] = "";
W
Warbo

One way to avoid pass-by-reference errors (eg. "end(array_values($foo))") is to use call_user_func or call_user_func_array:

// PHP Fatal error: Only variables can be passed by reference
// No output (500 server error)
var_dump(end(array(1, 2, 3)));

// No errors, but modifies the array's internal pointer
// Outputs "int(3)"
var_dump(call_user_func('end', array(1, 2, 3)));

// PHP Strict standards:  Only variables should be passed by reference
// Outputs "int(3)"
var_dump(end(array_values(array(1, 2, 3))));

// No errors, doesn't change the array
// Outputs "int(3)"
var_dump(call_user_func('end', array_values(array(1, 2, 3))));

Great approach! (insert the standard 'This should be the accepted answer' here)
Or just add an extra paranthesis. Shorter and sweeter: end((array_values($yourArray)))
The extra parenthesis trick relies on a bug in PHP, and that approach no longer works in later versions of PHP (or at least, not in PHP 7).
And the call_user_func trick doesn't work in PHP 7 either. I think you're stuck with creating a temporary variable.
G
Gras Double

If you don't care about modifying the internal pointer (the following lines support both indexed and associative arrays):

// false if empty array
$last = end($array);

// null if empty array
$last = !empty($array) ? end($array) : null;

If you want an utility function that doesn't modify the internal pointer (because the array is passed by value to the function, so the function operates on a copy of it):

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    return end($array);
}


Though, PHP produces copies "on-the-fly", i.e. only when actually needed. As the end() function modifies the array, internally a copy of the whole array (minus one item) is generated.

Therefore, I would recommend the following alternative that is actually faster, as internally it doesn't copy the array, it just makes a slice:

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    foreach (array_slice($array, -1) as $value) {
        return $value;
    }
}

Additionally, the "foreach / return" is a tweak for efficiently getting the first (and here single) item.

Finally, the fastest alternative but for indexed arrays (and without gaps) only:

$last = !empty($array) ? $array[count($array)-1] : null;

For the record, here is another answer of mine, for the array's first element.


you provide 2 alternative implementations for an array_last function. For the first you state that the $array is copied and for the second that it is not copied. Where is the difference / why is it copied in the first implementation and not in the second?
@PaulvanLeeuwen I understood why you got confused. I tried to clarify the answer, is it better?
t
thrau

I need this quite often to deal with stacks, and i always find myself baffled that there's no native function that does it without manipulating the array or its internal pointer in some form.

So i usually carry around a util function that's also safe to use on associative arrays.

function array_last($array) {
    if (count($array) < 1)
        return null;

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}

Good news, they are making it a native function :-) You can keep an eye on it's release planning here: wiki.php.net/todo/php73 (expected Dec 13 2018 at the time of this writing).
T
TecBrat

untested: wouldn't this work?

<?php
$last_element=end(array_values($array));
?>

Since the array returned by array_values is fleeting, no-one cares if it's pointer is reset.

and if you need the key to go with it I guess you'd do:

<?php
$last_key=end(array_keys($array));
?>

Question: why untested? You just open a terminal and type: php -r '$array=[1,2,3];echo end(array_values($array))."\n";' BTW it throws a notice, so it's not the best way: Only variables should be passed by reference in Command line code on line 1
W
Westy92

To get the last element of an array, use:

$lastElement = array_slice($array, -1)[0];

Benchmark

I iterated 1,000 times, grabbing the last element of small and large arrays that contained 100 and 50,000 elements, respectively.

Method: $array[count($array)-1];
Small array (s): 0.000319957733154
Large array (s): 0.000526905059814
Note: Fastest!  count() must access an internal length property.
Note: This method only works if the array is naturally-keyed (0, 1, 2, ...).

Method: array_slice($array, -1)[0];
Small array (s): 0.00145292282104
Large array (s): 0.499367952347

Method: array_pop((array_slice($array, -1, 1)));
Small array (s): 0.00162816047668
Large array (s): 0.513121843338

Method: end($array);
Small array (s): 0.0028350353241
Large array (s): 4.81077480316
Note: Slowest...

I used PHP Version 5.5.32.


what about using $array[array_keys($array)[count(array_keys($array))-1] ]?
hmm..array_keys seems to scale pretty poorly.
It's actually crazy faster for the large array (0.0002) to pop the item and put it back on...$val=$ar[]=$array_pop($ar);
@Westy92 Your units seem wrong on the benchmark. The smallest number you give is 0.00031... microseconds which is about 0.3 nanoseconds. That would mean that your test took one clock tick to run if you have a newish computer. I'm guessing you either meant milliseconds or possibly even seconds.
The values are clearly several orders of magnitude wrong. Why the focus on performance anyway?
Q
Quasimodo's clone

As of PHP version 7.3 the functions array_key_first and array_key_last has been introduced.

Since arrays in PHP are not strict array types, i.e. fixed sized collections of fixed sized fields starting at index 0, but dynamically extended associative array, the handling of positions with unknown keys is hard and workarounds do not perform very well. In contrast real arrays would be internally addressed via pointer arithmethics very rapidly and the last index is already known at compile-time by declaration.

At least the problem with the first and last position is solved by builtin functions now since version 7.3. This even works without any warnings on array literals out of the box:

$first = array_key_first( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );
$last  = array_key_last ( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );

Obviously the last value is:

$array[array_key_last($array)];

Thanks for bringing this to everybody's attention. For those who are eager to use this: please not that this is a RC at the moment of this writing. It is scheduled for release Dec 2018.
This is great news. I've just posted a polyfill/shim in my answer below so people can start using this syntax right away.
A
Ajith

end() will provide the last element of an array

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
echo end($array); //output: c

$array1 = array('a', 'b', 'c', 'd');
echo end($array1); //output: d

This solution works, but it changes the array's internal pointer, I don't think it is the right way.
M
Mirko Pagliai

For me:

$last = $array[count($array) - 1];

With associatives:

$last =array_values($array)[count($array - 1)]

Please provide some context to your answer.
@Shawn Which context? Don't need context. Added code for associative arrays.
B
Bouke Versteegh

How about:

current(array_slice($array, -1))

works for associative arrays

works when $array == [] (returns false)

doesn't affect the original array


I like this, because you don't have to pass by reference. So it can be used for the oft-asked question "How do I get the last element of a delimited string?", by using current(array_slice(explode('|', 'a|b|c|d'), -1))
K
Koushik Das

How about this?

Eg-

$arr = [1,2,3];
$lastElem = count($arr) ? $arr[count($arr) - 1] : null;

You may have problems with it if you will have an empty array $arr
@VolodymyrI. thanks for pointing it out. I changed it.
V
Vihaan Verma
$lastValue = end(array_values($array))

No modification is made to $array pointers. This avoids the

reset($array)

which might not be desired in certain conditions.


P
Pang

One more possible solution...

$last_element = array_reverse( $array )[0];

Not working on associative arrays does not seem like enough reason to downvote to me. Quality-wise this answer is not worse then many other answers to this question. I do not understand why I see at least 2 downvotes at this time. (score of -2). Anyways, upvote for me, it is not that bad.
M
Mark Thomson

The top answers are great, but as mentioned by @paul-van-leeuwen and @quasimodos-clone, PHP 7.3 will introduce two new functions to solve this problem directly - array_key_first() and array_key_last().

You can start using this syntax today with the following polyfill (or shim) functions.

// Polyfill for array_key_last() available from PHP 7.3
if (!function_exists('array_key_last')) {
  function array_key_last($array) {
    return array_slice(array_keys($array),-1)[0];
  }
}

// Polyfill for array_key_first() available from PHP 7.3
if (!function_exists('array_key_first')) {
  function array_key_first($array) {
    return array_slice(array_keys($array),0)[0];
  }
}

// Usage examples:
$first_element_key   = array_key_first($array);
$first_element_value = $array[array_key_first($array)];

$last_element_key    = array_key_last($array);
$last_element_value  = $array[array_key_last($array)];

Caveat: This requires PHP 5.4 or greater.


D
Damiene

To do this and avoid the E_STRICT and not mess with the array's internal pointer you can use:

function lelement($array) {return end($array);}

$last_element = lelement($array);

lelement only works with a copy so it doesn't affect the array's pointer.


R
Rishabh

For getting the last value from Array :

array_slice($arr,-1,1) ;

For Removing last value form array :

array_slice($arr,0,count($arr)-1) ;

array_slice($arr,-1,1) will result in another array with length 1, not the last element
Let's take a example : $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Result: Array ( [0] => brown )
G
Giuseppe Gallo

Another solution:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
$lastItem = $array[(array_keys($array)[(count($array)-1)])];
echo $lastItem;

d
divaka

As of PHP 7.3, array_key_last is available

$lastEl = $myArray[array_key_last($myArray)];

A
Amzad Khan

You will get last element from an array easily by using below logic

$array = array('a', 'b', 'c', 'd');
echo ($array[count($array)-1]);

Not only last element but you can also get second last, third last and so on by using below logic.

for second last element you have to pass just number 2 in the above statement for example: echo ($array[count($array)-2]);


D
Daan

Simply: $last_element = end((array_values($array)))

Doesn't reset the array and doesn't gives STRICT warnings.

PS. Since the most voted answer still hasn't the double parenthesis, I submitted this answer.


A
Adelmar

I think this is a slight improvement on all the existing answers:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;

Performs better than end() or solutions using array_keys(), especially with large arrays

Won't modify the array's internal pointer

Won't try to access an undefined offset for empty arrays

Will work as expected for empty arrays, indexed arrays, mixed arrays, and associative arrays


Sadly it doesn't work with associative arrays, because the slice's single item may have a named key.
You're right, edited to add a fix (array_values on the single-element slice)
g
giovannipds

Nowadays, I'd prefer always having this helper, as suggested at an php.net/end answer.

<?php
function endc($array) {
    return end($array);
}

$items = array('one','two','three');
$lastItem = endc($items); // three
$current = current($items); // one
?>

This will always keeps the pointer as it is and we will never have to worry about parenthesis, strict standards or whatever.


Already mentioned above: stackoverflow.com/a/45333947/1255289
B
Brian Berneker

Use the end() function.

$array = [1,2,3,4,5];
$last = end($array); // 5

Just pay attention that this function moves your array's pointer to that position.
Also pay attention that this was posted as an answer 8 years previous. stackoverflow.com/a/3687368/1255289
l
lokender singh

Note: For (PHP 7 >= 7.3.0) we can use array_key_last — Gets the last key of an array

array_key_last ( array $array ) : mixed

Ref: http://php.net/manual/en/function.array-key-last.php


but I answered it earlier than others
C
Christos Lytras

Most solutions here are unreliable for unassociated arrays, because if we have an unassociated array with the last element being false, then end and current(array_slice($array, -1)) will also return false so we can't use false as an indicator of an empty unassociated array.

// end returns false form empty arrays
>>> $arr = []
>>> end($arr)
=> false

// last element is false, so end returns false,
// now we'll have a false possitive that the array is empty
>>> $arr = [1, 2, 3, false]
>>> end($arr)
=> false

>>> $arr = [1, 2, 3, false, 4]
>>> end($arr)
=> 4

Same goes for current(array_slice($arr, -1)):

// returns false form empty arrays
>>> $arr = []
>>> current(array_slice($arr, -1))
=> false

// returns false if last element is false
>>> $arr = [1, 2, 3, false]
>>> current(array_slice($arr, -1))
=> false

>>> $arr = [1, 2, 3, false, 4]
>>> current(array_slice($arr, -1))
=> 4

Best option is to use array_key_last which is available for PHP >= 7.3.0 or for older versions, we use count to get the last index (only for unassociated arrays):

// returns null for empty arrays
>>> $arr = []
>>> array_key_last($arr)
=> null

// returns last index of the array
>>> $arr = [1, 2, 3, false]
>>> array_key_last($arr)
=> 3

// returns last index of the array
>>> $arr = [1, 2, 3, false, 4]
>>> array_key_last($arr)
=> 4

For older versions, we can use count:

>>> $arr = []
>>> if (count($arr) > 0) $arr[count($arr) - 1]
// No excecution

>>> $arr = [1, 2, 3, false]
>>> if (count($arr) > 0) $arr[count($arr) - 1]
=> false

>>> $arr = [1, 2, 3, false, 4]
>>> if (count($arr) > 0) $arr[count($arr) - 1]
=> 4

That's all for unassociated arrays. If we are sure that we have associated arrays, then we can use end.


J
Jon Egerton

What if you want to get the last element of array inside of the loop of it's array?

The code below will result into an infinite loop:

foreach ($array as $item) {
 $last_element = end($array);
 reset($array);
 if ($last_element == $item) {
   // something useful here
 }
}

The solution is obviously simple for non associative arrays:

$last_element = $array[sizeof ($array) - 1];
foreach ($array as $key => $item) {
 if ($last_element == $item) {
   // something useful here
 }
}

I know about end() and reset() functions. My comment was related to loops like foreach or while where you cannot use these functions because reset function resets the inner pointer of an array which is used in the loop for iteration. Sorry for that, the question was more simple, I just wanted to give more advanced situation I came across in my project. Best regards.
This is wrong in many ways (arrays with duplicates, non-strict comparison...) and in any case not really related to the question.
use the end($array) function to get the last element, why you unnecessarily using loops?
@MahakChoudhary My comment is an addition to "how to get last element of array if you are doing some manipulations already inside a loop of this array. Using end() will reset the innver pointer and break iteration loop. Cheers!
H
Hussy Borad
$file_name_dm =  $_FILES["video"]["name"];    

                           $ext_thumb = extension($file_name_dm);

                            echo extension($file_name_dm); 
function extension($str){
    $str=implode("",explode("\\",$str));
    $str=explode(".",$str);
    $str=strtolower(end($str));
     return $str;
}