我正在尝试使用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(又名profileImage)和immagineUni(又名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,所以它似乎发送了一些东西。
答案 0 :(得分:1)
您的PHP专栏说:
echo $datiutente;
相反,您希望返回JSON,可以由客户端轻松解析。因此,您应该指定响应将是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中(因为它会将响应的大小增加几个数量级,从而减慢它的速度)。我可能更愿意在响应中包含图像的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
请求(例如使用{ {1}}构建看起来像NSJSONSerialization dataWithJSONObject
)的请求。然后在服务器端解析它。
请注意,不推荐使用此MySQL接口。正如文档所说:
此扩展在PHP 5.5.0中已弃用,并已在PHP 7.0.0中删除。相反,应使用MySQLi或PDO_MySQL扩展名。有关详细信息,另请参阅MySQL: choosing an API指南和related FAQ。