php中数组如何转换为json php数组转json的方法与注意事项

冰火之心
发布: 2025-08-29 13:13:01
原创
958人浏览过
最核心方法是使用json_encode()函数将PHP数组转为JSON字符串,需确保数据为UTF-8编码、避免资源类型和循环引用,并通过json_last_error()检查错误;处理中文时应使用JSON_UNESCAPED_UNICODE选项;反向转换则用json_decode()并验证返回值与数据结构。

php中数组如何转换为json php数组转json的方法与注意事项

PHP中将数组转换为JSON,最核心且直接的方法是使用内置的

json_encode()
登录后复制
函数。这个函数能够将PHP数组(或其他数据类型)序列化为符合JSON标准的字符串,是前后端数据交互的基石。但在实际操作中,我们常常会遇到编码、数据类型或配置不当导致的问题,需要一些技巧和注意事项来确保转换的顺利和正确。

解决方案

要将PHP数组转换为JSON,你只需要调用

json_encode()
登录后复制
函数,并将你的PHP数组作为参数传入。

<?php
$data = [
    'name' => '张三',
    'age' => 30,
    'isStudent' => false,
    'courses' => ['PHP', 'JavaScript', 'SQL'],
    'details' => [
        'city' => '北京',
        'occupation' => '开发者'
    ]
];

$json_string = json_encode($data);

if ($json_string === false) {
    echo "JSON 编码失败!错误信息:" . json_last_error_msg();
} else {
    echo $json_string;
}
// 预期输出(如果未指定JSON_UNESCAPED_UNICODE):
// {"name":"\u5f20\u4e09","age":30,"isStudent":false,"courses":["PHP","JavaScript","SQL"],"details":{"city":"\u5317\u4eac","occupation":"\u5f00\u53d1\u8005"}}
// 如果指定了JSON_UNESCAPED_UNICODE:
// {"name":"张三","age":30,"isStudent":false,"courses":["PHP","JavaScript","SQL"],"details":{"city":"北京","occupation":"开发者"}}
?>
登录后复制

json_encode()
登录后复制
函数默认会返回一个JSON格式的字符串。如果转换失败,它会返回
false
登录后复制
。所以,在实际开发中,检查返回值并利用
json_last_error()
登录后复制
json_last_error_msg()
登录后复制
来获取错误信息,是排查问题的关键一步。我个人觉得,很多人在刚开始用的时候,往往忽略了错误检查,结果出了问题一头雾水,这习惯可要不得。

json_encode()
登录后复制
为什么会返回
false
登录后复制
?常见的转换失败原因有哪些?

这事儿挺有意思的,

json_encode()
登录后复制
返回
false
登录后复制
,通常意味着你的PHP数据结构里藏着一些JSON不认识的“异类”,或者编码出了岔子。我以前就因为这个栽过不少跟头,排查起来挺费劲的。

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

最常见的原因,我总结下来大概有这么几点:

  1. 非UTF-8编码的字符串:JSON标准要求字符串必须是UTF-8编码。如果你的PHP数组中包含了其他编码(比如GBK或ISO-8859-1)的字符串,

    json_encode()
    登录后复制
    就会懵圈,直接返回
    false
    登录后复制
    。这是一个非常普遍的坑,尤其是在处理一些老旧系统或者从数据库读取数据时没有正确设置字符集的情况下。

    • 解决方案:在使用
      json_encode()
      登录后复制
      之前,确保所有字符串都已经被转换成UTF-8编码。你可以用
      mb_convert_encoding()
      登录后复制
      或者
      iconv()
      登录后复制
      函数来做这件事。
    $non_utf8_string = mb_convert_encoding('你好,世界!', 'GBK', 'UTF-8'); // 假设这是一个GBK字符串
    $data_with_bad_encoding = ['message' => $non_utf8_string];
    $result = json_encode($data_with_bad_encoding); // 这可能会返回 false
    
    // 正确的做法
    $data_fixed_encoding = ['message' => mb_convert_encoding($non_utf8_string, 'UTF-8', 'GBK')];
    // 或者更直接地,确保源头就是UTF-8
    $result_fixed = json_encode($data_fixed_encoding);
    登录后复制
  2. 不可序列化的数据类型:JSON只支持有限的数据类型:字符串、数字、布尔值、

    null
    登录后复制
    、数组(JSON的数组)和对象(JSON的对象)。如果你尝试编码一个资源类型(比如文件句柄、数据库连接)、闭包函数或者一些PHP特有的复杂对象(除非该对象实现了
    JsonSerializable
    登录后复制
    接口),
    json_encode()
    登录后复制
    就无能为力了。

    • 解决方案:在编码前,过滤掉或转换这些不可序列化的数据。对于自定义对象,可以实现
      JsonSerializable
      登录后复制
      接口,或者在编码前手动将其属性提取到普通数组中。
  3. 循环引用(Recursion):当你的数组或对象中存在循环引用,比如A引用B,B又引用A,

    json_encode()
    登录后复制
    在尝试遍历时会陷入无限循环,最终导致失败。

    • 解决方案:在构建数据结构时避免循环引用,或者在编码前手动打破这些循环。
  4. 编码深度过大:PHP的

    json_encode()
    登录后复制
    有一个默认的递归深度限制(通常是512)。如果你的数组嵌套层级太深,超过了这个限制,也会导致编码失败。

    • 解决方案:检查你的数据结构,看是否可以扁平化一些层级。如果确实需要深层嵌套,可以通过
      json_encode($data, $options, $depth)
      登录后复制
      的第三个参数来增加深度限制,但这通常不是一个好兆头,可能说明你的数据结构设计需要优化。
  5. 内存不足:当处理非常庞大的数组时,生成JSON字符串可能会消耗大量内存,如果超出PHP的内存限制,也会导致失败。

    • 解决方案:增加
      memory_limit
      登录后复制
      配置,或者考虑分块处理数据,而不是一次性编码整个巨型数组。

无论哪种情况,记住,

json_last_error()
登录后复制
json_last_error_msg()
登录后复制
是你的好朋友。

<?php
$resource = fopen('php://temp', 'r');
$data_with_resource = ['id' => 1, 'file_handle' => $resource];

$json_string = json_encode($data_with_resource);

if ($json_string === false) {
    echo "JSON 编码失败!错误代码: " . json_last_error() . ", 错误信息: " . json_last_error_msg() . "\n";
} else {
    echo $json_string;
}
fclose($resource); // 记得关闭资源
// 预期输出:JSON 编码失败!错误代码: 7, 错误信息: Type is not supported
?>
登录后复制

这个例子就清楚地展示了资源类型无法编码的情况。

PHP 数组转换为 JSON 时,如何处理中文字符乱码问题?

中文字符乱码,这简直是PHP开发者在处理JSON时最常遇到的“拦路虎”之一。我个人觉得,这主要源于对字符编码理解不够深入,以及对

json_encode()
登录后复制
默认行为的不熟悉。

json_encode()
登录后复制
在默认情况下,会将非ASCII字符(包括中文)转换为
\uXXXX
登录后复制
这种Unicode转义序列。这本身不是乱码,而是符合JSON规范的,因为它保证了JSON字符串在各种系统和编码环境下都能被正确解析。但问题是,这样生成的JSON字符串在调试或者直接查看时,可读性极差。

<?php
$data = ['message' => '你好,世界!'];
$json_default = json_encode($data);
echo "默认编码结果: " . $json_default . "\n";
// 默认编码结果: {"message":"\u4f60\u597d\uff0c\u4e16\u754c\uff01"}
?>
登录后复制

你看,

\u4f60\u597d
登录后复制
这些东西,看着就头疼。

为了让中文字符在JSON中直接显示,提高可读性,我们需要使用

json_encode()
登录后复制
的第二个参数——
options
登录后复制
,并传入
JSON_UNESCAPED_UNICODE
登录后复制
这个常量。

<?php
$data = ['message' => '你好,世界!'];
$json_unescaped = json_encode($data, JSON_UNESCAPED_UNICODE);
echo "使用 JSON_UNESCAPED_UNICODE: " . $json_unescaped . "\n";
// 使用 JSON_UNESCAPED_UNICODE: {"message":"你好,世界!"}
?>
登录后复制

这样一来,中文字符就直接显示了,是不是舒服多了?

但是,这里有一个非常重要的前提:你的PHP脚本、你的数据源(比如数据库)、以及传递给

json_encode()
登录后复制
的字符串本身,都必须是UTF-8编码的。如果你的源字符串不是UTF-8,即使你使用了
JSON_UNESCAPED_UNICODE
登录后复制
,也可能导致:

Find JSON Path Online
Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online 30
查看详情 Find JSON Path Online
  1. json_encode()
    登录后复制
    返回
    false
    登录后复制
    (正如前面所说,非UTF-8字符串导致编码失败)。
  2. 即使没有返回
    false
    登录后复制
    ,也可能输出乱码(如果PHP在处理非UTF-8字符串时,误以为是UTF-8并进行了错误的转义或处理)。

所以,解决中文乱码的根本之道是:全程UTF-8

  • 数据库连接:确保你的数据库连接字符集设置为UTF-8(例如,
    SET NAMES utf8mb4;
    登录后复制
    )。
  • PHP文件编码:确保你的PHP文件本身是UTF-8编码保存的。
  • HTTP头:如果你的PHP脚本是作为Web服务输出JSON,确保设置了正确的
    Content-Type
    登录后复制
    头:
    header('Content-Type: application/json; charset=utf-8');
    登录后复制

做到了这些,再配合

JSON_UNESCAPED_UNICODE
登录后复制
,中文乱码问题基本上就能迎刃而解了。

json_encode()
登录后复制
的可选参数
options
登录后复制
有哪些实用功能?

json_encode()
登录后复制
options
登录后复制
参数,简直是一个宝藏,它能让你对JSON输出格式进行精细控制,解决很多实际问题。我个人觉得,掌握这些选项,能让你的JSON处理能力上一个台阶。除了前面提到的
JSON_UNESCAPED_UNICODE
登录后复制
,还有几个常用的,我来给你掰扯掰扯:

  1. JSON_PRETTY_PRINT
    登录后复制
    :让JSON输出格式化,带有缩进和换行,提高可读性。

    • 场景:调试API响应、生成可读性高的配置文件。
    • 示例
      $data = ['id' => 1, 'name' => '产品A', 'price' => 99.99];
      echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
      /*
      输出:
      {
      "id": 1,
      "name": "产品A",
      "price": 99.99
      }
      */
      登录后复制

      这个选项在开发阶段简直是神器,一眼就能看出JSON结构,不用再借助外部工具格式化。

  2. JSON_NUMERIC_CHECK
    登录后复制
    :将所有数值型的字符串(比如
    "123"
    登录后复制
    )自动转换为JSON数字类型。

    • 场景:从数据库读取的数据,数字字段可能被PHP处理成字符串。
    • 示例
      $data = ['id' => '123', 'amount' => '45.67', 'code' => 'ABC'];
      echo json_encode($data);
      // {"id":"123","amount":"45.67","code":"ABC"} - 都是字符串
      登录后复制

    echo json_encode($data, JSON_NUMERIC_CHECK); // {"id":123,"amount":45.67,"code":"ABC"} - 数字型字符串变成了数字

    这在前后端接口对接时非常有用,可以避免前端拿到数字字符串后还需要手动转换的麻烦。
    登录后复制
  3. JSON_FORCE_OBJECT
    登录后复制
    :强制将非关联数组(索引数组)编码为JSON对象,而不是JSON数组。

    • 场景:当你有一个空数组或者只有一个元素的索引数组,但你希望它在JSON中始终表现为一个对象(
      {}
      登录后复制
      而不是
      []
      登录后复制
      ),这在某些API设计中可能有用。
    • 示例
      $empty_array = [];
      $indexed_array = ['apple', 'banana'];
      登录后复制

    echo "默认空数组: " . json_encode($empty_array) . "\n"; // 默认空数组: []

    echo "默认索引数组: " . json_encode($indexed_array) . "\n"; // 默认索引数组: ["apple","banana"]

    echo "强制对象空数组: " . json_encode($empty_array, JSON_FORCE_OBJECT) . "\n"; // 强制对象空数组: {}

    echo "强制对象索引数组: " . json_encode($indexed_array, JSON_FORCE_OBJECT) . "\n"; // 强制对象索引数组: {"0":"apple","1":"banana"}

    这个选项用得不多,但遇到特定需求时,它能帮你省去一些手动转换的逻辑。
    登录后复制
  4. JSON_UNESCAPED_SLASHES
    登录后复制
    :不转义斜杠
    /
    登录后复制

    • 场景:当你的数据中包含URL路径时,
      json_encode()
      登录后复制
      默认会把
      /
      登录后复制
      转义成
      \/
      登录后复制
      。虽然这不影响解析,但会增加字符串长度,有时也会影响可读性。
    • 示例
      $data = ['url' => 'https://www.php.cn/link/c1481a88d8e582ce58f9413d5ac93360'];
      echo "默认斜杠转义: " . json_encode($data) . "\n";
      // 默认斜杠转义: {"url":"http:\/\/example.com\/path\/to\/resource"}
      登录后复制

    echo "不转义斜杠: " . json_encode($data, JSON_UNESCAPED_SLASHES) . "\n"; // 不转义斜杠: {"url":"https://www.php.cn/link/c1481a88d8e582ce58f9413d5ac93360"}

    这个选项在处理包含大量URL的JSON时,能让输出更简洁。
    登录后复制

这些选项可以组合使用,用位运算符

|
登录后复制
连接即可,就像
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
登录后复制
那样。灵活运用它们,能让你的PHP在处理JSON时更加得心应手。

如何将 JSON 字符串安全地转换回 PHP 数组?

把JSON字符串转换回PHP数组,这个过程叫做反序列化或解码,主要用到的是

json_decode()
登录后复制
函数。这就像是
json_encode()
登录后复制
的逆操作,但同样,也有不少需要注意的地方,尤其是在“安全”和“正确”上。

json_decode()
登录后复制
函数接受两个主要参数:

  1. $json
    登录后复制
    :要解码的JSON字符串。
  2. $associative
    登录后复制
    (可选):一个布尔值。如果设置为
    true
    登录后复制
    ,JSON对象将被解码为PHP关联数组;如果设置为
    false
    登录后复制
    (默认值),JSON对象将被解码为PHP
    stdClass
    登录后复制
    对象。

我个人习惯是,绝大多数情况下都把

$associative
登录后复制
设为
true
登录后复制
,这样拿到的就是关联数组,操作起来更符合PHP开发者的直觉。

<?php
$json_string = '{"name":"张三","age":30,"isStudent":false,"courses":["PHP","JavaScript"],"details":{"city":"北京"}}';

// 转换为PHP对象(默认行为)
$php_object = json_decode($json_string);
echo "转换为PHP对象:\n";
print_r($php_object);
// 输出:
// stdClass Object
// (
//     [name] => 张三
//     [age] => 30
//     [isStudent] =>
//     [courses] => Array
//         (
//             [0] => PHP
//             [1] => JavaScript
//         )
//     [details] => stdClass Object
//         (
//             [city] => 北京
//         )
// )

// 转换为PHP关联数组
$php_array = json_decode($json_string, true);
echo "\n转换为PHP关联数组:\n";
print_r($php_array);
// 输出:
// Array
// (
//     [name] => 张三
//     [age] => 30
//     [isStudent] =>
//     [courses] => Array
//         (
//             [0] => PHP
//             [1] => JavaScript
//         )
//     [details] => Array
//         (
//             [city] => 北京
//         )
// )
?>
登录后复制

关于“安全地”转换:

这里的“安全”主要指的是错误处理输入验证。因为你收到的JSON字符串可能来自外部,它可能是无效的、恶意的,或者只是格式不正确。

  1. 检查

    json_decode()
    登录后复制
    的返回值
    json_decode()
    登录后复制
    在解析失败时会返回
    null
    登录后复制
    。所以,你总是应该检查它的返回值。

    $invalid_json = '{"name":"John", "age":30, }'; // 错误的JSON格式
    $result = json_decode($invalid_json, true);
    
    if ($result === null) {
        echo "JSON 解码失败!错误代码: " . json_last_error() . ", 错误信息: " . json_last_error_msg() . "\n";
    } else {
        print_r($result);
    }
    // 预期输出:JSON 解码失败!错误代码: 4, 错误信息: Syntax error
    登录后复制

    json_encode()
    登录后复制
    一样,
    json_last_error()
    登录后复制
    json_last_error_msg()
    登录后复制
    在这里也是排查利器。

  2. 验证解码后的数据结构: 即使

    json_decode()
    登录后复制
    成功返回了数组或对象,你也不能完全信任它的内容。比如,你期望一个
    id
    登录后复制
    字段是整数,但实际可能是一个字符串或者干脆不存在。

    • 解决方案:使用
      isset()
      登录后复制
      is_array()
      登录后复制
      is_numeric()
      登录后复制
      等PHP函数对解码后的数据进行严格的类型和结构检查。这尤其重要,因为它关系到你的应用程序的稳定性和安全性,避免潜在的注入或逻辑错误。
    $user_data_json = '{"user_id":"abc", "username":"test"}'; // user_id 应该是数字
    $user_data = json_decode($user_data_json, true);
    
    if ($user_data !== null && isset($user_data['user_id']) && is_numeric($user_data['user_id'])) {
        $user_id = (int)$user_data['user_id'];
        echo "用户ID: " . $user_id . "\n";
    } else {
        echo "无效的用户数据或用户ID格式不正确。\n";
    }
    登录后复制

    我个人觉得,这一步是很多新手容易忽略的,但却是防御性编程中不可或缺的一环。你永远不知道外部输入会是什么妖魔鬼怪,所以做好验证是保护自己的关键。

通过结合

json_decode()
登录后复制
的返回值检查和对解码后数据内容的严格验证,你就能相对安全地将JSON字符串转换回PHP数组,并确保应用程序的健壮性。

以上就是php中数组如何转换为json php数组转json的方法与注意事项的详细内容,更多请关注php中文网其它相关文章!

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

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

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号