将数组从 PHP 发送到 NSURLSession
Sending array from PHP to NSURLSession
我目前正在尝试使用 NSURLSession 将一个包含文本和图像的数组从我的 PHP 文件发送到我的 iOS 应用程序。最初,我测试了一个纯文本数组,我在发送到我的应用程序之前将其转换为 JSON 格式:一切正常,但现在我需要发送一个包含文本和图像的数组,所以我'我做过这样的事情:
这是代码:
- PHP(对非英文注释和变量名表示抱歉)
<?php
// Connessione al server mediante le credenziali.
$con = mysql_connect("localhost", "mobdev2015", "Pistacchio1");
if(!$con){
die("Server non trovato" . mysql_error());
}
// Seleziono il database.
$db = mysql_select_db("gandalf", $con);
if(!$db){
die("Database non trovato" . mysql_error());
}
// Mi metto in ascolto per ricevere l'user dall'utente.
$user = file_get_contents('php://input');
// Prelevo i dati dello studente, controllando se tutto va bene.
$sql = "SELECT * FROM Studente WHERE nomeUtente = '$user' ";
if(!mysql_query($sql, $con))
die ("Errore nella ricerca dello studente" . mysql_error());
// Prelevo i valori delle colonne del result set.
$result = mysql_query($sql, $con);
$resultSet = mysql_fetch_row($result);
// Prelevo il percorso dell'immagine dell'università dello studente, dato l'id nel risultato,
// Facendo sempre i vari controlli del caso.
$queryImmagineUni = "SELECT immagine FROM Universita WHERE id = '$result[5]'";
if(!mysql_query($queryImmagineUni, $con))
die ("Errore nella ricerca dell'università" . mysql_error());
$result = mysql_query($queryImmagineUni, $con);
$pathImmagine = mysql_result($result, 0);
//Inserisco tutti i dati nell'array, ottenendo le immagini mediante file_get_contents.
$datiutente = array(
"nome" => $resultSet[1],
"cognome" => $resultSet[2],
"email" => $resultSet[4],
"nomeUtente" => $resultset[6],
"immagineProfilo" => file_get_contents($resultSet[3]),
"immagineUni" => file_get_contents($pathImmagine)
);
//Mando in output il risultato e chiudo la connessione.
echo $datiutente;
mysql_close($con);
?>
immagineProfilo 和(aka profileImage)和 immagineUni(aka universityImage)是从数据库中检索的两个路径(如“./folder/image.jpg”)。
iOS:
// Setting up the url of the request (we will call a php file).
NSURL *url = [[NSURL alloc]initWithString:@"http://inserturlhere.com/userdata.php"];
// Creating the NSMutableRequest object, which will contain the HTML headers and the nickname needed to retrieve data.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
// Converting the NSString into NSData to append at MutableURLRequest.
NSData *postData = [user dataUsingEncoding:NSASCIIStringEncoding];
//Setting the method to post
[request setHTTPMethod:@"POST"];
// Setting the body of the post to the reqeust
[request setHTTPBody:postData];
//
/*
NSURLSession needs a NSURLSessionConfiguration to run, so we instiate a NSURLSessionConfiguration object saying
we want to use a default Session, then we create a session with that configuration
*/
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
// Starting a dataTask with the request previously defined. The completion handler will be used to manage the response
// from the server, stored in a NSURLResponse object.
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSArray *datiUtente = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%@", datiUtente);
}]resume];
此解决方案中的问题是我无法打印应包含 PHP 数组内容的数组内容,但使用调试器我可以看到 data 不是 NULL,所以好像发送了一些东西。
你的 PHP 行说:
echo $datiutente;
相反,你想要returnJSON,这样可以很容易被客户端解析。因此,您应该指定响应将是 JSON(并在 echo
之前执行此操作):
header('Content-type: application/json');
然后,响应数据的回显将是:
echo json_encode($datiutente);
然后在客户端解析它,你需要:
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
}
if (!data) {
return;
}
NSError *parseError;
NSArray *datiUtente = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (datiUtente) {
NSLog(@"responseObject = %@", datiUtente);
} else {
NSLog(@"parseError = %@", parseError);
NSLog(@"responseString = %@", [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding]);
}
}] resume];
顺便说一下,当您构建 JSON 响应时,您不能包含二进制数据(即图像负载)。因此,如果您要在 JSON 响应中包含图像,请确保 base64_encode
它们(然后在客户端对其进行解码):
$datiutente = array(
"nome" => $resultSet[1],
"cognome" => $resultSet[2],
"email" => $resultSet[4],
"nomeUtente" => $resultset[6],
"immagineProfilo" => base64_encode(file_get_contents($resultSet[3])),
"immagineUni" => base64_encode(file_get_contents($pathImmagine)),
"success" => true
);
就个人而言,我不倾向于将图像负载包含在 JSON ar all 中(因为它会使响应的大小增加几个数量级,从而减慢速度)。我可能更愿意在响应中只包含图像的 URL ,并让客户端在需要时请求图像本身。您可以通过这种设计使应用程序更具响应性。但这取决于你。
注意,除了上面的改动,我还加了一段success
代码。这可能很有用,以便客户端可以快速确定响应是否成功。
显然,您也想 JSON 编码失败。例如,如果 MySQL 连接失败,您应该在 JSON 响应中指出(并包括 MySQL 提供的适当信息):
if (!$con) {
$response = array(
"success" => false,
"message" => "Server non trovato",
"sqlerror" => mysql_error(),
"sqlerrno" => mysql_errno()
);
echo json_encode($response);
exit();
}
一旦你开始工作,其他一些观察结果:
不要只获取发布的数据并在查询中使用它。这会使您暴露于 SQL 注入攻击。请记住 mysql_real_escape_string
在查询中使用该输入之前。
我可能会将客户端代码创建的请求更改为 application/x-www-form-urlencoded
请求(例如 user=...
)或 application/json
请求(例如使用 NSJSONSerialization dataWithJSONObject
构建看起来像 {"user": "..."}
的请求)。然后在服务器端解析。
请注意,此 MySQL 接口已弃用。正如文档所说:
This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
我目前正在尝试使用 NSURLSession 将一个包含文本和图像的数组从我的 PHP 文件发送到我的 iOS 应用程序。最初,我测试了一个纯文本数组,我在发送到我的应用程序之前将其转换为 JSON 格式:一切正常,但现在我需要发送一个包含文本和图像的数组,所以我'我做过这样的事情:
这是代码:
- PHP(对非英文注释和变量名表示抱歉)
<?php
// Connessione al server mediante le credenziali.
$con = mysql_connect("localhost", "mobdev2015", "Pistacchio1");
if(!$con){
die("Server non trovato" . mysql_error());
}
// Seleziono il database.
$db = mysql_select_db("gandalf", $con);
if(!$db){
die("Database non trovato" . mysql_error());
}
// Mi metto in ascolto per ricevere l'user dall'utente.
$user = file_get_contents('php://input');
// Prelevo i dati dello studente, controllando se tutto va bene.
$sql = "SELECT * FROM Studente WHERE nomeUtente = '$user' ";
if(!mysql_query($sql, $con))
die ("Errore nella ricerca dello studente" . mysql_error());
// Prelevo i valori delle colonne del result set.
$result = mysql_query($sql, $con);
$resultSet = mysql_fetch_row($result);
// Prelevo il percorso dell'immagine dell'università dello studente, dato l'id nel risultato,
// Facendo sempre i vari controlli del caso.
$queryImmagineUni = "SELECT immagine FROM Universita WHERE id = '$result[5]'";
if(!mysql_query($queryImmagineUni, $con))
die ("Errore nella ricerca dell'università" . mysql_error());
$result = mysql_query($queryImmagineUni, $con);
$pathImmagine = mysql_result($result, 0);
//Inserisco tutti i dati nell'array, ottenendo le immagini mediante file_get_contents.
$datiutente = array(
"nome" => $resultSet[1],
"cognome" => $resultSet[2],
"email" => $resultSet[4],
"nomeUtente" => $resultset[6],
"immagineProfilo" => file_get_contents($resultSet[3]),
"immagineUni" => file_get_contents($pathImmagine)
);
//Mando in output il risultato e chiudo la connessione.
echo $datiutente;
mysql_close($con);
?>
immagineProfilo 和(aka profileImage)和 immagineUni(aka universityImage)是从数据库中检索的两个路径(如“./folder/image.jpg”)。
iOS:
// Setting up the url of the request (we will call a php file). NSURL *url = [[NSURL alloc]initWithString:@"http://inserturlhere.com/userdata.php"]; // Creating the NSMutableRequest object, which will contain the HTML headers and the nickname needed to retrieve data. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url]; // Converting the NSString into NSData to append at MutableURLRequest. NSData *postData = [user dataUsingEncoding:NSASCIIStringEncoding]; //Setting the method to post [request setHTTPMethod:@"POST"]; // Setting the body of the post to the reqeust [request setHTTPBody:postData]; // /* NSURLSession needs a NSURLSessionConfiguration to run, so we instiate a NSURLSessionConfiguration object saying we want to use a default Session, then we create a session with that configuration */ NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration]; // Starting a dataTask with the request previously defined. The completion handler will be used to manage the response // from the server, stored in a NSURLResponse object. [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSArray *datiUtente = [NSKeyedUnarchiver unarchiveObjectWithData:data]; NSLog(@"%@", datiUtente); }]resume];
此解决方案中的问题是我无法打印应包含 PHP 数组内容的数组内容,但使用调试器我可以看到 data 不是 NULL,所以好像发送了一些东西。
你的 PHP 行说:
echo $datiutente;
相反,你想要returnJSON,这样可以很容易被客户端解析。因此,您应该指定响应将是 JSON(并在 echo
之前执行此操作):
header('Content-type: application/json');
然后,响应数据的回显将是:
echo json_encode($datiutente);
然后在客户端解析它,你需要:
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
}
if (!data) {
return;
}
NSError *parseError;
NSArray *datiUtente = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (datiUtente) {
NSLog(@"responseObject = %@", datiUtente);
} else {
NSLog(@"parseError = %@", parseError);
NSLog(@"responseString = %@", [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding]);
}
}] resume];
顺便说一下,当您构建 JSON 响应时,您不能包含二进制数据(即图像负载)。因此,如果您要在 JSON 响应中包含图像,请确保 base64_encode
它们(然后在客户端对其进行解码):
$datiutente = array(
"nome" => $resultSet[1],
"cognome" => $resultSet[2],
"email" => $resultSet[4],
"nomeUtente" => $resultset[6],
"immagineProfilo" => base64_encode(file_get_contents($resultSet[3])),
"immagineUni" => base64_encode(file_get_contents($pathImmagine)),
"success" => true
);
就个人而言,我不倾向于将图像负载包含在 JSON ar all 中(因为它会使响应的大小增加几个数量级,从而减慢速度)。我可能更愿意在响应中只包含图像的 URL ,并让客户端在需要时请求图像本身。您可以通过这种设计使应用程序更具响应性。但这取决于你。
注意,除了上面的改动,我还加了一段success
代码。这可能很有用,以便客户端可以快速确定响应是否成功。
显然,您也想 JSON 编码失败。例如,如果 MySQL 连接失败,您应该在 JSON 响应中指出(并包括 MySQL 提供的适当信息):
if (!$con) {
$response = array(
"success" => false,
"message" => "Server non trovato",
"sqlerror" => mysql_error(),
"sqlerrno" => mysql_errno()
);
echo json_encode($response);
exit();
}
一旦你开始工作,其他一些观察结果:
不要只获取发布的数据并在查询中使用它。这会使您暴露于 SQL 注入攻击。请记住
mysql_real_escape_string
在查询中使用该输入之前。我可能会将客户端代码创建的请求更改为
application/x-www-form-urlencoded
请求(例如user=...
)或application/json
请求(例如使用NSJSONSerialization dataWithJSONObject
构建看起来像{"user": "..."}
的请求)。然后在服务器端解析。请注意,此 MySQL 接口已弃用。正如文档所说:
This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information.