如何使用objective-cpostJSON数据到PHP数据库?
How to post JSON data to PHP database using objective-c?
我在将数据发送到我的在线数据库时遇到问题。当我检查数据库时,似乎什么都没有 post。我对收到的响应执行了 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,这就是为什么它没有 posting 或其他一些问题?
感谢您的帮助。
一些观察:
您应该使用 msqli
接口,而不是已弃用的 mysql
接口。
你永远不应该接受输入,而只是在 SQL 语句中使用它。使用 mysqli_real_escape_string
或绑定值(如下所示)。这对于确保您不易受到 SQL 注入攻击至关重要。如果插入的值恰好包含保留字符,它还可以保护您免受可能出现的无辜错误。
与其尝试只 json_encode
mysqli_query
结果,不如构建一个更有意义的关联数组。例如,您可以检查 mysqli
调用的结果,如果成功则 return 一次 JSON ,如果失败则再检查一次。我可能会建议将失败再现 return 错误消息。
您应该在网络浏览器中测试您的 PHP,或者使用 Charles 之类的设备从设备上测试它。在您对客户端代码做得太过火之前,请确保您已返回预期的 JSON。最重要的是,看看您是否可以测试彼此隔离的客户端代码和服务器代码(或者首先保持尽可能简单)。
我不熟悉这个 $_SERVER['HTTP_JSON'];
结构。如果这对你有用,那很好,但它在我的服务器上不起作用。我曾经做过 fopen
个 php://input
,如下图所示。
例如,这是一个不同的 database/table,但它可能说明了 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
,测试以确保在我尝试使用变量之前设置了变量,等等),但你可能明白了。
在客户端,还有一些小观察:
最严重的问题是sendSynchronousRequest
的使用。使用 sendAsynchronousRequest
代替(或无数其他异步技术中的任何一种)。永远不要从主线程发出同步请求。
解析响应时,resString
将包含原始 JSON。我不知道你在构建 jsonString
时引用的 jsonData
变量是什么,但这看起来不对。
如果要解析响应,则为:
NSError *parseError;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
顺便说一下,上面假设你在你的回复中 return 一个 JSON 字典,就像我在我的例子中所做的那样,而不是你原来的 JSON 所做的。
我在将数据发送到我的在线数据库时遇到问题。当我检查数据库时,似乎什么都没有 post。我对收到的响应执行了 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,这就是为什么它没有 posting 或其他一些问题?
感谢您的帮助。
一些观察:
您应该使用
msqli
接口,而不是已弃用的mysql
接口。你永远不应该接受输入,而只是在 SQL 语句中使用它。使用
mysqli_real_escape_string
或绑定值(如下所示)。这对于确保您不易受到 SQL 注入攻击至关重要。如果插入的值恰好包含保留字符,它还可以保护您免受可能出现的无辜错误。与其尝试只
json_encode
mysqli_query
结果,不如构建一个更有意义的关联数组。例如,您可以检查mysqli
调用的结果,如果成功则 return 一次 JSON ,如果失败则再检查一次。我可能会建议将失败再现 return 错误消息。您应该在网络浏览器中测试您的 PHP,或者使用 Charles 之类的设备从设备上测试它。在您对客户端代码做得太过火之前,请确保您已返回预期的 JSON。最重要的是,看看您是否可以测试彼此隔离的客户端代码和服务器代码(或者首先保持尽可能简单)。
我不熟悉这个
$_SERVER['HTTP_JSON'];
结构。如果这对你有用,那很好,但它在我的服务器上不起作用。我曾经做过fopen
个php://input
,如下图所示。
例如,这是一个不同的 database/table,但它可能说明了 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
,测试以确保在我尝试使用变量之前设置了变量,等等),但你可能明白了。
在客户端,还有一些小观察:
最严重的问题是
sendSynchronousRequest
的使用。使用sendAsynchronousRequest
代替(或无数其他异步技术中的任何一种)。永远不要从主线程发出同步请求。解析响应时,
resString
将包含原始 JSON。我不知道你在构建jsonString
时引用的jsonData
变量是什么,但这看起来不对。如果要解析响应,则为:
NSError *parseError; NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
顺便说一下,上面假设你在你的回复中 return 一个 JSON 字典,就像我在我的例子中所做的那样,而不是你原来的 JSON 所做的。