views:

880

answers:

6

Hi,

I'm fairly new to objective-c, and am looking to pass a number of key-value pairs to a PHP script using POST. I'm using the following code but the data just doesn't seem to be getting posted through. I tried sending stuff through using NSData as well, but neither seem to be working.

 NSDictionary* data = [NSDictionary dictionaryWithObjectsAndKeys:
    @"bob", @"sender",
    @"aaron", @"rcpt",
    @"hi there", @"message",
    nil];

 NSURL *url = [NSURL URLWithString:@"http://myserver.com/script.php"];
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

 [request setHTTPMethod:@"POST"];
 [request setHTTPBody:[NSData dataWithBytes:data length:[data count]]];

  NSURLResponse *response;
  NSError *err;
  NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
  NSLog(@"responseData: %@", content);

This is getting sent to this simple script to perform a db insert:

<?php $sender = $_POST['sender'];
      $rcpt = $_POST['rcpt'];
      $message = $_POST['message'];

      //script variables
      include ("vars.php");

      $con = mysql_connect($host, $user, $pass);
      if (!$con)
      {
        die('Could not connect: ' . mysql_error());
      }

      mysql_select_db("mydb", $con);

      mysql_query("INSERT INTO php_test (SENDER, RCPT, MESSAGE) 
      VALUES ($sender, $rcpt, $message)");

      echo "complete"
?>

Any ideas?

A: 

Edit: Has been fixed in OP.


This may not be your sole problem (I don't know my way around objective-c), but here goes:

mysql_query("INSERT INTO php_test (SENDER, RCPT, MESSAGE) 
VALUES ($sender, $rcpt, $message)");

You're not quote-enclosing your strings - MySQL is bound to have a hissy fit over that.

mysql_query("INSERT INTO php_test (SENDER, RCPT, MESSAGE) 
VALUES ('$sender', '$rcpt', '$message')");

Beyond that, generally, even if your script is not reachable from the outside, you shouldn't trust user input and either use mysql_real_escape_string() to escape your values before you insert them into the SQL statement to prevent SQL injection, or use prepared statements (preferred) - otherwise single quotes in your legitimate data will break the SQL statement's syntax.

Entirely ungraceful example for reference:

mysql_query("INSERT INTO php_test (SENDER, RCPT, MESSAGE) 
VALUES ('" . mysql_real_escape_string($sender) ."',"
." '" . mysql_real_escape_string($rcpt) ."',"
." '" . mysql_real_escape_string($message) ."')");
pinkgothic
+2  A: 

This line [request setHTTPBody:[NSData dataWithBytes:data length:[data count]]]; looks way wrong to me.

I think you want: [request setAllHTTPHeaderFields:data];

Secondly, you will find the Cocoa framework capitalizes the first letter of your field names before sending them (annoyingly). You might have to make some changes to cope with that.

invariant
Afraid not - now i'm getting:<HTML><HEAD><TITLE>400 Bad Request</TITLE></HEAD><BODY><H1>400 Bad Request</H1>Your client has issued a malformed or illegal request.</BODY></HTML>back from the sendSynchronousRequest: method. Are there any other header fields i need to send to conform with HTTP?
Ralf Mclaren
+3  A: 

If you are going to do a lot of form posting, I'd recommend skipping NSURLRequest and using ASIHTTPRequest instead. IMHO, it's well documented and offers an straightforward way to interact with webservices.

Victor Jalencas
thanks, but not looking to use it more than this once in the whole project really. Although i do like the look of how easy it makes to post stuff.
Ralf Mclaren
+2  A: 

Thanks for the suggestions everyone. In the end i managed to solve the issue by using stuff given here.

Code:

NSString *myRequestString = @"sender=my%20sender&rcpt=my%20rcpt&message=hello";
NSData *myRequestData = [ NSData dataWithBytes: [ myRequestString UTF8String ] length: [ myRequestString length ] ];
NSMutableURLRequest *request = [ [ NSMutableURLRequest alloc ] initWithURL: [ NSURL URLWithString: @"http://people.bath.ac.uk/trs22/insert.php" ] ]; 
[ request setHTTPMethod: @"POST" ];
[ request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[ request setHTTPBody: myRequestData ];
NSURLResponse *response;
NSError *err;
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse:&response error:&err];
NSString *content = [NSString stringWithUTF8String:[returnData bytes]];
NSLog(@"responseData: %@", content);
Ralf Mclaren
A: 

This didnt work for me... NSString *post = [NSString stringWithFormat:@"userudid=%@", [udid stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"%@",post); NSData *postData = [NSData dataWithBytes:[post UTF8String] length:[post length]]; //[udid dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSLog(@"%@",postData); //NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.myserver.com/myapp/readtags2.php"]];
[request setURL:url];
[request setHTTPMethod:@"POST"];
//[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *error;
NSData *urlData = [NSURLConnection sendSynchronousRequest:request
                                returningResponse:&response
                                            error:&error];

NSString *content = [NSString stringWithUTF8String:[urlData bytes]];
NSLog(@"responseData: %@", content);
mars
A: 

This is wrong:

[NSData dataWithBytes:[post UTF8String] length:[post length]]

The length should be expressed in bytes not in count of UTF8 characters. Instead of this line you should use:

NSData *data = [post dataUsingEncoding: NSUTF8StringEncoding]; 
Prcela