2015-01-11 75 views
0

我在將數據發送到我的在線數據庫時遇到問題。當我檢查數據庫時似乎沒有任何內容。我對接收到的響應執行了NSLog,並且它是空白的。如何使用objective-c發佈JSON數據到PHP數據庫?

這裏是.php爲:

<?php 
     $db_host="someurl.com"; 
     $db_username="some_user"; 
     $db_pass="some_passwd"; 
     $db_name="some_db"; 

     $conn = mysql_connect($db_host, $db_username, $db_pass) or die ("Could not connect to 
                     MySQL"); 

     mysql_select_db("$db_name") or die ("No database"); 

     // array for JSON response 
     $json = $_SERVER['HTTP_JSON']; 
     $data = json_decode($json); 
     $some1_id = $data->some1_id; 
     $imei = $data->imei; 

     //does the imei exist? 
     $result = mysql_query("SELECT * FROM usr_go WHERE imei = '".$imei."'"); 

     if (mysql_num_rows($result) == 0){ 
      if(isset($some1_id)) 
       $result = mysql_query("INSERT INTO usr_go(some1_id, imei) VALUES('".$some1_id."','".$imei."')"); 
     } 
     else{ 
      if(isset($some1_id)) 
       $result = mysql_query("UPDATE usr_go SET some1_id = '".$some1_id."' WHERE imei = '". $imei ." AND some1_id IS NULL "); 
     } 

     mysql_close($conn); 

     header('Content-type: application/json'); 
     $response = $result; 
     echo json_encode($response); 
?> 

但是,如果我硬編碼的$迴應是一些字符串值,的NSLog接收到的響應,它接收相應的字符串值。

這裏是我的代碼:

NSDictionary *dict = @{@"some1_id" : [NSNumber numberWithInt:self.cellIndex]}; 

    NSError *error = nil; 

    NSData *json = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error]; 

    if (json) 
    { 
     NSURL *url = [NSURL URLWithString:@"someurl.com"]; 

     NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; 
     [req setHTTPMethod:@"POST"]; 
     [req setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
     [req setHTTPBody:json]; 

     NSURLResponse *res = nil; 
     NSData *ret = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&error]; 

     NSString *resString = [[NSString alloc] initWithData:ret encoding:NSUTF8StringEncoding]; 
     NSLog(@"response String: %@",resString); 


     NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 
     NSLog(@"JSON Output: %@", jsonString); 
    } 
    else 
    { 
     NSLog(@"Unable to serialize the data %@: %@", dictionary, error); 
    } 

這是不是事實,這是不可能插入IMEI,這就是爲什麼它不張貼,或其他一些問題?

感謝您的協助。

回答

1

一對夫婦的意見:

  1. 您應該使用msqli接口,而不是過時mysql接口。

  2. 你不應該接受輸入,只是在SQL語句中使用它。使用mysqli_real_escape_string或綁定值(如下所示)。這對確保您不容易受到SQL注入攻擊至關重要。它還可以保護您免受插入的值恰好包含保留字符時可能出現的無辜錯誤。

  3. 而不是試圖只是json_encode結果mysqli_query結果,你應該建立一個更有意義的關聯數組。例如,您可能會檢查mysqli調用的結果,如果成功則返回一個JSON,而另一個失敗。我可能會建議讓失敗再現返回錯誤消息。

  4. 您應該測試你的PHP無論是在Web瀏覽器,或使用類似Charles的設備進行測試。確保在使用客戶端代碼之前,您已經找回了您期望的JSON。底線,看看你是否可以彼此隔離地測試客戶端代碼和服務器代碼(或者儘可能簡單地保持它)。

  5. 我不熟悉這個$_SERVER['HTTP_JSON'];結構。如果這對你很好,但它不適用於我的服務器。我歷來完成fopenphp://input,如下圖所示。

例如,這是一個不同的數據庫/表,但它可能說明了什麼樣的PHP代碼可能看起來像的想法:

// read JSON input 

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

$request_data = json_decode($raw_post_data, true); 

// prepare header for reply 

header("Content-Type: application/json"); 

// open database 

$mysqli = new mysqli($host, $userid, $password, $database); 

// check connection 

if ($mysqli->connect_errno) { 
    echo json_encode(array("success" => false, "message" => $mysqli->connect_error, "sqlerrno" => $mysqli->connect_errno)); 
    exit(); 
} 

// perform the insert 

$sql = "INSERT INTO locations (message, device, longitude, latitude) VALUES (?, ?, ?, ?)"; 

if ($stmt = $mysqli->prepare($sql)) { 
    $stmt->bind_param("ssdd", $request_data["message"], $request_data["device"], $request_data["latitude"], $request_data["longitude"]); 

    if (!$stmt->execute()) 
     $response = array("success" => false, "message" => $mysqli->error, "sqlerrno" => $mysqli->errno, "sqlstate" => $mysqli->sqlstate); 
    else 
     $response = array("success" => true); 

    $stmt->close(); 
} else { 
    $response = array("success" => false, "message" => $mysqli->error, "sqlerrno" => $mysqli->errno, "sqlstate" => $mysqli->sqlstate); 
} 

$mysqli->close(); 

echo json_encode($response); 

顯然,改變這種對你的表,但它說明了上述一些概念。我通常會添加更多的錯誤檢查(例如請求的Content-Type,在我嘗試使用它們之前確定變量的測試等),但您可能會明白。


在客戶端,也有一些較輕微的意見:

  1. 最嚴重的問題是使用sendSynchronousRequest。改爲使用sendAsynchronousRequest(或其他任何異步技術)。切勿從主線程發出同步請求。

  2. 解析響應時,resString將包含原始JSON。我不知道在構建jsonString時參考的jsonData變量是什麼,但看起來不正確。

    如果要解析響應,這將是:

    NSError *parseError; 
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; 
    

    順便說一句,上述假設你在響應返回一個JSON字典,像我這樣在我的例子,而不是你的原來的JSON做到了。

+0

感謝羅布,PHP已被改爲更安全。一個問題:如果我想包含數值,可以說數組中的字段值「緯度」作爲響應的一部分,我該怎麼做?現在,我正在做類似$ response = array(「success」=> false,「message」=> $ mysqli-> error,「latitude」=> $ latitude,...);但是當我在Xcode中獲取json時,即使我的表中有一個緯度值,緯度值也是null。謝謝 – Pangu

+0

是的,構建'$ response'的方式看起來不錯,所以我懷疑在'$ latitude'變量中存在一些錯誤。我會建議發佈一個新的問題,其中包含修訂後的PHP的詳細信息... – Rob