我折腾了3周,翻了无数篇文档,才搞懂php array的这些奇葩用法

我折腾了3周,翻了无数篇文档,才搞懂php array的这些奇葩用法 一

我原本以为 PHP 的数组(array)和其他语言差不多,无非就是个能装数据的集合。谁知道,一旦深入 web 前端开发需要和后端交互多一点之后,PHP array 的“脾气”真是一个比一个难搞。尤其是和 JavaScript、HTML 表单配合使用的时候,各种坑一不小心就踩上了。

  • H2: PHP 的数组到底有多“奇葩”?

  • 你可能听过一句话:PHP 的数组是“超能力集合体”。数组既可以是索引数组(indexed array),又可以是关联数组(associative array),甚至可以混合使用。不止如此,它还能被当成栈、队列、哈希表、甚至对象结构来用。

    H3: 数组键名的自动转换真的很迷惑

    $array = [
    

    true => '布尔true',

    1 => '数字1',

    '1' => '字符串1',

    1.0 => '浮点1.0',

    ];

    你以为这里有4个键?实际上 $array 最后只保留了一个键值对,因为 PHP 会把布尔、数字、字符串、浮点数键名自动转换成整数型,最终只有一个键:1

    如果你在处理表单数据时碰到这种情况,想通过 key 获取用户提交的表单项,结果直接“被覆盖”,调试都得怀疑人生。

  • H2: 和 HTML 表单联动时的那些坑

  • web 前端最常见的场景就是表单提交,尤其是多选框(checkbox)或动态表单项。这时候 PHP array 的解析方式就决定了你后台能不能正确接收前端数据。

    H3: name 属性的写法决定了 array 的结构

    
    
    
    

    提交之后,$_POST['user'] 会变成一个多维数组。如果你不清楚前端的 name 属性怎么拼写,很容易在后台接收不到正确的数据结构,或者数据丢失。

    表单提交后生成的 PHP 数组结构(可视化)

    字段名 数据类型 键名 备注
    name 字符串 ‘name’ 张三 用户姓名
    age 字符串 ‘age’ 18 用户年龄
    hobby 数组 ‘hobby’ [阅读, 写作] 爱好,多选
  • H2: 前端开发中用 json_encode() 搭配 PHP 数组,也不是没坑

  • 有时候为了方便把 PHP 数组传给前端 JavaScript,我们会用 json_encode()。但这个函数默认会把数字索引的数组转成 JSON 数组,关联数组转成对象。这意味着,如果数组里键名是混合的,结果前端拿到的数据结构可能和你预期完全不一样。

    H3: 举个简单但常见的例子

    $data = [
    

    "a" => 1,

    0 => "zero",

    "1" => "one"

    ];

    echo json_encode($data);

    输出的是:{"0":"zero","1":"one","a":1},虽然形式看似没问题,但前端用 Object.keys() 遍历时顺序可能变得不可控,而且原本希望是数组结构,结果变成了对象。

  • H2: array_merge()、array_replace() 这些函数居然会“吞键”

  • 我们前端有时候需要组装数据,比如通过 JS 构建一个结构,通过 AJAX 发给 PHP,PHP 接收到后可能需要用 array_merge() 合并几个数组。

    但如果你用 array_merge() 合并两个索引数组,PHP 会重新为结果数组重新编号,也就是说你原来的键会被抛弃,顺序也可能变化。

    $a = [2 => 'apple', 5 => 'banana'];
    

    $b = [8 => 'orange'];

    $result = array_merge($a, $b);

    输出结果:[0 => 'apple', 1 => 'banana', 2 => 'orange'],所有原来的键都没了。如果你希望保留键值,必须用 + 运算符或者 array_replace()

  • H2: 前端想要接收 PHP 数组?你得这么做

  • 对于前端来说,想获取后端传来的 PHP 数组数据,一般都会通过 Ajax 或页面渲染。要保证结构和内容一致,处理过程不能马虎。

  • 后端数组结构尽量规范,键名统一,不混用数字和字符串键。
  • json_encode($array, JSON_UNESCAPED_UNICODE) 避免中文乱码。
  • 前端拿到数据后,先判断结构:Array.isArray()typeof === 'object'
  • PHP array 的确很强大,但也很“任性”。一不注意,它的奇葩行为就能让你在前端调试页面数据调试一天。如果你做 web 前端又要跟 PHP 后台交互,理解这些 array 的细节真的是避坑的关键。

  • array_merge() 这个函数在 PHP 里挺常用的,特别是在需要把两个数组合并成一个的时候。但是它有个比较“激进”的做法,就是一旦发现两个数组都是索引数组,它就会直接把所有的值连起来,并重新从 0 开始编号,完全不管你原本给的键是什么。如果你原本在数组里特意安排了某些键名,比如前端展示顺序或者 ID 对应关系,那用 array_merge() 一不小心就全乱了。而如果是关联数组,两个数组中有相同的键名,后者的值会把前者的值覆盖掉,这点倒还挺好理解的。

    反过来看 array_replace(),它的行为就“保守”多了。它不会重新给索引编号,而是以第一个数组为基础,把第二个数组中键名相同的内容替换掉,剩下的保持不变。举个例子,如果你前面一个数组有键名为 "title""desc",后面的数组只提供了 "desc",那结果就是只替换 "desc""title" 原样保留。这在一些需要保留默认配置、只更新部分值的场景下特别实用,比如你在前端传了部分设置给后台,后台就可以用 array_replace() 合理补全默认项,而不用担心整个数组被重构或者顺序被破坏。


    H3: PHP 中数组和其他编程语言的数组有什么区别?

    PHP 中的数组既可以是索引数组,也可以是关联数组,甚至可以混合使用。与其他语言相比,PHP 的数组不仅可以保存单一数据类型,还能接纳多种类型的数据,包括对象和其他数组,这种灵活性使得它的使用场景更加广泛,但也容易产生混淆。

    H3: PHP 数组键名的自动转换是如何工作的?

    PHP 会自动将布尔、数字、字符串和浮点数键名转换为整数型键名。在同一个数组中,如果存在相同的键名,PHP 将只保留最后一个键对应的值, 在使用数组时一定要小心键名的类型,避免数据被不必要地覆盖。

    H3: 如何在前端获取 PHP 数组的数据?

    可以通过 AJAX 调用 PHP 脚本来获取数据。在 PHP 中使用 json_encode() 函数将数组转换为 JSON 格式传递给前端,并确保在 AJAX 请求中正确设置内容类型。前端可以使用 JSON.parse() 方法解析接收到的数据。

    H3: 为什么要使用 JSON_UNESCAPED_UNICODE 选项?

    使用 json_encode($array, JSON_UNESCAPED_UNICODE) 有助于避免中文乱码问题。当数组中包含中文字符时,不加此选项将导致输出的 JSON 的中文字符被转义,从而影响前端展示的效果。

    H3: array_merge() 和 array_replace() 有什么区别?

    array_merge() 会重新索引并合并所有数组元素,当键名相同的情况下,会覆盖之前的值。而 array_replace() 会保留原数组的键名,仅用新的数组填充相应的键名,没有的则不受影响, 在数据结构需要保留时,使用 array_replace() 更为合适。

    © 版权声明
    THE END
    喜欢就支持一下吧
    点赞13 分享
    评论 抢沙发

    请登录后发表评论

      暂无评论内容