Swift中使用Alamofire请求向数据库插入空值问题排查
注册接口插入数据库为空的问题排查与解决
我帮你梳理下这个问题的核心原因和解决方案——你遇到的数据库插入空值,本质是请求参数的编码格式和PHP端的读取方式不匹配,具体分析和解决方法如下:
问题场景回顾
你用Swift的Alamofire(或原生URLRequest)发送POST请求到PHP注册接口,但数据库始终插入空值。相关代码如下:
Swift端(Alamofire)代码
let headers : HTTPHeaders = ["Content-Type": "application/json"] let postString : Parameters = ["name": "com", "email": "raj123@v", "mobile": "123", "password": "123"] let signUpUrl = "myURL/api_register.php" Alamofire.request(signUpUrl, method: .post, parameters: postString, encoding: JSONEncoding.default, headers: headers).responseJSON { response in switch response.result { case .success: print(response) case .failure(let error): print(error) } }
PHP端API代码
header('Content-Type: application/json'); $return_arr = array(); $username=mysqli_real_escape_string($link,$_POST["name"]); $email=mysqli_real_escape_string($link,$_POST["email"]); $mobile=mysqli_real_escape_string($link,$_POST["mobile"]); $password=mysqli_real_escape_string($link,$_POST["password"]); $result=mysqli_query($link,"insert into users(name,email,mob,password) values('$username','$email','$mobile','$password')"); if(mysqli_num_rows($result)) { $row_array['status']=true; array_push($return_arr,$row_array); } else { $row_array['status']=false; array_push($return_arr,$row_array); } echo json_encode($return_arr); mysqli_close($link);
核心问题分析
你的Swift端用了JSONEncoding.default将参数以JSON格式发送,但PHP端却尝试用$_POST全局变量获取参数——这是关键错误!
$_POST只能解析application/x-www-form-urlencoded(表单编码)或multipart/form-data格式的请求数据,无法直接读取JSON格式的请求体,所以PHP端拿到的都是空值,最终插入数据库的自然也是空值。
另外,你的PHP代码还有一个小错误:mysqli_num_rows($result)不能用来判断INSERT语句是否成功,这个函数仅适用于SELECT查询的结果行数判断,INSERT成功时mysqli_query会返回true,失败返回false。
两种解决方案
方案一:修改Swift端,使用表单编码发送参数
保持PHP端的$_POST读取逻辑,把Swift端的编码方式改成URLEncoding.default,让参数以表单格式发送:
修改后的Alamofire代码
let headers : HTTPHeaders = ["Content-Type": "application/x-www-form-urlencoded"] let postString : Parameters = ["name": "com", "email": "raj123@v", "mobile": "123", "password": "123"] let signUpUrl = "myURL/api_register.php" Alamofire.request(signUpUrl, method: .post, parameters: postString, encoding: URLEncoding.default, headers: headers).responseJSON { response in switch response.result { case .success: print(response) case .failure(let error): print(error) } }
修改后的原生URLRequest代码
let signUpUrl = URL(string: "myURL/api_register.php")! var request = URLRequest(url: signUpUrl) request.httpMethod = "POST" request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") // 将参数转换为表单格式字符串 let postParameters = ["name": "com", "email": "raj123@v", "mobile": "123", "password": "123"] let postString = postParameters.map { "\($0.key)=\($0.value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)" }.joined(separator: "&") request.httpBody = postString.data(using: .utf8) // 发送请求 URLSession.shared.dataTask(with: request) { data, response, error in // 处理响应逻辑 }.resume()
方案二:修改PHP端,读取JSON格式的请求体
如果想保持Swift端的JSON编码方式,PHP端需要从php://input读取原始请求体,再解析为JSON对象:
修改后的PHP代码
header('Content-Type: application/json'); $return_arr = array(); // 读取并解析JSON请求体 $jsonRaw = file_get_contents('php://input'); $requestData = json_decode($jsonRaw, true); if($requestData) { // 从解析后的JSON对象中获取参数 $username = mysqli_real_escape_string($link, $requestData["name"] ?? ""); $email = mysqli_real_escape_string($link, $requestData["email"] ?? ""); $mobile = mysqli_real_escape_string($link, $requestData["mobile"] ?? ""); $password = mysqli_real_escape_string($link, $requestData["password"] ?? ""); // 执行插入操作,直接判断mysqli_query的返回值 $insertResult = mysqli_query($link,"insert into users(name,email,mob,password) values('$username','$email','$mobile','$password')"); if($insertResult) { $row_array['status'] = true; } else { $row_array['status'] = false; $row_array['error_msg'] = mysqli_error($link); // 添加错误信息方便调试 } array_push($return_arr, $row_array); } else { $row_array['status'] = false; $row_array['error_msg'] = "无效的JSON请求数据"; array_push($return_arr, $row_array); } echo json_encode($return_arr); mysqli_close($link);
内容的提问来源于stack exchange,提问作者user9368327
相关产品推荐
相关产品推荐

