【问题标题】:Send array to PHP from objective C using POST/GET使用 POST/GET 从目标 C 向 PHP 发送数组
【发布时间】:2014-04-28 05:00:43
【问题描述】:

我正在尝试将一组字符串从 Objective C 发送到 PHP。我最初使用的是 GET,但我知道 GET 不适合发送大量数据。我的数组将有大约 300 个条目。因此,我正在使用 POST。 After going through this page我想出了以下代码

 NSDictionary *userconnections = [user objectForKey:@"connections"];
             NSMutableArray *connectionsID = [[NSMutableArray alloc] init];
             for (id foo in [userconnections objectForKey:@"values"]) {

                 [connectionsID addObject:[foo objectForKey:@"id"]];
                 //[User sharedUser].connections = connectionsID;

             }

             NSError *error;
             NSData *jsonData = [NSJSONSerialization dataWithJSONObject:connectionsID options:NSJSONWritingPrettyPrinted error:&error];

             NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
             [User sharedUser].connections = jsonData;
             [User sharedUser].connectionsID = jsonString;

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://localhost:8888/API.php"]];

    [request setHTTPMethod:@"POST"];

[request setValue:[[User sharedUser]connectionsID] forKey:@"songs"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[[[User sharedUser] connections] length]] forHTTPHeaderField:@"Content-Length"];
 [request setHTTPBody: [[User sharedUser] connections]];

NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSLog(@"Return DATA contains: %@", [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil]);

在我的 PHP 中,我收到如下:

    <?php 

header("Content-Type: application/json");
$headers = array_change_key_case(getallheaders());


include "dbconnect.php";

$songs = json_decode(stripcslashes($_GET["songs"]));
echo json_encode($songs);

但是,我无法在 php 中接收数据。任何帮助或指针将不胜感激

编辑:我改回使用 GET,因为 POST 对我没有帮助。感谢您提供的任何帮助

【问题讨论】:

  • 如果你只看正文,它是形式编码的吗?我认为它需要出现在 $_POST... 否则我认为你必须从原始请求中得到它。
  • 你也应该通过 Charles 代理查看请求。

标签: php mysql objective-c arrays json


【解决方案1】:

几个问题:

  1. 您正在构建application/json 请求中的Content-Type,但您的PHP 正在尝试读取$_POST['songs']。你应该做一个或另一个(要么发送原始 JSON 请求,要么发送 application/x-www-form-urlencoded 请求)。假设您只想创建简单的 JSON 请求(就像您的 Objective-C 代码现在主要做的那样)。在这种情况下,您的 PHP 应该像这样读取原始 JSON:

    <?php
    
    // be a good citizen and report that we're going to return JSON response
    
    header("Content-Type: application/json");
    
    // get the lower case rendition of the headers of the request
    
    $headers = array_change_key_case(getallheaders());
    
    // extract the content-type
    
    if (isset($headers["content-type"]))
        $content_type = $headers["content-type"];
    else
        $content_type = "";
    
    // if JSON, read and parse it
    
    if ($content_type == "application/json")
    {
        // read it
    
        $handle = fopen("php://input", "rb");
        $raw_post_data = '';
        while (!feof($handle)) {
            $raw_post_data .= fread($handle, 8192);
        }
        fclose($handle);
    
        // parse it
    
        $songs = json_decode($raw_post_data, true);
    }
    else
    {
        // report non-JSON request and exit
    }
    
    // now use that `$songs` variable here
    
    // if you wanted to report it back to the client for debugging purposes, you should
    // recreate JSON response:
    
    $raw_result = json_encode($songs);
    
    // finally, write the body of the response
    
    echo $raw_result;
    
    ?>
    
  2. 我建议在您的 Objective-C 代码中删除带有 @"songs" 键的 setValue:forKey:。假设您只想像我上面概述的那样发送原始 JSON 请求,那么这不是必需的(坦率地说,无论如何发送 application/x-www-form-urlencoded 请求是错误的方式)。

如果您打算制作有效负载以便可以使用$_POST['songs'],那么执行此操作的Objective-C 代码不使用setValue:forKey:,而是包含使用Content-Type 或@987654332 手动构建请求@,而songs=... 将在请求的正文中(并且您必须使用CFURLCreateStringByAddingPercentEscapes 来编码您在此请求中传递的 JSON 字符串)。不过,这有点学术性,因为我认为您应该坚持application/json 请求。

【讨论】:

  • 您好,感谢您的回复。我的 php.ini 中确实有 json 标头。我已经更新了我的 php 代码,应该可以让您更好地了解我的文件的外观。
  • @ShrutiKapoor 太好了。但 JSON 标头的缺失或存在都不是问题。这是您的 Objective-C 代码正在创建一个 JSON 请求(不是 application/x-www-form-urlencoded 请求),但您的 PHP 使用的是 $_POST,它仅用于 application/x-www-form-urlencoded 和类似编码的请求。由于您只是在请求正文中发送原始 JSON,因此您应该更改 PHP 以读取请求正文的原始数据,然后它可以使用 json_decode 进行转换。
【解决方案2】:

我推荐广泛使用的 AFNetworking 库 (https://github.com/AFNetworking/AFNetworking)。一个简单的带参数的 POST 请求可以这样构造:

NSDictionary *p = @{@"foo": @"bar"};
[[AFHTTPRequestOperationManager manager] POST:@"http://example.com/resources.json" parameters:p success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error); 
}];

【讨论】:

    【解决方案3】:

    AFNetworking 2.0 有带有 POST 方法的 AFHTTPSessionManager 类

    (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id<AFMultipartFormData>))block success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure;
    

    将connectionsID传递给参数

    NSDictionary *params = @{@"connectionsID": [connectionsID copy]};
    

    可以在PHP中访问

    $_POST['connectionsID']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-25
      • 2011-04-22
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多