• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • array_replace()

    (PHP 5 >= 5.3.0, PHP 7)

    使用传递的数组替换第一个数组的元素

    说明

    array_replace(array $array1[,array $...]): array

    array_replace()函数使用后面数组元素相同 key 的值替换$array1数组的值。如果一个键存在于第一个数组同时也存在于第二个数组,它的值将被第二个数组中的值替换。如果一个键存在于第二个数组,但是不存在于第一个数组,则会在第一个数组中创建这个元素。如果一个键仅存在于第一个数组,它将保持不变。如果传递了多个替换数组,它们将被按顺序依次处理,后面的数组将覆盖之前的值。

    array_replace()是非递归的:它将第一个数组的值进行替换而不管第二个数组中是什么类型。

    参数

    $array1

    替换该数组的值。

    包含要提取元素的数组。后面的数组里的值会覆盖前面的值。

    返回值

    返回一个数组。如果发生错误,将返回NULL

    范例

    Example #1array_replace()范例

    <?php
    $base = array("orange", "banana", "apple", "raspberry");
    $replacements = array(0 => "pineapple", 4 => "cherry");
    $replacements2 = array(0 => "grape");
    $basket = array_replace($base, $replacements, $replacements2);
    print_r($basket);
    ?>
    

    以上例程会输出:

    Array
    (
        [0] => grape
        [1] => banana
        [2] => apple
        [3] => raspberry
        [4] => cherry
    )
    

    参见

    <?php
    // we wanted the output of only selected array_keys from a big array from a csv-table
    // with different order of keys, with optional suppressing of empty or unused values
    $values = array
    (
      'Article'=>'24497',
      'Type'=>'LED',
      'Socket'=>'E27',
      'Dimmable'=>'',
      'Wattage'=>'10W'
    );
    $keys = array_fill_keys(array('Article','Wattage','Dimmable','Type','Foobar'), ''); // wanted array with empty value
    $allkeys = array_replace($keys, array_intersect_key($values, $keys));  // replace only the wanted keys
    $notempty = array_filter($allkeys, 'strlen'); // strlen used as the callback-function with 0==false
    print '<pre>';
    print_r($allkeys);
    print_r($notempty);
    /*
    Array
    (
      [Article] => 24497
      [Wattage] => 10W
      [Dimmable] => 
      [Type] => LED
      [Foobar] => 
    )
    Array
    (
      [Article] => 24497
      [Wattage] => 10W
      [Type] => LED
    )
    */
    ?>
    
    If the arrays are associative (that is, their keys are strings), then I believe this function is identical to (the older) array_merge.
    Simple function to replace array keys. Note you have to manually select wether existing keys will be overrided.
     
    /**
     * @param array $array
     * @param array $replacements
     * @param boolean $override
     * @return array
     */
    function array_replace_keys(array $array, array $replacements, $override = false) {
      foreach ($replacements as $old => $new) {
        if(is_int($new) || is_string($new)){
          if(array_key_exists($old, $array)){
            if(array_key_exists($new, $array) && $override === false){
              continue;
            }
            $array[$new] = $array[$old];
            unset($array[$old]);
          }
        }
      }
      return $array;
    }
    In some cases you might have a structured array from the database and one
    of its nodes goes like this;
    <?php
    # a random node structure
    $arr  = array( 
      'name' => 'some name', 
      'key2' => 'value2', 
      'title' => 'some title', 
      'key4' => 4, 
      'json' => '[1,0,1,1,0]'
    );
    # capture these keys values into given order
    $keys  = array( 'name', 'json', 'title' );
    ?>
    Now consider that you want to capture $arr values from $keys.
    Assuming that you have a limitation to display the content into given keys
    order, i.e. use it with a vsprintf, you could use the following
    <?php
    # string to transform
    $string = "<p>name: %s, json: %s, title: %s</p>";
    # flip keys once, we will use this twice
    $keys  = array_flip( $keys );
    # get values from $arr
    $test  = array_intersect_key( $arr, $keys );
    # still not good enough
    echo vsprintf( $string, $test );
    // output --> name: some name, json: some title, title: [1,0,1,1,0]
    # usage of array_replace to get exact order and save the day
    $test  = array_replace( $keys, $test );
    # exact output
    echo vsprintf( $string, $test );
    // output --> name: some name, json: [1,0,1,1,0], title: some title
    ?>
    I hope that this will save someone's time.
    You can also use:
    <?php 
    $myarray = [
    "Orange",
    "572" => "Banana",
    "omg" => "Chili",
    "nevermind" => "mango"
    ];
    $myarray[0] = "NO-Orange"; 
    $myarray["572"] = "BANANAPHONE!!!";
    $myarray["omg"] = "NO-Chili";
    print_r($myarray);
    ?>
    RESULT:
    Array
    (
      [0] => NO-Orange
      [572] => BANANAPHONE!!!
      [omg] => NO-Chili
      [nevermind] => mango
    )
    with regards
    I would like to add to my previous note about my polecat_array_replace function that if you want to add a single dimensional array to a multi, all you must do is pass the matching internal array key from the multi as the initial argument as such:
    $array1 = array( "berries" => array( "strawberry" => array( "color" => "red", "food" => "desserts"), "dewberry" = array( "color" => "dark violet", "food" => "pies"), );
    $array2 = array( "food" => "wine");
    $array1["berries"]["dewberry"] = polecat_array_replace($array1["berries"]["dewberry"], $array2);
     
    This is will replace the value for "food" for "dewberry" with "wine".
    The function will also do the reverse and add a multi to a single dimensional array or even a 2 tier array to a 5 tier as long as the heirarchy tree is identical.
    I hope this helps atleast one person for all that I've gained from this site.
    To get exactly same result like in PHP 5.3, the foreach loop in your code should look like:
    <?php
    ...
    $count = func_num_args();
    for ($i = 1; $i < $count; $i++) {
      ...
    }
    ...
    ?>
    Check on this code:
    <?php
    $base = array('id' => NULL, 'login' => NULL, 'credit' => NULL);
    $arr1 = array('id' => 2, 'login' => NULL, 'credit' => 5);
    $arr2 = array('id' => NULL, 'login' => 'john.doe', 'credit' => 100);
    $result = array_replace($base, $arr1, $arr2);
    /*
    correct output:
    array(3) {
      "id" => NULL
      "login" => string(8) "john.doe"
      "credit" => int(100)
    }
    your output:
    array(3) {
      "id" => int(2)
      "login" => NULL
      "credit" => int(5)
    }
    */
    ?>
    Function array_replace "replaces elements from passed arrays into the first array" -- this means replace from top-right to first, then from top-right - 1 to first, etc, etc...
    Here is a simple array_replace_keys function:
    /**
       * This function replaces the keys of an associate array by those supplied in the keys array
       *
       * @param $array target associative array in which the keys are intended to be replaced
       * @param $keys associate array where search key => replace by key, for replacing respective keys
       * @return array with replaced keys
       */
      private function array_replace_keys($array, $keys)
      {
        foreach ($keys as $search => $replace) {
          if ( isset($array[$search])) {
            $array[$replace] = $array[$search];
            unset($array[$search]);
          }
        }
        return $array;
      }
    // Test Drive
    print_r(array_replace_keys(['one'=>'apple', 'two'=>'orange'], ['one'=>'ett', 'two'=>'tvo']);
    // Output
    array(
    'ett'=>'apple',
    'tvo'=>'orange'
    )
    The documentation is wrongly phrased: "array_replace() replaces the values of array1" No replacing is done. A new array is created which looks like the one that would have resulted from the described replacement. 
    If you want to augment the set of indices in an array, use 
        array_to_be_modified += array_with_indices_to_add;
    Instead of calling this function, it's often faster and simpler to do this instead:
    <?php
    $array_replaced = $array2 + $array1;
    ?>
    If you need references to stay intact:
    <?php
    $array2 += $array1;
    ?>
    
    I got hit with a noob mistake. :)
    When the function was called more than once, it threw a function redeclare error of course. The enviroment I was coding in never called it more than once but I caught it in testing and here is the fully working revision. A simple logical step was all that was needed.
    With PHP 5.3 still unstable for Debian Lenny at this time and not knowing if array_replace would work with multi-dimensional arrays, I wrote my own. Since this site has helped me so much, I felt the need to return the favor. :) 
    <?php
        // Polecat's Multi-dimensional array_replace function
        // Will take all data in second array and apply to first array leaving any non-corresponding values untouched and intact 
        function polecat_array_replace( array &$array1, array &$array2 ) {
          // This sub function is the iterator that will loop back on itself ad infinitum till it runs out of array dimensions
          if(!function_exists('tier_parse')){
            function tier_parse(array &$t_array1, array&$t_array2) {
              foreach ($t_array2 as $k2 => $v2) {
                if (is_array($t_array2[$k2])) {
                  tier_parse($t_array1[$k2], $t_array2[$k2]);
                } else {
                  $t_array1[$k2] = $t_array2[$k2];
                }
              }
              return $t_array1;
            }
          }
          
          foreach ($array2 as $key => $val) {
            if (is_array($array2[$key])) {
              tier_parse($array1[$key], $array2[$key]);
            } else {
              $array1[$key] = $array2[$key];
            }
          }
          return $array1;
        }
    ?>
    [I would also like to note] that if you want to add a single dimensional array to a multi, all you must do is pass the matching internal array key from the multi as the initial argument as such:
    <?php
    $array1 = array( "berries" => array( "strawberry" => array( "color" => "red", "food" => "desserts"), "dewberry" = array( "color" => "dark violet", "food" => "pies"), );
    $array2 = array( "food" => "wine");
    $array1["berries"]["dewberry"] = polecat_array_replace($array1["berries"]["dewberry"], $array2);
    ?>
    This is will replace the value for "food" for "dewberry" with "wine".
    The function will also do the reverse and add a multi to a single dimensional array or even a 2 tier array to a 5 tier as long as the heirarchy tree is identical.
    I hope this helps atleast one person for all that I've gained from this site.
    if(!function_exists('array_replace'))
    {
     function array_replace()
     {
      $args = func_get_args();
      $num_args = func_num_args();
      $res = array();
      for($i=0; $i<$num_args; $i++)
      {
       if(is_array($args[$i]))
       {
        foreach($args[$i] as $key => $val)
        {
         $res[$key] = $val;
        }
       }
       else
       {
        trigger_error(__FUNCTION__ .'(): Argument #'.($i+1).' is not an array', E_USER_WARNING);
        return NULL;
       }
      }
      return $res;
     }
    }
    a little enhancement to dyer85 at gmail dot com's function below: 
    <?php
    if (!function_exists('array_replace'))
    {
     function array_replace( array &$array, array &$array1, $filterEmpty=false )
     {
      $args = func_get_args();
      $count = func_num_args() 1;
      for ($i = 0; $i < $count; ++$i) {
       if (is_array($args[$i])) {
        foreach ($args[$i] as $key => $val) {
          if ($filterEmpty && empty($val)) continue;
          $array[$key] = $val;
        }
       }
       else {
        trigger_error(
         __FUNCTION__ . '(): Argument #' . ($i+1) . ' is not an array',
         E_USER_WARNING
        );
        return NULL;
       }
      }
      return $array;
     }
    } 
    ?>
    this will allow you to "tetris-like" merge arrays:
    <?php
    $a= array(
      0 => "foo",
      1 => "",
      2 => "baz"
    );
    $b= array(
      0 => "",
      1 => "bar",
      2 => ""
    );
    print_r(array_replace($a,$b, true));
    ?>
    results in: 
    Array
    (
      [0] => foo
      [1] => bar
      [2] => baz
    )
    If you work on some realy old server below PHP5 you can use array_merge like "necessary evil" to replace values in array:
    Here is example how you can use this:
    <?php
    if(function_exists("array_replace") && version_compare(phpversion(), '5.3.0', '>='))
        $data = array_replace($array1, $array2); // (PHP 5 >= 5.3.0)
      else
        $data = array_merge($array1, $array2); // (PHP 5 < 5.3.0)
    var_dump($data);
    ?>
    This can also help someplugin developers to cover some old PHP versions.