如何在Swift与PHP间实现JSON变量的发送与接收?
Swift字典转JSON发送至PHP的正确实现
一、Swift端修正方案
原代码核心问题是将JSON编码后的Data直接拼接成POST参数,导致传递的不是有效JSON字符串。以下是两种可行的修正方案:
方案1:作为POST表单参数发送
func appl(_ application: UIApplication) { print("...........................................................") let mappedViewsArray = DisplayVC.viewsArray.map { ($0, 1) } let viewsArrayCount = Dictionary(mappedViewsArray, uniquingKeysWith: +) print(viewsArrayCount) do { // 将字典转为JSON字符串(自动将Int类型的Key转为JSON要求的字符串键) let jsonData = try JSONSerialization.data(withJSONObject: viewsArrayCount, options: []) guard let jsonString = String(data: jsonData, encoding: .utf8) else { print("JSON数据转字符串失败") return } // 对JSON字符串做URL编码,避免特殊字符破坏参数结构 guard let encodedJson = jsonString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { print("JSON字符串URL编码失败") return } let urlPath = "http://localhost/updateViews.php" guard let url = URL(string: urlPath) else { print("无效URL") return } var request = URLRequest(url: url) request.httpMethod = "POST" // 设置表单类型的请求头 request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") // 拼接POST参数 let postString = "JSONDataEncoded=\(encodedJson)" request.httpBody = postString.data(using: .utf8) let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("数据更新失败: \(error.localizedDescription)") return } print("数据更新成功") // 可选:打印PHP返回的响应内容 if let data = data, let responseString = String(data: data, encoding: .utf8) { print("PHP响应: \(responseString)") } } task.resume() print("生成的JSON字符串: \(jsonString)") } catch { print("操作失败") print("错误信息: ", error) } }
方案2:直接发送JSON请求体(更简洁)
跳过表单参数,直接将JSON作为请求体发送,PHP端读取原始请求体即可:
func appl(_ application: UIApplication) { print("...........................................................") let mappedViewsArray = DisplayVC.viewsArray.map { ($0, 1) } let viewsArrayCount = Dictionary(mappedViewsArray, uniquingKeysWith: +) print(viewsArrayCount) do { let jsonData = try JSONSerialization.data(withJSONObject: viewsArrayCount, options: []) let urlPath = "http://localhost/updateViews.php" guard let url = URL(string: urlPath) else { print("无效URL") return } var request = URLRequest(url: url) request.httpMethod = "POST" // 设置JSON类型的请求头 request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = jsonData let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("数据更新失败: \(error.localizedDescription)") return } print("数据更新成功") if let data = data, let responseString = String(data: data, encoding: .utf8) { print("PHP响应: \(responseString)") } } task.resume() print("生成的JSON字符串: \(String(data: jsonData, encoding: .utf8)!)") } catch { print("操作失败") print("错误信息: ", error) } }
二、PHP端接收处理方案
对应方案1(表单参数)的PHP代码
修正语法错误、修复SQL注入风险,增加错误校验:
<?php // 补充数据库名称(替换为你的实际数据库名) $con = mysqli_connect("localhost", "root", "", "你的数据库名"); // 检查数据库连接 if (mysqli_connect_errno()) { die("MySQL连接失败: " . mysqli_connect_error()); } // 检查参数是否存在 if (!isset($_POST["JSONDataEncoded"])) { die("缺少JSONDataEncoded参数"); } $json = $_POST["JSONDataEncoded"]; // 解码JSON为关联数组 $updateViews = json_decode($json, true); // 检查JSON解码是否成功 if (json_last_error() !== JSON_ERROR_NONE) { die("无效JSON数据: " . json_last_error_msg()); } // 使用预处理语句避免SQL注入 $stmt = $con->prepare("UPDATE cars SET views = views + ? WHERE ID = ?"); if (!$stmt) { die("预处理语句创建失败: " . $con->error); } // 绑定参数(ii代表两个整数类型参数,根据你的字段类型调整) $stmt->bind_param("ii", $value, $key); foreach ($updateViews as $key => $value) { // 强制转换为整数,确保数据类型正确 $key = (int)$key; $value = (int)$value; if (!$stmt->execute()) { echo "ID $key 更新失败: " . $stmt->error . "\n"; } else { echo "ID $key 更新成功\n"; } } $stmt->close(); mysqli_close($con); ?>
对应方案2(JSON请求体)的PHP代码
如果Swift端直接发送JSON请求体,PHP需读取原始请求体:
<?php $con = mysqli_connect("localhost", "root", "", "你的数据库名"); if (mysqli_connect_errno()) { die("MySQL连接失败: " . mysqli_connect_error()); } // 读取原始JSON请求体 $json = file_get_contents('php://input'); $updateViews = json_decode($json, true); if (json_last_error() !== JSON_ERROR_NONE) { die("无效JSON数据: " . json_last_error_msg()); } $stmt = $con->prepare("UPDATE cars SET views = views + ? WHERE ID = ?"); $stmt->bind_param("ii", $value, $key); foreach ($updateViews as $key => $value) { $key = (int)$key; $value = (int)$value; if (!$stmt->execute()) { echo "ID $key 更新失败: " . $stmt->error . "\n"; } else { echo "ID $key 更新成功\n"; } } $stmt->close(); mysqli_close($con); ?>
关键注意事项
- JSON规范:JSON的键必须是字符串,Swift中
JSONSerialization会自动将Int类型的Key转为字符串,符合要求。 - URL编码:通过表单参数传递JSON时必须做URL编码,避免特殊字符导致参数解析错误。
- SQL防护:必须使用预处理语句绑定参数,禁止直接拼接SQL字符串,防止SQL注入攻击。
- 错误处理:两端都要增加错误校验,便于调试定位问题。
内容的提问来源于stack exchange,提问作者Cataster
相关产品推荐
相关产品推荐

