【问题标题】:Objective-C->JSON->PHP ArrayObjective-C->JSON->PHP 数组
【发布时间】:2013-06-04 05:44:06
【问题描述】:

过去几天我一直在为此苦苦挣扎;我正在尝试将数组发布到 PHP。我可以成功发送它,但它没有使用后变量(我正在尝试使用变量键“json”...使用此代码,我在 php 中收到数组:

目标-C

NSError *error;
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects: @"one", @"two", @"three", nil] forKeys: [NSArray arrayWithObjects: @"a", @"b", @"c", nil]];
NSArray *jsonArray = [NSArray arrayWithObject:jsonDictionary];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonArray options:NSUTF8StringEncoding error:&error];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"somewebservicelocation/arrayTest.php?json="]];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:jsonData];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *response = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"response: %@",response);

PHP

$handle = fopen('php://input','r');
    $array = fgets($handle);
    echo $array;
    if(isset($array))
    {
        echo "success";
    }
    else
    {
        echo "failure";
    }

如果我使用这个 PHP,使用 _POST,我不会得到爱:

$rawJsonData = $_POST['json'];
$array = json_decode(stripslashes($rawJsonData),true);
echo $array;
if(isset($array))
{
    echo "success";
}
else
{
    echo "failure";
}

...我已经用了好几天了——在 Stack Overflow 上,我知道我需要在请求的正文中包含变量和数据,但我就是无法让它工作。我究竟做错了什么?你如何以不同的方式解决这个问题?让我免于这种头痛......

【问题讨论】:

  • 我不确定您为什么需要 _POST 演绎版,但我在答案的后半部分提供了一个示例。
  • a) 有时我会将其他变量与数组一起发送(是的,我知道我可以将数组操作得更大,但我认为这不是最佳做法)。 b)因为我确信这是可能的......
  • 正如我在下面所说的,我绝对更喜欢构建我 json 编码的 NSDictionary 来捕获我想要传递的所有这些项目。 _POST 结构感觉就像是一种网络浏览器表单技术,它不适合 JSON 擅长的这种计算机到计算机的通信(尽管这样做可能会被扭曲)。这两种技术都有效,但我倾向于整合 JSON 方法,而不是 _POST 和 JSON 方法的混合。但使用适合您的。

标签: php objective-c arrays http-post


【解决方案1】:

在 PHP 方面,我使用了与您的第一个示例类似的内容:

<?php

$handle = fopen("php://input", "rb");
$http_raw_post_data = '';
while (!feof($handle)) {
    $http_raw_post_data .= fread($handle, 8192);
}
fclose($handle);

// do what you want with it
//
// For diagnostic purposes, I'm just going to decode, make sure I got an array, 
// and respond with JSON that includes status, code, and the original request

$post_data = json_decode($http_raw_post_data,true);

if (is_array($post_data))
    $response = array("status" => "ok", "code" => 0, "original request" => $post_data);
else
    $response = array("status" => "error", "code" => -1, "original_request" => $post_data);

$processed = json_encode($response);
echo $processed;

?>

然后在 iOS 端,我使用:

// create the dictionary (or array)

NSDictionary *dictionary = @{@"a": @"One", @"b": @"Two", @"c": @"Three"};
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
if (error)
    NSLog(@"%s: JSON encode error: %@", __FUNCTION__, error);

// create the request

NSURL *url = [NSURL URLWithString:@"your.url.here"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:data];

// issue the request

NSURLResponse *response = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error)
    NSLog(@"%s: NSURLConnection error: %@", __FUNCTION__, error);

// examine the response

NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"responseString: %@",responseString);

我刚刚测试了这个往返,它工作正常。


如果您确定使用_POST技术,对我有用的是将数据设置为json=%@,例如:

NSDictionary *dictionary = ...
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (error)
    NSLog(@"%s: JSON encode error: %@", __FUNCTION__, error);

NSURL *url = [NSURL URLWithString:@"your.url.here"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPMethod:@"POST"];
NSString *params = [NSString stringWithFormat:@"json=%@",
                    [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *paramsData = [params dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:@"8bit" forHTTPHeaderField:@"Content-Transfer-Encoding"];
[request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:paramsData];

// now send the request, like before

解析它的 PHP 和你的很像:

$http_raw_post_data = $_POST['json'];

$post_data = json_decode(stripslashes($http_raw_post_data),true);

if (is_array($post_data))
    $response = array("status" => "ok", "code" => 0, "original request" => $post_data);
else
    $response = array("status" => "error", "code" => -1, "original_request" => $post_data);

$processed = json_encode($response);
echo $processed;

【讨论】:

  • 谢谢,但是如果我也想发送多个数组和字符串等呢?
  • @Ryan 我会使用第一种技术(避免在退出时添加百分比转义并在进入时去除斜杠),但将多个数组和字符串添加到我的 NSMutableDictionary用 JSON 编码。您可以将字典和数组嵌套到您心中的内容(查看我的示例响应,这是一个具有三个键的字典,其中第三个的值是另一个字典(在本示例中,只是我上传的那个的另一个副本))。使用 HTML POST 不是解决此问题的方法。构建您的 JSON 以处理您要发送的所有不同值等。
  • 编辑:啊太棒了。太感谢你了! edit2:我希望能够添加外部变量的原因是为了安全或区分来源(在连接/下载数据之前使用密钥)。
  • 嗨 Rob,我刚刚拿走了你的 iOS 代码和 php 代码,并将字典替换为数组,但它在 NSJSONSerialization 行之后立即崩溃。没有错误日志。只是糟糕的 EXC 访问 :(
  • @marciokoko 如果它在dataWithJSONObject 崩溃,请检查您传递给它的数组是否不是nil。上面的代码来自一个工作示例,所以我看不出它会以任何其他方式在NSJSONSerialization 上崩溃。数组只是字典和/或标准 Cocoa 对象的数组吗?或者你在那个数组中有你自己的对象吗? NSLog 调用之前数组的内容dataWithJSONObject...
【解决方案2】:

最好使用下面的PHP函数 回复将在stdobject

parse_str(file_get_contents("php://input"), $data);

$d = json_decode(json_encode($data));

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多