You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:55:24