讲师中心 微信公众号
AI工具推荐 视频效率加速

PHP数组合并怎么操作_PHP数组合并函数与使用技巧

轻芳同学_7768

轻芳同学_7768

发布时间:2025-10-12 16:21:01

|

340人浏览过

|

来源于php中文网

原创

PHP数组合并需根据键类型和冲突处理选择+运算符、array_merge或array_merge_recursive:+保留左侧数组值,array_merge右侧覆盖并重索引数值键,array_merge_recursive递归合并或生成新数组,适用于不同场景。

php数组合并怎么操作_php数组合并函数与使用技巧

PHP数组合并,这事儿看着简单,但里面门道不少,尤其是在处理键名冲突的时候,一不小心就可能踩坑。核心操作主要通过+运算符、array_merge()函数和array_merge_recursive()函数来实现,每种方式都有其特定的行为和适用场景,理解它们之间的差异是关键。

解决方案

在PHP中,合并数组有几种主要的方法,每种方法在处理键名冲突和数值键时都有不同的表现。

  1. 使用 + 运算符(数组联合) 这是最直观的合并方式之一,但它的行为可能和一些人的直觉相反。当使用+运算符合并两个数组时,如果两个数组有相同的字符串键,那么第一个数组的值会被保留,第二个数组中相同键的值会被忽略。对于数值键,第二个数组的元素会直接附加到第一个数组的后面,不会重新索引,也不会覆盖。

    <?php
    $array1 = ['a' => 1, 'b' => 2, 0 => 'foo'];
    $array2 = ['a' => 3, 'c' => 4, 0 => 'bar', 1 => 'baz'];
    
    $mergedArray = $array1 + $array2;
    print_r($mergedArray);
    /*
    输出:
    Array
    (
        [a] => 1    // 'a' 键保留了 $array1 的值
        [b] => 2
        [0] => foo  // 0 键保留了 $array1 的值
        [c] => 4
        [1] => baz  // 1 键是 $array2 新增的
    )
    */
    
    $array3 = [10, 20];
    $array4 = [30, 40];
    $mergedNumeric = $array3 + $array4;
    print_r($mergedNumeric);
    /*
    输出:
    Array
    (
        [0] => 10
        [1] => 20
        [2] => 30 // 键名不冲突,直接追加
        [3] => 40
    )
    */
    ?>

    这个方法特别适合你希望“补充”一个数组,而不是“覆盖”它的情况。

  2. 使用 array_merge() 函数array_merge() 是最常用的数组合并函数,它的行为相对更符合一般预期。它将一个或多个数组合并到一起。

    立即学习“PHP免费学习笔记(深入)”;

    • 字符串键: 如果有相同的字符串键,后面数组的值会覆盖前面数组的值。
    • 数值键: 数值键的元素会被追加到结果数组的后面,并且会被重新索引(从0开始)。
    <?php
    $array1 = ['a' => 1, 'b' => 2, 0 => 'foo'];
    $array2 = ['a' => 3, 'c' => 4, 0 => 'bar', 1 => 'baz'];
    
    $mergedArray = array_merge($array1, $array2);
    print_r($mergedArray);
    /*
    输出:
    Array
    (
        [a] => 3    // 'a' 键被 $array2 覆盖
        [b] => 2
        [0] => foo  // 数值键被重新索引
        [1] => bar
        [2] => baz
        [c] => 4
    )
    */
    
    $array3 = [10, 20];
    $array4 = [30, 40];
    $mergedNumeric = array_merge($array3, $array4);
    print_r($mergedNumeric);
    /*
    输出:
    Array
    (
        [0] => 10
        [1] => 20
        [2] => 30
        [3] => 40
    )
    */
    ?>

    这是我个人在大多数情况下首选的合并方式,因为它处理字符串键覆盖和数值键重索引的方式通常是我想要的。

  3. 使用 array_merge_recursive() 函数 这个函数用于递归地合并数组。它的主要特点是,当遇到相同的字符串键且对应的值都是数组时,它会递归地合并这些子数组。如果相同键的值一个是数组,另一个不是数组(比如字符串或整数),它会将这两个值都放入一个新的数组中。

    <?php
    $array1 = ['a' => 1, 'b' => ['c' => 2, 'd' => 3]];
    $array2 = ['a' => 4, 'b' => ['e' => 5], 'f' => 6];
    $array3 = ['g' => 7, 'b' => 'not_an_array']; // 演示非数组值冲突
    
    $mergedArray = array_merge_recursive($array1, $array2);
    print_r($mergedArray);
    /*
    输出:
    Array
    (
        [a] => Array  // 'a' 键的值都是标量,所以被放入一个数组中
            (
                [0] => 1
                [1] => 4
            )
        [b] => Array  // 'b' 键的值都是数组,所以递归合并
            (
                [c] => 2
                [d] => 3
                [e] => 5
            )
        [f] => 6
    )
    */
    
    $mergedArrayWithScalarConflict = array_merge_recursive($array1, $array3);
    print_r($mergedArrayWithScalarConflict);
    /*
    输出:
    Array
    (
        [a] => 1
        [b] => Array
            (
                [c] => 2
                [d] => 3
                [0] => not_an_array // 注意这里,非数组值被追加进来了
            )
        [g] => 7
    )
    */
    ?>

    array_merge_recursive() 在处理配置项或者多层级数据结构时非常有用,但它的行为在键值冲突时(特别是标量值冲突)可能需要你仔细考虑。

PHP数组合并时,键名冲突了怎么办?

键名冲突是数组合并中最常遇到的“陷阱”,不同的合并方式对此有截然不同的处理逻辑。理解这些差异,才能避免数据丢失或结果不符合预期。

  1. + 运算符:左边优先 当使用+运算符进行数组联合时,如果两个数组中存在相同的字符串键,左边(第一个)数组的值会保留下来,右边数组中相同键的值会被完全忽略。对于数值键,它不会覆盖,而是直接将右边数组中不冲突的数值键元素追加到左边数组的后面。

    • 场景: 你有一个“默认配置”数组,想用一个“用户配置”数组去补充它,但又不希望用户配置覆盖掉默认配置中那些不应该被修改的项。或者,你只是想把一个数组中没有的元素从另一个数组中“搬过来”。

    • 示例:

      $defaultSettings = ['theme' => 'dark', 'font_size' => 16, 'debug' => false];
      $userSettings = ['font_size' => 18, 'debug' => true, 'language' => 'en'];
      
      $finalSettings = $defaultSettings + $userSettings;
      print_r($finalSettings);
      /*
      输出:
      Array
      (
          [theme] => dark
          [font_size] => 16  // 保留了默认设置的值
          [debug] => false   // 保留了默认设置的值
          [language] => en
      )
      */

      可以看到,font_size和debug都保留了$defaultSettings的值。

  2. array_merge() 函数:右边优先,数值键重索引array_merge()的行为更像“更新”或“合并覆盖”。如果存在相同的字符串键,右边(后面)数组的值会覆盖掉左边(前面)数组的值。对于数值键,它会重新索引所有数值键,将所有数值键的元素视为新元素,并从0开始重新分配索引。

    • 场景: 这是最常见的合并需求,比如你有一个基本数据数组,然后从数据库或用户输入获取到更新数据,想用更新数据覆盖掉基本数据。

    • 示例:

      $baseData = ['id' => 1, 'name' => 'Alice', 'status' => 'active'];
      $updateData = ['name' => 'Alicia', 'status' => 'inactive', 'last_login' => '2023-10-27'];
      
      $mergedData = array_merge($baseData, $updateData);
      print_r($mergedData);
      /*
      输出:
      Array
      (
          [id] => 1
          [name] => Alicia    // 被 $updateData 覆盖
          [status] => inactive // 被 $updateData 覆盖
          [last_login] => 2023-10-27
      )
      */
  3. array_merge_recursive() 函数:递归合并或生成值数组 这是最复杂的冲突处理方式。

    • 字符串键(值都是数组): 如果两个数组在相同字符串键下对应的值都是数组,array_merge_recursive()会递归地合并这两个子数组。

    • 字符串键(至少一个值不是数组): 如果相同字符串键下的值,至少有一个不是数组(比如一个是字符串,一个是数组;或者都是字符串),那么这些值会被放入一个新的数组中。

      btpanel phpsite 宝塔面板PHP网站
      btpanel phpsite 宝塔面板PHP网站

      宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

      下载
    • 数值键: 行为与array_merge()类似,都会被重新索引。

    • 场景: 深度合并多层嵌套的配置数组,或者在处理一些特定数据结构时,你希望所有冲突的值都能被保留下来,而不是简单覆盖。

    • 示例:

      $config1 = ['db' => ['host' => 'localhost', 'port' => 3306], 'app' => ['name' => 'MyApp']];
      $config2 = ['db' => ['user' => 'root'], 'app' => ['version' => '1.0']];
      $config3 = ['db' => 'mysql_connection_string']; // 冲突但不是数组
      
      $mergedRecursive = array_merge_recursive($config1, $config2);
      print_r($mergedRecursive);
      /*
      输出:
      Array
      (
          [db] => Array
              (
                  [host] => localhost
                  [port] => 3306
                  [user] => root
              )
          [app] => Array
              (
                  [name] => MyApp
                  [version] => 1.0
              )
      )
      */
      
      $mergedWithScalarConflict = array_merge_recursive($config1, $config3);
      print_r($mergedWithScalarConflict);
      /*
      输出:
      Array
      (
          [db] => Array
              (
                  [host] => localhost
                  [port] => 3306
                  [0] => mysql_connection_string // 注意这里,字符串被追加到数组中
              )
          [app] => Array
              (
                  [name] => MyApp
              )
      )
      */

      选择哪种方式,完全取决于你对冲突键的处理预期。没有绝对的好坏,只有是否符合你的业务逻辑。

如何高效合并大型数组,避免性能问题?

处理大型数组合并时,性能确实是个不得不考虑的问题。PHP虽然在底层对数组操作做了很多优化,但如果操作不当,依然可能导致内存溢出或执行时间过长。

  1. 理解函数开销:

    • array_merge() 和 + 运算符在C语言层面实现,通常效率很高。但当涉及的数组非常大(比如几十万甚至上百万个元素),并且需要频繁合并时,依然会累积可观的开销。
    • array_merge_recursive() 由于其递归特性,开销通常会更大,因为它需要进行更多的检查和操作来处理嵌套结构和冲突。
  2. 减少不必要的合并: 这是最直接的优化。在代码设计时,问问自己:真的需要合并所有数据吗?

    • 按需合并: 如果你只需要合并数组中的一部分数据,或者只有特定条件满足时才合并,那么就只做必要的合并。例如,如果只有用户提供了新数据才去合并更新。
    • 延迟合并: 如果合并后的数据不是立即需要,可以考虑延迟到真正使用时再进行。
  3. 使用 array_replace() 和 array_replace_recursive() 替代特定场景下的 array_merge(): 这两个函数行为类似array_merge(),都是右边覆盖左边。但它们有一个重要区别:它们不会重新索引数值键。这意味着如果你只是想用一个数组的值去“替换”另一个数组中对应键的值(无论字符串键还是数值键),并且不希望数值键被重置,那么它们可能是更高效的选择,尤其是在数值键占比较大的数组中。

    • array_replace(): 非递归替换。

    • array_replace_recursive(): 递归替换。

    • 示例:

      <?php
      $array1 = [0 => 'a', 1 => 'b', 'key' => 'old'];
      $array2 = [1 => 'c', 'key' => 'new'];
      
      $merged = array_merge($array1, $array2);
      print_r($merged);
      /*
      输出:
      Array
      (
          [0] => a
          [1] => b // array_merge 重新索引,所以这里是 array1 的 1
          [2] => c // array_merge 重新索引,所以 array2 的 1 变成了 2
          [key] => new
      )
      */
      
      $replaced = array_replace($array1, $array2);
      print_r($replaced);
      /*
      输出:
      Array
      (
          [0] => a
          [1] => c // array_replace 直接替换了 array1 的 1
          [key] => new
      )
      */
      ?>

      在某些场景下,array_replace()可以避免array_merge()在处理数值键时创建新索引的开销。

  4. 循环迭代手动合并(特定复杂场景): 虽然内置函数通常更快,但在一些非常复杂的合并逻辑(比如需要根据特定条件合并,或者合并过程中需要对值进行转换)下,手动使用foreach循环可能更清晰,也可能让你对性能有更精细的控制。但这通常是最后的手段,因为它会增加代码量和维护成本。

    <?php
    $array1 = ['id' => 1, 'name' => 'Alice'];
    $array2 = ['name' => 'Alicia', 'age' => 30];
    $result = $array1; // 以 array1 为基础
    
    foreach ($array2 as $key => $value) {
        // 假设我们只合并 array1 中没有的键,或者 array1 中有但值为空的键
        if (!isset($result[$key]) || empty($result[$key])) {
            $result[$key] = $value;
        }
    }
    print_r($result);
    /*
    输出:
    Array
    (
        [id] => 1
        [name] => Alice // name 键在 array1 中不为空,所以没有被覆盖
        [age] => 30
    )
    */
    ?>

    这种方式虽然灵活,但需要你仔细测试其性能,确保不会比内置函数慢太多。

  5. 内存管理: 合并大数组会占用大量内存。如果你的脚本经常处理这类操作,考虑以下几点:

    • 及时释放不再需要的变量: 使用unset()释放大数组的内存。
    • 增加PHP内存限制: 在php.ini中调整memory_limit,但这只是治标不治本。
    • 分块处理: 如果数据量实在太大,考虑将数据分块处理,而不是一次性加载所有数据到内存中。这可能涉及到从数据库分批读取,或者将文件分段处理。

处理大型数组,关键在于审慎思考,选择最适合当前场景的工具,并时刻关注性能和内存消耗。

除了简单的合并,还有哪些高级的数组处理技巧可以结合使用?

数组合并往往只是数据处理链条中的一环,很少有项目只做简单的合并就完事儿。结合其他PHP数组函数,我们可以实现更复杂、更精细的数据操作。

  1. array_filter():合并后的数据清洗 在合并数组之后,你可能需要移除一些空值、无效值或者不符合特定条件的元素。array_filter()非常适合做这个。

    • 场景: 合并了多个用户输入,但有些字段可能为空字符串或null,需要清除。

    • 示例:

      <?php
      $data = ['name' => 'John Doe', 'email' => '', 'age' => 30, 'phone' => null];
      $newData = ['address' => '123 Main St', 'email' => 'john@example.com'];
      
      $merged = array_merge

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

549

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6144

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3084

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

1812

2025.10.17

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

798

2025.12.04

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1798

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2804

2023.09.04

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 191人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn