11

EDIT: I have edited the OP with all the suggestions I got from people, so this is the latest (and its still not working).


I have the following code, which is supposed to POST some data to a .php file I have (and then to a database but that is beyond the scope of this question).

To my method, I pass an array that contains some strings.

-(void)JSON:(NSArray *)arrayData {

    //parse out the json data
    NSError *error;

    //convert array object to data
    NSData* JSONData = [NSJSONSerialization dataWithJSONObject:arrayData 
                                                       options:NSJSONWritingPrettyPrinted 
                                                         error:&error];

    NSString *JSONString = [[NSString alloc] initWithData:JSONData 
                                                 encoding:NSUTF8StringEncoding];


    NSString *URLString = [NSString stringWithFormat:@"websitename"];

    NSURL *URL = [NSURL URLWithString:URLString];

    NSLog(@"URL: %@", URL);


    NSMutableURLRequest *URLRequest = [NSMutableURLRequest requestWithURL:URL 
                                                              cachePolicy:NSURLRequestUseProtocolCachePolicy 
                                                          timeoutInterval:60.0];

    NSData *requestData = [NSData dataWithBytes:[JSONString UTF8String] length:[JSONString length]];

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

    [URLRequest setHTTPMethod:@"POST"];
    NSLog(@"method: %@", URLRequest.HTTPMethod);
    [URLRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [URLRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [URLRequest setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [URLRequest setHTTPBody: requestData];

    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:URLRequest delegate:self];

    if (connection) {
        NSMutableData *receivedData = [[NSMutableData data] retain];
        NSString *receivedDataString = [[NSString alloc] initWithData:receivedData 
                                                             encoding:NSUTF8StringEncoding];
        NSLog(@"receivedData: %@", receivedDataString);
    }

    //potential response
    NSData *response = [NSURLConnection sendSynchronousRequest:URLRequest returningResponse:nil error:nil];

    //convert response so that it can be LOG'd
    NSString *returnString = [[NSString alloc] initWithData:response encoding:NSASCIIStringEncoding];

    NSLog(@"RETURN STRING: %@", returnString);
}

NOTE: I have the actual URL of my website in the code, so that anyone can test if they want to.


Then there is the .php side of things, where all I am trying to do is look for any input at all (but I am getting nothing).

<html>
        <body>
        <?php

        echo "Connection from iOS app to MySQL database<BR>";

        echo '<pre>'.print_r($GLOBALS,true).'</pre>';



        ?>
        </body>
</html>

All I am really trying to do right now is confirm the data is getting through, by echoing it to the page, and then reading the page from my app (so far the data hasn't been showing up).


The output of the .php:

 <html>
        <body>
        Connection from iOS app to MySQL database<BR>'Array
(
)
'<pre>Array
(
    [_GET] => Array
        (
        )

    [_POST] => Array
        (
        )

    [_COOKIE] => Array
        (
        )

    [_FILES] => Array
        (
        )

    [GLOBALS] => Array
 *RECURSION*
)
</pre>        </body>
</html>
BloonsTowerDefence
  • 1,184
  • 2
  • 18
  • 43
  • 2
    If you're `POST`ing the data, it won't show up in `$_GET`, it'll be in `$_POST`. – WWW Aug 09 '12 at 20:41
  • As others have pointed out, you want to access $_POST, but you may also want to use `print_r($_POST)` rather than the join/echo – ernie Aug 09 '12 at 20:46
  • what happens if you print_r($_POST)? – Vladimir Hraban Aug 09 '12 at 20:46
  • when I `print_r($_POST)`, nothing happens. And in my table (in the database), the field is also blank instead of being NULL. – BloonsTowerDefence Aug 09 '12 at 20:50
  • For testing, I'd drop the if empty test and `var_dump($_POST)` or `print_r($_POST)` so you will get _something_ back. – TecBrat Aug 09 '12 at 20:54
  • $_GET and $_POST exist to get data from a html
    . $_GET gets the data from the url after the question-mark and $_POST from a `application/x-www-form-urlencoded`body. You are setting it to `application/json` and therefore you have to get the body of the post-request and process that. $_GET and $_POST will not be populated.
    – some Aug 13 '12 at 14:37
  • Silly question, but I see you're logging your requestData variable. It does actually contain what you expect it to, right? (what *does* it contain?) – WWW Aug 16 '12 at 13:40

3 Answers3

10

You are POSTing JSON instead of application/x-www-form-urlencoded.

The PHP $_POST is only filled for application/x-www-form-urlencoded-requests. If you are sending json directly like that, then you should do:

<?php
$posted_json = json_decode(file_get_contents("php://input"));
print_r($posted_json);

Note that if the json is invalid this won't work. You can always debug the request body with:

<?php
echo file_get_contents("php://input");

Here's general explanation of $_POST and $_GET http://www.php.net/manual/en/language.variables.external.php:

They are meant to be used with normal html forms, though you can easily emulate such requests with appropriate encoding and content type header. But they won't work with JSON as that's not how normal html forms work.

Esailija
  • 138,174
  • 23
  • 272
  • 326
  • Like you said $_GET and $_POST are only supposed [to be used for posting variables from
    ](http://www.php.net/manual/en/language.variables.external.php). If the data isn't from a form (or in a different encoding) one has to get the body and process that.
    – some Aug 13 '12 at 14:28
  • Didn't know about php://input, yet; just stdin/stdout variation... thank for teaching me! ;-) – SDwarfs Aug 17 '12 at 22:30
8

I have no idea about Objective-C, bu assuming you are trying to send following JSON data (i.e. JSONString is the following):

{
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": "10021"
    },
    "phoneNumber": [
        {
            "type": "home",
            "number": "212 555-1234"
        },
        {
            "type": "fax",
            "number": "646 555-4567"
        }
    ]
}

then your request should be something like this:

POST /yourwebsite.php HTTP/1.1
Host: cs.dal.ca
User-Agent: USER-AGENT
Accept: text/html,application/json,*/*
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 624

data=%7B%0A++++%22firstName%22%3A+%22John%22%2C%0A++++%22lastName%22%3A+%22Smith%22%2C%0A++++%22age%22%3A+25%2C%0A++++%22address%22%3A+%7B%0A++++++++%22streetAddress%22%3A+%2221+2nd+Street%22%2C%0A++++++++%22city%22%3A+%22New+York%22%2C%0A++++++++%22state%22%3A+%22NY%22%2C%0A++++++++%22postalCode%22%3A+%2210021%22%0A++++%7D%2C%0A++++%22phoneNumber%22%3A+%5B%0A++++++++%7B%0A++++++++++++%22type%22%3A+%22home%22%2C%0A++++++++++++%22number%22%3A+%22212+555-1234%22%0A++++++++%7D%2C%0A++++++++%7B%0A++++++++++++%22type%22%3A+%22fax%22%2C%0A++++++++++++%22number%22%3A+%22646+555-4567%22%0A++++++++%7D%0A++++%5D%0A%7D%0A%0A%0A

note that Content-Type: application/json is NOT a way for posting data, as you have used, and note that data has been urlencoded, it should not be hard to this, I found this link about doing so in Objective-C: URLEncoding a string with Objective-C

Sending above request, I got this:

php code:

<?php
$raw_json_data = $_POST['data'];
$json_data = json_decode($raw_json_data);
print_r($json_data);

result:

stdClass Object
(
    [firstName] => John
    [lastName] => Smith
    [age] => 25
    [address] => stdClass Object
        (
            [streetAddress] => 21 2nd Street
            [city] => New York
            [state] => NY
            [postalCode] => 10021
        )

    [phoneNumber] => Array
        (
            [0] => stdClass Object
                (
                    [type] => home
                    [number] => 212 555-1234
                )

            [1] => stdClass Object
                (
                    [type] => fax
                    [number] => 646 555-4567
                )

        )

)

which is what you want!

NOTE: I should mention that your script at http://yourwebsite.php does not work properly, I could not even submit a normal form to it! There might be a problem like server misconfiguration or something similar, but using Apache 2.2 and PHP 5.4.4 and codes mentioned above, I got it working!

Community
  • 1
  • 1
PLuS
  • 642
  • 5
  • 12
  • thanks, I ended up figuring it out using what you said + some other resources. – BloonsTowerDefence Aug 16 '12 at 17:48
  • Note that you *can* post `application/json`, and there is nothing wrong with that.. There is no need to hack this to get `$_POST` working when you can just read the request body directly. – Esailija Aug 18 '12 at 08:22
2

You have accept http header field set to application/json. so is the content type..you might want to check if the data passed between the browser and server are valid json. You can also change it to text/plain and check..

raidenace
  • 12,789
  • 1
  • 32
  • 35
  • I have a `NSLog` statement that outputs the data for me, it looks like this: `[ "5", "NO", "LOW", "FAIR", "", "" ]` . Which I think is valid JSON ? – BloonsTowerDefence Aug 09 '12 at 21:29