我在将数据发送到在线数据库时遇到问题。当我检查数据库时,似乎什么都没有发布。我对收到的响应执行了NSLog,它为空。
这是.php:
<?php $db_host="someurl.com"; $db_username="some_user"; $db_pass="some_passwd"; $db_name="some_db"; $conn = mysql_connect($db_host, $db_username, $db_pass) or die ("Could not connect to MySQL"); mysql_select_db("$db_name") or die ("No database"); // array for JSON response $json = $_SERVER['HTTP_JSON']; $data = json_decode($json); $some1_id = $data->some1_id; $imei = $data->imei; //does the imei exist? $result = mysql_query("SELECT * FROM usr_go WHERE imei = '".$imei."'"); if (mysql_num_rows($result) == 0){ if(isset($some1_id)) $result = mysql_query("INSERT INTO usr_go(some1_id, imei) VALUES('".$some1_id."','".$imei."')"); } else{ if(isset($some1_id)) $result = mysql_query("UPDATE usr_go SET some1_id = '".$some1_id."' WHERE imei = '". $imei ." AND some1_id IS NULL "); } mysql_close($conn); header('Content-type: application/json'); $response = $result; echo json_encode($response); ?>
但是,如果我将$ response硬编码为某个字符串值,而NSLog接收到的响应,它将接收适当的字符串值。
这是我的代码:
NSDictionary *dict = @{@"some1_id" : [NSNumber numberWithInt:self.cellIndex]}; NSError *error = nil; NSData *json = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error]; if (json) { NSURL *url = [NSURL URLWithString:@"someurl.com"]; NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; [req setHTTPMethod:@"POST"]; [req setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [req setHTTPBody:json]; NSURLResponse *res = nil; NSData *ret = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&error]; NSString *resString = [[NSString alloc] initWithData:ret encoding:NSUTF8StringEncoding]; NSLog(@"response String: %@",resString); NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@"JSON Output: %@", jsonString); } else { NSLog(@"Unable to serialize the data %@: %@", dictionary, error); }
是不是无法插入IMEI(这就是为什么它不发布)或其他问题的事实?
谢谢你的协助。
一些观察:
您应该使用msqliinterface而不是不推荐使用的mysql接口。
msqli
mysql
您永远不要接受输入,而只能在SQL语句中使用它。使用mysqli_real_escape_string或绑定值(如下所示)。这对于确保您不受SQL注入攻击的影响至关重要。如果插入的值恰好包含保留字符,它还可以防止出现无辜的错误。
mysqli_real_escape_string
不仅要尝试仅json_encode求结果的mysqli_query结果,还应构建更有意义的关联数组。例如,您可以检查mysqli调用的结果,如果成功,则返回一个JSON,如果失败,则返回另一个。我可能建议让故障再现返回错误消息。
json_encode
mysqli_query
mysqli
您应该在Web浏览器中测试PHP,或者使用类似于Charles的设备在PHP中进行测试。在处理客户端代码之前,请确保已获取期望的JSON。底线,看看是否可以彼此隔离地测试客户端代码和服务器代码(或首先使其尽可能简单)。
我对这种$_SERVER['HTTP_JSON'];结构不熟悉。如果这对您有用,那很好,但是在我的服务器上不起作用。历史上我已经完成了fopen,php://input如下图所示。
$_SERVER['HTTP_JSON'];
fopen
php://input
例如,这是一个不同的数据库/表,但是它可能说明了PHP代码可能是什么样的想法:
// read JSON input $handle = fopen("php://input", "rb"); $raw_post_data = ''; while (!feof($handle)) { $raw_post_data .= fread($handle, 8192); } fclose($handle); $request_data = json_decode($raw_post_data, true); // prepare header for reply header("Content-Type: application/json"); // open database $mysqli = new mysqli($host, $userid, $password, $database); // check connection if ($mysqli->connect_errno) { echo json_encode(array("success" => false, "message" => $mysqli->connect_error, "sqlerrno" => $mysqli->connect_errno)); exit(); } // perform the insert $sql = "INSERT INTO locations (message, device, longitude, latitude) VALUES (?, ?, ?, ?)"; if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("ssdd", $request_data["message"], $request_data["device"], $request_data["latitude"], $request_data["longitude"]); if (!$stmt->execute()) $response = array("success" => false, "message" => $mysqli->error, "sqlerrno" => $mysqli->errno, "sqlstate" => $mysqli->sqlstate); else $response = array("success" => true); $stmt->close(); } else { $response = array("success" => false, "message" => $mysqli->error, "sqlerrno" => $mysqli->errno, "sqlstate" => $mysqli->sqlstate); } $mysqli->close(); echo json_encode($response);
显然,为您的表更改此设置,但它说明了上述一些概念。通常,我会添加更多的错误检查(例如Content- Type,请求的,检查以确保在尝试使用变量之前已设置变量等),但是您可能会明白。
Content- Type
在客户端,还有一些较小的发现:
最严重的问题是的使用sendSynchronousRequest。请sendAsynchronousRequest改用(或无数其他异步方法)。切勿从主线程发出同步请求。
sendSynchronousRequest
sendAsynchronousRequest
解析响应时,resString将包含原始JSON。我不知道jsonData在构建时要引用什么变量jsonString,但这看起来并不正确。
resString
jsonData
jsonString
如果要解析响应,则为:
NSError *parseError; NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
顺便说一句,以上方法假设您在响应中返回JSON字典,就像我在示例中所做的那样,而不是原始JSON所做的。