221

Let's imagine that we have two arrays:

$array_1 = array(
  '0' => 'zero',
  '1' => 'one',
  '2' => 'two',
  '3' => 'three',
);

$array_2 = array(
  'zero'  => '0',
  'one'   => '1',
  'two'   => '2',
  'three' => '3',
);

Now, I'd like to insert array('sample_key' => 'sample_value') after third element of each array. How can I do it?

DanMan
  • 11,323
  • 4
  • 40
  • 61
Kirzilla
  • 16,368
  • 26
  • 84
  • 129
  • Possible duplicate of [Insert new item in array on any position in PHP](https://stackoverflow.com/questions/3797239/insert-new-item-in-array-on-any-position-in-php) – Kashyap Kotak Jun 22 '18 at 15:07
  • Not a duplicate this quesiton is more focused on assoc arrays, @KashyapKotak – anthony_718 Nov 17 '21 at 18:48

25 Answers25

260

array_slice() can be used to extract parts of the array, and the union array operator (+) can recombine the parts.

$res = array_slice($array, 0, 3, true) +
    array("my_key" => "my_value") +
    array_slice($array, 3, count($array)-3, true);

This example:

$array = array(
  'zero'  => '0',
  'one'   => '1',
  'two'   => '2',
  'three' => '3',
);
$res = array_slice($array, 0, 3, true) +
    array("my_key" => "my_value") +
    array_slice($array, 3, count($array) - 1, true) ;
print_r($res);

gives:

Array
(
    [zero] => 0
    [one] => 1
    [two] => 2
    [my_key] => my_value
    [three] => 3
)
outis
  • 75,655
  • 22
  • 151
  • 221
Artefacto
  • 96,375
  • 17
  • 202
  • 225
  • This also a good point, but it should be placed into separated function. – Kirzilla Jul 28 '10 at 16:00
  • 10
    You should use array_splice() as M42 suggested. It solves the problem in just one line of code. – nickh Apr 16 '13 at 20:59
  • 35
    `+` shouldn't be used! Use `array_merge` instead! BEcause if the indices are integer (normal array, not hash), `+` will not work as expected!!! – Tomas May 13 '13 at 14:20
  • 5
    @Tomas Whether it works as expected or not depends on your expectations. `array_merge`'s behavior with respect to numeric keys is not appropriate for this question. – Artefacto May 19 '13 at 00:09
  • 16
    Instead of using `count($array)-3` you can simply specifcy null to the same effect. Also, using `array_merge` as TMS suggested won't require you to use a unique index. EXAMPLE: Add "new-value" to an existing array: `$b = array_merge( array_slice( $a, 0, 1, true ), array( 'new-value' ), array_slice( $a, 1, null, true ) );` – Radley Sustaire Jun 20 '14 at 18:34
  • For those implementing this, make sure to mind the stark difference between `array_slice()` and `array_splice()`. Accidentally typing the latter will result in `$array` being modified (it is passed by reference) and the results not being what was expected. – Bailey Parker Aug 12 '14 at 16:08
  • 2
    There seems to be some confusion about `+` vs. `array_merge`. If you want to insert things into a numeric array, you shouldn't use `+` because it probably won't match you expectations. But you shouldn't use `array_merge` either; for numeric arrays, this whole problem is solved with the [`array_splice`](http://php.net/array_splice) function. For associative or mixed arrays, you probably don't want numeric keys to be re-indexed so using `+` is entirely appropriate. – meustrus Jan 15 '15 at 18:36
  • This answer as a function (with null for array_slice length as suggested by @Bailey Parker): `function insertArrayAtPosition( $array, $insert, $position ) { return array_slice($array, 0, $position, TRUE) + $insert + array_slice($array, $position, NULL, TRUE); }` – fiskhandlarn Jun 29 '16 at 07:54
  • 1
    As others have said, you should use https://www.php.net/manual/en/function.array-splice.php for this instead. Please stop upvoting this answer. – btomw Jun 26 '20 at 17:22
  • This code work very well with `$array_2` which is associative array, `array_splice()` can't add array with custom key. – vee Jul 27 '21 at 06:25
126

For your first array, use array_splice():

$array_1 = array(
  '0' => 'zero',
  '1' => 'one',
  '2' => 'two',
  '3' => 'three',
);

array_splice($array_1, 3, 0, 'more');
print_r($array_1);

output:

Array(
    [0] => zero
    [1] => one
    [2] => two
    [3] => more
    [4] => three
)

for the second one there is no order so you just have to do :

$array_2['more'] = '2.5';
print_r($array_2);

And sort the keys by whatever you want.

Anwar
  • 4,162
  • 4
  • 41
  • 62
Toto
  • 89,455
  • 62
  • 89
  • 125
  • 39
    The second array does have an order... All arrays have, as they're also double linked lists. – Artefacto Jul 28 '10 at 16:06
  • @M42 When you go through a `foreach` loop, the array certainly DOES have an order. This may or may not be significant, depending on what your end goal is. (I came across this thread because in my case, the order IS significant). It's very frustrating that there's no such thing as `array_splice()` for associative arrays. – cartbeforehorse May 30 '12 at 16:37
  • 7
    -1, as mentioned "there is no order" is false. Also, array_splice destroys the key/value association in the first example (but maybe the OP intended that). – Brad Koch Dec 03 '12 at 23:58
  • 2
    @Artefacto "Arrays" in PHP are, in fact, _ordered hash tables_. PHP arrays act like arrays, but they are never really arrays; nor are they linked lists, or array lists. – Frederik Krautwald Aug 10 '14 at 11:31
  • 1
    5 hours later I finally read an answer I understand, thank you! One thing extra to note that if someone's pushing an associative array they can also specify "array" as the 4th argument in array_splice..like so: array_splice($array_1, 3, 0, ARRAY($array_name_to_insert)); – Robert Sinclair Aug 17 '16 at 05:03
  • 1
    @FrederikKrautwald Since PHP 7, that statement is not true. PHP 7 uses two arrays to implement its hash table + ordered list. Here's an article from one of the core PHP devs (Nikic): https://nikic.github.io/2014/12/22/PHPs-new-hashtable-implementation.html – CubicleSoft Oct 18 '19 at 11:43
24

code:

function insertValueAtPosition($arr, $insertedArray, $position) {
    $i = 0;
    $new_array=[];
    foreach ($arr as $key => $value) {
        if ($i == $position) {
            foreach ($insertedArray as $ikey => $ivalue) {
                $new_array[$ikey] = $ivalue;
            }
        }
        $new_array[$key] = $value;
        $i++;
    }
    return $new_array;
}

example:

$array        = ["A"=8, "K"=>3];
$insert_array = ["D"= 9];

insertValueAtPosition($array, $insert_array, $position=2);
// result ====> ["A"=>8,  "D"=>9,  "K"=>3];

May not really look perfect, but it works.

T.Todua
  • 53,146
  • 19
  • 236
  • 237
clausvdb
  • 636
  • 2
  • 6
  • 13
  • 13
    you're basically trying to do splicing, don't reinvent the wheel. – Paul Dragoonis Jul 28 '10 at 14:38
  • 11
    Nope, he is not reinventing the wheel. array_splice() do not allow to put key and value. Only value with specific position as key. – Kirzilla Jul 28 '10 at 14:44
  • 1
    yeah, but as remarked before, array_splice does not support associative arrays. I'd be more than happy to see a more elegant approach. – clausvdb Jul 28 '10 at 14:46
  • Your function is really good, but it doesn't work propertly with position bigger than array length ( try executing this array_insert($array_2, array("wow" => "wow"), 4) ). But it can be easily fixed. Your answer is great and you've answered my question! – Kirzilla Jul 28 '10 at 15:07
16

Here's a simple function that you could use. Just plug n play.

This is Insert By Index, Not By Value.

you can choose to pass the array, or use one that you already have declared.

Newer, shorter version:

   function insert($array, $index, $val)
   {
       $size = count($array); //because I am going to use this more than one time
       if (!is_int($index) || $index < 0 || $index > $size)
       {
           return -1;
       }
       else
       {
           $temp   = array_slice($array, 0, $index);
           $temp[] = $val;
           return array_merge($temp, array_slice($array, $index, $size));
       }
   }

Older, longer version:

  function insert($array, $index, $val) { //function decleration
    $temp = array(); // this temp array will hold the value 
    $size = count($array); //because I am going to use this more than one time
    // Validation -- validate if index value is proper (you can omit this part)       
        if (!is_int($index) || $index < 0 || $index > $size) {
            echo "Error: Wrong index at Insert. Index: " . $index . " Current Size: " . $size;
            echo "<br/>";
            return false;
        }    
    //here is the actual insertion code
    //slice part of the array from 0 to insertion index
    $temp = array_slice($array, 0, $index);//e.g index=5, then slice will result elements [0-4]
    //add the value at the end of the temp array// at the insertion index e.g 5
    array_push($temp, $val);
    //reconnect the remaining part of the array to the current temp
    $temp = array_merge($temp, array_slice($array, $index, $size)); 
    $array = $temp;//swap// no need for this if you pass the array cuz you can simply return $temp, but, if u r using a class array for example, this is useful. 
  
     return $array; // you can return $temp instead if you don't use class array
}

Usage example:

//1
$result = insert(array(1,2,3,4,5),0, 0);
echo "<pre>";
echo "<br/>";
print_r($result);
echo "</pre>";
//2
$result = insert(array(1,2,3,4,5),2, "a");
echo "<pre>";
print_r($result);
echo "</pre>";
//3
$result = insert(array(1,2,3,4,5) ,4, "b");
echo "<pre>";
print_r($result);
echo "</pre>";
//4
$result = insert(array(1,2,3,4,5),5, 6);
echo "<pre>";
echo "<br/>";
print_r($result);
echo "</pre>";

Expected result:

//1
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
)
//2
Array
(
    [0] => 1
    [1] => 2
    [2] => a
    [3] => 3
    [4] => 4
    [5] => 5
)
//3
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => b
    [5] => 5
)

//4
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
)
Pikamander2
  • 7,332
  • 3
  • 48
  • 69
Mohammed Joraid
  • 6,202
  • 2
  • 27
  • 38
12
$list = array(
'Tunisia' => 'Tunis',
'Germany' => 'Berlin',
'Italy' => 'Rom',
'Egypt' => 'Cairo'
);
$afterIndex = 2;
$newVal= array('Palestine' => 'Jerusalem');

$newList = array_merge(array_slice($list,0,$afterIndex+1), $newVal,array_slice($list,$afterIndex+1));
foued611
  • 359
  • 2
  • 7
  • Just a mention: instead of array_merge, one can also use + between arrays nowadays – roelleor Sep 11 '19 at 10:55
  • @roelleor But be careful: "If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended." - [array_merge](https://www.php.net/manual/en/function.array-merge.php) – long Mar 18 '20 at 15:11
  • Thanks! This is the only answer that worked for me considering associative arrays – Pablo S G Pacheco Nov 09 '20 at 19:31
6

This function supports:

  • both numeric and assoc keys
  • insert before or after the founded key
  • append to the end of array if key isn't founded

function insert_into_array( $array, $search_key, $insert_key, $insert_value, $insert_after_founded_key = true, $append_if_not_found = false ) {

        $new_array = array();

        foreach( $array as $key => $value ){

            // INSERT BEFORE THE CURRENT KEY? 
            // ONLY IF CURRENT KEY IS THE KEY WE ARE SEARCHING FOR, AND WE WANT TO INSERT BEFORE THAT FOUNDED KEY
            if( $key === $search_key && ! $insert_after_founded_key )
                $new_array[ $insert_key ] = $insert_value;

            // COPY THE CURRENT KEY/VALUE FROM OLD ARRAY TO A NEW ARRAY
            $new_array[ $key ] = $value;

            // INSERT AFTER THE CURRENT KEY? 
            // ONLY IF CURRENT KEY IS THE KEY WE ARE SEARCHING FOR, AND WE WANT TO INSERT AFTER THAT FOUNDED KEY
            if( $key === $search_key && $insert_after_founded_key )
                $new_array[ $insert_key ] = $insert_value;

        }

        // APPEND IF KEY ISNT FOUNDED
        if( $append_if_not_found && count( $array ) == count( $new_array ) )
            $new_array[ $insert_key ] = $insert_value;

        return $new_array;

    }

USAGE:

    $array1 = array(
        0 => 'zero',
        1 => 'one',
        2 => 'two',
        3 => 'three',
        4 => 'four'
    );

    $array2 = array(
        'zero'  => '# 0',
        'one'   => '# 1',
        'two'   => '# 2',
        'three' => '# 3',
        'four'  => '# 4'
    );

    $array3 = array(
        0 => 'zero',
        1 => 'one',
       64 => '64',
        3 => 'three',
        4 => 'four'
    );


    // INSERT AFTER WITH NUMERIC KEYS
    print_r( insert_into_array( $array1, 3, 'three+', 'three+ value') );

    // INSERT AFTER WITH ASSOC KEYS
    print_r( insert_into_array( $array2, 'three', 'three+', 'three+ value') );

    // INSERT BEFORE
    print_r( insert_into_array( $array3, 64, 'before-64', 'before-64 value', false) );

    // APPEND IF SEARCH KEY ISNT FOUNDED
    print_r( insert_into_array( $array3, 'undefined assoc key', 'new key', 'new value', true, true) );

RESULTS:

Array
(
    [0] => zero
    [1] => one
    [2] => two
    [3] => three
    [three+] => three+ value
    [4] => four
)
Array
(
    [zero] => # 0
    [one] => # 1
    [two] => # 2
    [three] => # 3
    [three+] => three+ value
    [four] => # 4
)
Array
(
    [0] => zero
    [1] => one
    [before-64] => before-64 value
    [64] => 64
    [3] => three
    [4] => four
)
Array
(
    [0] => zero
    [1] => one
    [64] => 64
    [3] => three
    [4] => four
    [new key] => new value
)
Dejan
  • 794
  • 9
  • 9
6

Simplest solution, if you want to insert (an element or array) after a certain key:

function array_splice_after_key($array, $key, $array_to_insert)
{
    $key_pos = array_search($key, array_keys($array));
    if($key_pos !== false){
        $key_pos++;
        $second_array = array_splice($array, $key_pos);
        $array = array_merge($array, $array_to_insert, $second_array);
    }
    return $array;
}

So, if you have:

$array = [
    'one' => 1,
    'three' => 3
];
$array_to_insert = ['two' => 2];

And execute:

$result_array = array_splice_after_key($array, 'one', $array_to_insert);

You'll have:

Array ( 
    ['one'] => 1 
    ['two'] => 2 
    ['three'] => 3 
)
Villapalos
  • 677
  • 9
  • 15
5

I recently wrote a function to do something similar to what it sounds like you're attempting, it's a similar approach to clasvdb's answer.

function magic_insert($index,$value,$input_array ) {
  if (isset($input_array[$index])) {
    $output_array = array($index=>$value);
    foreach($input_array as $k=>$v) {
      if ($k<$index) {
        $output_array[$k] = $v;
      } else {
        if (isset($output_array[$k]) ) {
          $output_array[$k+1] = $v;
        } else {
          $output_array[$k] = $v;
        }
      } 
    }

  } else {
    $output_array = $input_array;
    $output_array[$index] = $value;
  }
  ksort($output_array);
  return $output_array;
}

Basically it inserts at a specific point, but avoids overwriting by shifting all items down.

Peter O'Callaghan
  • 6,181
  • 3
  • 26
  • 27
5

Using array_splice instead of array_slice gives one less function call.

$toto =  array(
  'zero'  => '0',
  'one'   => '1',
  'two'   => '2',
  'three' => '3'
);
$ret = array_splice($toto, 3 );
$toto = $toto +  array("my_key" => "my_value") + $ret;
print_r($toto);
Florent
  • 436
  • 3
  • 8
4

Cleaner approach (based on fluidity of use and less code).

/**
 * Insert data at position given the target key.
 *
 * @param array $array
 * @param mixed $target_key
 * @param mixed $insert_key
 * @param mixed $insert_val
 * @param bool $insert_after
 * @param bool $append_on_fail
 * @param array $out
 * @return array
 */
function array_insert(
    array $array, 
    $target_key, 
    $insert_key, 
    $insert_val = null,
    $insert_after = true,
    $append_on_fail = false,
    $out = [])
{
    foreach ($array as $key => $value) {
        if ($insert_after) $out[$key] = $value;
        if ($key == $target_key) $out[$insert_key] = $insert_val;
        if (!$insert_after) $out[$key] = $value;
    }

    if (!isset($array[$target_key]) && $append_on_fail) {
        $out[$insert_key] = $insert_val;
    }

    return $out;
}

Usage:

$colors = [
    'blue' => 'Blue',
    'green' => 'Green',
    'orange' => 'Orange',
];

$colors = array_insert($colors, 'blue', 'pink', 'Pink');

die(var_dump($colors));
Luka
  • 603
  • 6
  • 12
4

This is an old question, but I posted a comment in 2014 and frequently come back to this. I thought I would leave a full answer. This isn't the shortest solution but it is quite easy to understand.

Insert a new value into an associative array, at a numbered position, preserving keys, and preserving order.

$columns = array(
    'id' => 'ID',
    'name' => 'Name',
    'email' => 'Email',
    'count' => 'Number of posts'
);

$columns = array_merge(
    array_slice( $columns, 0, 3, true ),     // The first 3 items from the old array
    array( 'subscribed' => 'Subscribed' ),   // New value to add after the 3rd item
    array_slice( $columns, 3, null, true )   // Other items after the 3rd
);

print_r( $columns );

/*
Array ( 
    [id] => ID 
    [name] => Name 
    [email] => Email 
    [subscribed] => Subscribed 
    [count] => Number of posts 
)
*/
Radley Sustaire
  • 3,382
  • 9
  • 37
  • 48
4

If you don't know that you want to insert it at position #3, but you know the key that you want to insert it after, I cooked up this little function after seeing this question.

/**
     * Inserts any number of scalars or arrays at the point
     * in the haystack immediately after the search key ($needle) was found,
     * or at the end if the needle is not found or not supplied.
     * Modifies $haystack in place.
     * @param array &$haystack the associative array to search. This will be modified by the function
     * @param string $needle the key to search for
     * @param mixed $stuff one or more arrays or scalars to be inserted into $haystack
     * @return int the index at which $needle was found
     */                         
    function array_insert_after(&$haystack, $needle = '', $stuff){
        if (! is_array($haystack) ) return $haystack;

        $new_array = array();
        for ($i = 2; $i < func_num_args(); ++$i){
            $arg = func_get_arg($i);
            if (is_array($arg)) $new_array = array_merge($new_array, $arg);
            else $new_array[] = $arg;
        }

        $i = 0;
        foreach($haystack as $key => $value){
            ++$i;
            if ($key == $needle) break;
        }

        $haystack = array_merge(array_slice($haystack, 0, $i, true), $new_array, array_slice($haystack, $i, null, true));

        return $i;
    }

Here's a codepad fiddle to see it in action: http://codepad.org/5WlKFKfz

Note: array_splice() would have been a lot more efficient than array_merge(array_slice()) but then the keys of your inserted arrays would have been lost. Sigh.

Tom Auger
  • 19,421
  • 22
  • 81
  • 104
2

I do that as


    $slightly_damaged = array_merge(
        array_slice($slightly_damaged, 0, 4, true) + ["4" => "0.0"], 
        array_slice($slightly_damaged, 4, count($slightly_damaged) - 4, true)
    );

2

This is another solution in PHP 7.1


     /**
     * @param array $input    Input array to add items to
     * @param array $items    Items to insert (as an array)
     * @param int   $position Position to inject items from (starts from 0)
     *
     * @return array
     */
    function arrayInject( array $input, array $items, int $position ): array 
    {
        if (0 >= $position) {
            return array_merge($items, $input);
        }
        if ($position >= count($input)) {
            return array_merge($input, $items);
        }

        return array_merge(
            array_slice($input, 0, $position, true),
            $items,
            array_slice($input, $position, null, true)
        );
    }

Oscar Gallardo
  • 2,240
  • 3
  • 27
  • 47
1

I just created an ArrayHelper class that would make this very easy for numeric indexes.

class ArrayHelper
{
    /*
        Inserts a value at the given position or throws an exception if
        the position is out of range.
        This function will push the current values up in index. ex. if 
        you insert at index 1 then the previous value at index 1 will 
        be pushed to index 2 and so on.
        $pos: The position where the inserted value should be placed. 
        Starts at 0.
    */
    public static function insertValueAtPos(array &$array, $pos, $value) {
        $maxIndex = count($array)-1;

        if ($pos === 0) {
            array_unshift($array, $value);
        } elseif (($pos > 0) && ($pos <= $maxIndex)) {
            $firstHalf = array_slice($array, 0, $pos);
            $secondHalf = array_slice($array, $pos);
            $array = array_merge($firstHalf, array($value), $secondHalf);
        } else {
            throw new IndexOutOfBoundsException();
        }

    }
}

Example:

$array = array('a', 'b', 'c', 'd', 'e');
$insertValue = 'insert';
\ArrayHelper::insertValueAtPos($array, 3, $insertValue);

Beginning $array:

Array ( 
    [0] => a 
    [1] => b 
    [2] => c 
    [3] => d 
    [4] => e 
)

Result:

Array ( 
    [0] => a 
    [1] => b 
    [2] => c 
    [3] => insert 
    [4] => d 
    [5] => e 
)
Rob Barber
  • 474
  • 3
  • 10
1

This is better method how insert item to array on some position.

function arrayInsert($array, $item, $position)
{
    $begin = array_slice($array, 0, $position);
    array_push($begin, $item);
    $end = array_slice($array, $position);
    $resultArray = array_merge($begin, $end);
    return $resultArray;
}
Lukáš Kříž
  • 630
  • 7
  • 5
1

I needed something that could do an insert before, replace, after the key; and add at the start or end of the array if target key is not found. Default is to insert after the key.

New Function

/**
 * Insert element into an array at a specific key.
 *
 * @param array $input_array
 *   The original array.
 * @param array $insert
 *   The element that is getting inserted; array(key => value).
 * @param string $target_key
 *   The key name.
 * @param int $location
 *   1 is after, 0 is replace, -1 is before.
 *
 * @return array
 *   The new array with the element merged in.
 */
function insert_into_array_at_key(array $input_array, array $insert, $target_key, $location = 1) {
  $output = array();
  $new_value = reset($insert);
  $new_key = key($insert);
  foreach ($input_array as $key => $value) {
    if ($key === $target_key) {
      // Insert before.
      if ($location == -1) {
        $output[$new_key] = $new_value;
        $output[$key] = $value;
      }
      // Replace.
      if ($location == 0) {
        $output[$new_key] = $new_value;
      }
      // After.
      if ($location == 1) {
        $output[$key] = $value;
        $output[$new_key] = $new_value;
      }
    }
    else {
      // Pick next key if there is an number collision.
      if (is_numeric($key)) {
        while (isset($output[$key])) {
          $key++;
        }
      }
      $output[$key] = $value;
    }
  }
  // Add to array if not found.
  if (!isset($output[$new_key])) {
    // Before everything.
    if ($location == -1) {
      $output = $insert + $output;
    }
    // After everything.
    if ($location == 1) {
      $output[$new_key] = $new_value;
    }

  }
  return $output;
}

Input code

$array_1 = array(
  '0' => 'zero',
  '1' => 'one',
  '2' => 'two',
  '3' => 'three',
);
$array_2 = array(
  'zero'  => '0',
  'one'   => '1',
  'two'   => '2',
  'three' => '3',
);

$array_1 = insert_into_array_at_key($array_1, array('sample_key' => 'sample_value'), 2, 1);
print_r($array_1);
$array_2 = insert_into_array_at_key($array_2, array('sample_key' => 'sample_value'), 'two', 1);
print_r($array_2);

Output

Array
(
    [0] => zero
    [1] => one
    [2] => two
    [sample_key] => sample_value
    [3] => three
)
Array
(
    [zero] => 0
    [one] => 1
    [two] => 2
    [sample_key] => sample_value
    [three] => 3
)
mikeytown2
  • 1,744
  • 24
  • 37
1

Very simple 2 string answer to your question:

$array_1 = array(
  '0' => 'zero',
  '1' => 'one',
  '2' => 'two',
  '3' => 'three',
);

At first you insert anything to your third element with array_splice and then assign a value to this element:

array_splice($array_1, 3, 0 , true);
$array_1[3] = array('sample_key' => 'sample_value');
0

Not as concrete as the answer of Artefacto, but based in his suggestion of using array_slice(), I wrote the next function:

function arrayInsert($target, $byKey, $byOffset, $valuesToInsert, $afterKey) {
    if (isset($byKey)) {
        if (is_numeric($byKey)) $byKey = (int)floor($byKey);
        $offset = 0;

        foreach ($target as $key => $value) {
            if ($key === $byKey) break;
            $offset++;
        }

        if ($afterKey) $offset++;
    } else {
        $offset = $byOffset;
    }

    $targetLength = count($target);
    $targetA = array_slice($target, 0, $offset, true);
    $targetB = array_slice($target, $offset, $targetLength, true);
    return array_merge($targetA, $valuesToInsert, $targetB);
}

Features:

  • Inserting one or múltiple values
  • Inserting key value pair(s)
  • Inserting before/after the key, or by offset

Usage examples:

$target = [
    'banana' => 12,
    'potatoe' => 6,
    'watermelon' => 8,
    'apple' => 7,
    2 => 21,
    'pear' => 6
];

// Values must be nested in an array
$insertValues = [
    'orange' => 0,
    'lemon' => 3,
    3
];

// By key
// Third parameter is not applicable
//     Insert after 2 (before 'pear')
var_dump(arrayInsert($target, 2, null, $valuesToInsert, true));
//     Insert before 'watermelon'
var_dump(arrayInsert($target, 'watermelon', null, $valuesToInsert, false)); 

// By offset
// Second and last parameter are not applicable
//     Insert in position 2 (zero based i.e. before 'watermelon')
var_dump(arrayInsert($target, null, 2, $valuesToInsert, null)); 
mikl
  • 1,067
  • 1
  • 20
  • 34
0

In case you are just looking to insert an item into an array at a certain position (based on @clausvdb answer):

function array_insert($arr, $insert, $position) {
    $i = 0;
    $ret = array();
    foreach ($arr as $key => $value) {
            if ($i == $position) {
                $ret[] = $insert;
            }
            $ret[] = $value;
            $i++;
    }
    return $ret;
}
0

Here is my version:

/**
 * 
 * Insert an element after an index in an array
 * @param array $array  
 * @param string|int $key 
 * @param mixed $value
 * @param string|int $offset
 * @return mixed
 */
function array_splice_associative($array, $key, $value, $offset) {
    if (!is_array($array)) {
        return $array;
    }
    if (array_key_exists($key, $array)) {
        unset($array[$key]);
    }
    $return = array();
    $inserted = false;
    foreach ($array as $k => $v) {
        $return[$k] = $v;
        if ($k == $offset && !$inserted) {
            $return[$key] = $value;
            $inserted = true;
        }
    }
    if (!$inserted) {
        $return[$key] = $value;
    }


    return $return;
}
beta-developper
  • 1,689
  • 1
  • 13
  • 24
0

try this one ===

$key_pos=0;
$a1=array("a"=>"red", "b"=>"green", "c"=>"blue", "d"=>"yellow");
$arrkey=array_keys($a1);
array_walk($arrkey,function($val,$key) use(&$key_pos) {
  if($val=='b')
    {
        $key_pos=$key;
    }
  });
$a2=array("e"=>"purple");
$newArray = array_slice($a1, 0, $key_pos, true) + $a2 +
        array_slice($a1, $key_pos, NULL, true);
print_r($newArray);

Output

Array (
      [a] => red
      [e] => purple
      [b] => green
      [c] => blue
      [d] => yellow )
0

This can be done by array.splice(). Please note array_splice or array_merge doesn't preserve keys for associative arrays. So array_slice is used and '+' operator is used for concatenating the two arrays.

More details here



$array_1 = array(
    '0' => 'zero',
    '1' => 'one',
    '2' => 'two',
    '3' => 'three',
  );
  
  $array_2 = array(
    'zero'  => '0',
    'one'   => '1',
    'two'   => '2',
    'three' => '3',
  );
  $index = 2;
  $finalArray = array_slice($array_1, 0, $index, true) +
                $array2  +
                array_slice($array_2, $index, NULL, true);
print_r($finalArray);
/*
Array
(
    [0] => zero
    [1] => one
    [10] => grapes
    [z] => mangoes
    [two] => 2
    [three] => 3
)
*/




mk23
  • 1,257
  • 1
  • 12
  • 25
0

I've created a function (PHP 8.1), which allows you to insert items to associative or numeric arrays:

function insertItemsToPosition(array $array, string|int $insertAfterPosition, array $itemsToAdd): array
    {
        $insertAfterIndex = array_search($insertAfterPosition, array_keys($array), true);
        if ($insertAfterIndex === false) {
            throw new \UnexpectedValueException(sprintf('You try to insert items to an array after the key "%s", but this key is not existing in given array. Available keys are: %s', $insertAfterPosition, implode(', ', array_keys($array))));
        }

        $itemsBefore = array_slice($array, 0, $insertAfterIndex + 1);
        $itemsAfter = array_slice($array, $insertAfterIndex + 1);

        return $itemsBefore + $itemsToAdd + $itemsAfter;
    }
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
Armin
  • 15,582
  • 10
  • 47
  • 64
-2

You can insert elements during a foreach loop, since this loop works on a copy of the original array, but you have to keep track of the number of inserted lines (I call this "bloat" in this code):

$bloat=0;
foreach ($Lines as $n=>$Line)
    {
    if (MustInsertLineHere($Line))
        {
        array_splice($Lines,$n+$bloat,0,"string to insert");
        ++$bloat;
        }
    }

Obviously, you can generalize this "bloat" idea to handle arbitrary insertions and deletions during the foreach loop.

David Spector
  • 1,520
  • 15
  • 21