PHP发送JSON数据的完整指南
在Web开发中,JSON(JavaScript Object Notation)因其轻量级、易读性和跨语言兼容性,成为前后端数据交互的主流格式,PHP作为后端开发常用语言,经常需要将数据封装为JSON格式并发送给客户端(如浏览器、移动端或其他服务),本文将详细介绍PHP发送JSON数据的多种方法、关键注意事项及完整代码示例。
发送JSON数据的核心步骤
无论通过哪种方式发送JSON数据,核心步骤都包括:准备PHP数据数组→转换为JSON字符串→设置正确的HTTP头→输出数据。HTTP头设置是关键,需明确告知客户端返回的数据类型为application/json,以确保客户端能正确解析。
常用方法:使用json_encode()与header()
这是最基础也是最常用的方法,适用于直接输出JSON响应的场景(如API接口)。
准备PHP数据
PHP中的数组(关联数组或索引数组)是JSON数据的主要来源。
$data = [
"name" => "张三",
"age" => 25,
"is_student" => false,
"courses" => ["PHP", "MySQL", "JavaScript"],
"address" => null
];
转换为JSON字符串
使用json_encode()函数将PHP数组转换为JSON格式字符串:
$jsonString = json_encode($data);
注意:json_encode()默认会对中文进行Unicode编码(如\u5f20\u4e09),如果希望保留中文,需添加JSON_UNESCAPED_UNICODE选项:
$jsonString = json_encode($data, JSON_UNESCAPED_UNICODE);
设置HTTP响应头
通过header()函数设置Content-Type为application/json,并指定字符集(通常为UTF-8):
header('Content-Type: application/json; charset=utf-8');
输出JSON数据
直接使用echo或print输出JSON字符串:
echo $jsonString;
完整示例
<?php
// 1. 准备PHP数据
$data = [
"status" => "success",
"message" => "数据获取成功",
"data" => [
"id" => 1001,
"username" => "php_user",
"roles" => ["admin", "editor"]
]
];
// 2. 转换为JSON(保留中文)
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
// 3. 设置HTTP头
header('Content-Type: application/json; charset=utf-8');
// 4. 输出JSON
echo $json;
?>
输出结果:
{"status":"success","message":"数据获取成功","data":{"id":1001,"username":"php_user","roles":["admin","editor"]}}
处理常见错误
json_encode()失败
当PHP数据中包含无法编码的值(如资源类型)时,json_encode()会返回false,需提前检查并处理错误:
$data = [
"file" => fopen("test.txt", "r") // 资源类型无法编码
];
$json = json_encode($data);
if ($json === false) {
// 获取错误信息
$errorMsg = json_last_error_msg();
http_response_code(500); // 设置HTTP状态码为500
echo json_encode(["error" => "JSON编码失败: " . $errorMsg], JSON_UNESCAPED_UNICODE);
exit;
}
echo $json;
中文乱码
未设置JSON_UNESCAPED_UNICODE或HTTP头字符集不匹配时,中文可能显示为Unicode编码,确保:
json_encode()添加JSON_UNESCAPED_UNICODE;- HTTP头明确
charset=utf-8。
HTTP头重复设置
在header()函数前不能有任何输出(包括空格、换行),否则会报错“Cannot modify header information”,建议将HTTP头设置放在代码最前面,或使用ob_start()开启输出缓冲:
<?php
ob_start(); // 开启输出缓冲,避免提前输出
// 业务逻辑处理...
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
ob_end_flush(); // 输出缓冲区内容
?>
进阶场景:发送JSON数据到远程服务器
除了直接输出,PHP还常需要将JSON数据通过HTTP请求发送到远程服务(如调用第三方API),此时可使用cURL或file_get_contents()(需开启allow_url_fopen)。
使用cURL发送POST请求
cURL功能更强大,支持自定义请求头、超时设置等,适合复杂场景:
<?php
// 1. 准备要发送的数据
$data = [
"name" => "李四",
"email" => "lisi@example.com"
];
$jsonData = json_encode($data, JSON_UNESCAPED_UNICODE);
// 2. 初始化cURL
$ch = curl_init("https://api.example.com/users");
// 3. 设置cURL选项
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); // 请求方法
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); // 请求体
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 不直接输出,而是返回
curl_setopt($ch, CURLOPT_HTTPHEADER, [ // 设置请求头
"Content-Type: application/json",
"Content-Length: " . strlen($jsonData)
]);
// 4. 执行请求并获取响应
$response = curl_exec($ch);
// 5. 检查错误
if (curl_errno($ch)) {
echo "cURL错误: " . curl_error($ch);
} else {
// 解析响应(假设响应也是JSON)
$responseData = json_decode($response, true);
print_r($responseData);
}
// 6. 关闭cURL
curl_close($ch);
?>
使用file_get_contents()发送POST请求(简单场景)
若allow_url_fopen开启,可通过stream_context_create()设置请求头和数据:
<?php
$data = [
"token" => "abc123",
"action" => "get_info"
];
$jsonData = json_encode($data, JSON_UNESCAPED_UNICODE);
$context = stream_context_create([
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\n" .
"Content-Length: " . strlen($jsonData),
"content" => $jsonData,
"timeout" => 5 // 超时时间(秒)
]
]);
$response = file_get_contents("https://api.example.com/data", false, $context);
echo $response;
?>
最佳实践
- 始终设置正确的HTTP头:确保
Content-Type: application/json,避免客户端解析错误。 - 处理JSON编码错误:使用
json_last_error_msg()捕获并提示编码失败原因。 - 安全输出:若JSON数据中包含用户输入,需防范XSS攻击(虽然JSON本身对特殊字符有转义,但建议对关键内容过滤)。
- 统一响应格式:API接口建议返回固定格式(如
{"code": 200, "message": "success", "data": {...}}),便于前端处理。 - 日志记录:记录JSON发送和响应的日志,便于排查问题。
PHP发送JSON数据的核心是json_encode()和header()的组合,无论是直接输出还是远程请求,都需要注意数据格式、HTTP头设置及错误处理,这些方法,能高效实现前后端数据交互,满足API开发、第三方服务调用等场景需求。



还没有评论,来说两句吧...