How can I add an element to the beginning of array without changing array key values in PHP?
-
How would that work? What if you've got an item with the key `0`? – Dominic Rodger Sep 07 '10 at 09:11
-
3Can you give an example with an array of what input and output you need – sushil bharwani Sep 07 '10 at 09:11
9 Answers
To keep numerical keys from being reindexed, you could simply add the arrays together.
Instead of:
array_unshift($arr1, $arr2)
try:
$arr1 = $arr2 + $arr1;

- 801
- 1
- 6
- 2
-
2I've always steered away from adding arrays this way, favoring `array_merge` instead, but now I have a legitimate reason to use it. Thanks! – Benjam Nov 12 '13 at 17:49
If you use self-assigned (e.g. literal) keys, array_unshift() will do it.
If you use auto-generated (numeric) keys, how should that work? Use '-1' as the new first key?
EDIT:
Thank you to JasonS for pointing out an error in this answer.
ANY numeric key will be re-indexed by array_unshift()
, no matter if it was auto-generated or self-assigned - if it's numeric, it'll get scrambled. See the link to the documentation above for details.

- 16,418
- 9
- 48
- 68
-
no because if the indexes represent ids in a table, there will never be a zero index so this works fine for these situations – Claire Jan 15 '14 at 17:02
-
@Nicola I'm sorry - I don't understand what you're trying to tell me. – Martin Hennings Jan 15 '14 at 18:37
-
I was meaning that if you return rows from a database and the keys of the array are the row ids, then an array will never have a 0 key. Therefore, in this instance, a situation would not arise where the index would be -1. – Claire Jan 16 '14 at 10:27
-
Any numerically indexed array will have the keys re-indexed to start counting from zero, as explained in the array_unshift() docs you linked to. Your example has numeric keys and so will be re-indexed if using array_unshift() – Jason S Mar 19 '15 at 05:52
-
I tried to edit your answer, using your original example, but it was rejected (by others). Presumably they didn't take notice that I was using your original example. So I'm posting it as an (abbreviated), comment. To take three items from an integer indexed array `$a`, and move them to the front of the array (your original example), you could do this. `$a = array_slice($a, -3, null, true) + $a;` – Jason S Mar 21 '15 at 20:52
-
Since my last comment I've added the edits I made to your answer as my own answer, since that is what the reviewers suggested I do. Still, I thought the spirit of SO is to edit and improve answers rather than add multiple redundant ones. So please excuse me. – Jason S Mar 21 '15 at 21:18
Use array_unshift()
. (As mentioned, it will keep your string keys intact, but not numeric keys).

- 11,042
- 3
- 36
- 41
-
1"All numerical array keys will be modified to start counting from zero while literal keys won't be touched." (http://www.php.net/array-unshift) – Dominic Rodger Sep 07 '10 at 09:12
try this:
function array_insert(&$array, $insert, $position = -1) {
$position = ($position == -1) ? (count($array)) : $position ;
if($position != (count($array))) {
$ta = $array;
for($i = $position; $i < (count($array)); $i++) {
if(!isset($array[$i])) {
die(print_r($array, 1)."\r\nInvalid array: All keys must be numerical and in sequence.");
}
$tmp[$i+1] = $array[$i];
unset($ta[$i]);
}
$ta[$position] = $insert;
$array = $ta + $tmp;
//print_r($array);
} else {
$array[$position] = $insert;
}
//ksort($array);
return true;
}

- 1,402
- 2
- 16
- 32
Adding my own (redundant) answer, because I tried to edit Martin's answer, using his original example, but it was rejected by others (not Martin). Maybe they didn't review the history of his answer, as I'm using his original example array and problem. Here is my rejected edit.
Kevin Wentworth's answer is correct. Expanding on that answer using the original example from Martin's answer, if you have an array
$a = [1 => a, 2 => b, 5 => e, 6 => f, 8 => h, 9 => i];
and you want to take the last three items and prepend them to this same array, then you could do the following.
$a = array_slice($a, -3, null, true) + $a;
The resulting array is
array (6 => 'f', 8 => 'h', 9 => 'i', 1 => 'a', 2 => 'b', 5 => 'e',)
Notes
The true
argument to array_slice
preserves numeric keys (no such parameter exists for array_unshift
).
Although array_slice
doesn't remove anything from the original array, because of the behaviour of the +
operator on arrays, the last three items are cancelled out.
From the docs for the + array operator
The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored.
Just a quick note for if you wish to use this in a loop...
As stated here: http://jp2.php.net/manual/en/function.array-unshift.php
array_unshift() prepends passed elements to the front of the array. Note that the list of elements is prepended as a whole, so that the prepended elements stay in the same order. All numerical array keys will be modified to start counting from zero while literal keys won't be touched.
TO give you an idea of how slow this is, we wrote some benchmark code (based on http://pastebin.com/Jad5TjsQ), and here is how it looks
mt@wizcorp-dev2:~/dev/test$ for d in arrayFillBrackets.php arrayFillPush.php arrayFillUnshift.php arrayFillPushReverse.php ; do cat $d; php $d; done
<?php
require "benchmark.php";
function ArrayFillBrackets()
{
$result = array();
for($i = 0; $i < 10000; $i++) $result[] = $i;
return $result;
}
$result = array();
$result[10]['ArrayFillBrackets'] = Benchmark('ArrayFillBrackets', null, 10);
!!! Benchmarking function ArrayFillBrackets for 10 iteration (args:null)...
===================
Results:
===================
time total: 0.02686286
time min: 0.00198293
time max: 0.0058589
time avg: 0.002686286
memory total: 0
memory min: 0
memory max: 0
memory avg: 0
<?php
require "benchmark.php";
function ArrayFillPush()
{
$result = array();
for($i = 0; $i < 10000; $i++) array_push($result, $i);
return $result;
}
$result = array();
$result[10]['ArrayFillPush'] = Benchmark('ArrayFillPush', null, 10);
!!! Benchmarking function ArrayFillPush for 10 iteration (args:null)...
===================
Results:
===================
time total: 0.03958679
time min: 0.003757
time max: 0.00485086
time avg: 0.003958679
memory total: 0
memory min: 0
memory max: 0
memory avg: 0
<?php
require "benchmark.php";
function ArrayFillUnshift()
{
$result = array();
for($i = 0; $i < 10000; $i++) array_unshift($result, $i);
return $result;
}
$result = array();
$result[1]['ArrayFillUnshift'] = Benchmark('ArrayFillUnshift', null, 1);
!!! Benchmarking function ArrayFillUnshift for 1 iteration (args:null)...
===================
Results:
===================
time total: 3.62487912
time min: 3.62487912
time max: 3.62487912
time avg: 3.62487912
memory total: 0
memory min: 0
memory max: 0
memory avg: 0
<?php
require "benchmark.php";
function ArrayFillPushReverse()
{
$result = array();
for($i = 0; $i < 10000; $i++) array_push($result, $i);
return array_reverse($result);
}
$result = array();
$result[10]['ArrayFillPushReverse'] = Benchmark('ArrayFillPushReverse', null, 10);
!!! Benchmarking function ArrayFillPushReverse for 10 iteration (args:null)...
===================
Results:
===================
time total: 0.05071593
time min: 0.00475311
time max: 0.00560999
time avg: 0.005071593
memory total: 108
memory min: 0
memory max: 24
memory avg: 10.8
mt@wizcorp-dev2:~/dev/test$
Please note that all tests are 10 * 10,000, except the array_unshift that runs 1 * 10,000 (was quite tired of waiting)... So again, don't use array_shift in iteration, as reversing the array only once costs almost nothing instead.

- 1,244
- 1
- 12
- 19
Well, if you are doing what I am doing and creating a select form using results from the DB with indexes being the ids from the DB table, but want to add say "Any..." to the array with an index of 0, simply create the array variable with that item first, then populate the remaining values from the database. No need to unshift or order things after the database call.