Как отправить данные JSON в базу данных PHP, используя target-c?

0

У меня проблема с отправкой данных в мою онлайн-базу данных. Кажется, что ничего не публикуется, когда я проверяю базу данных. Я выполнил NSLog на полученном ответе, и он пуст.

Вот.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);
?>

Однако, если я жестко запрограммирую $ 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
Лучший ответ

Несколько замечаний:

  1. Вы должны использовать интерфейс msqli а не устаревший интерфейс mysql.

  2. Вы никогда не должны вводить данные и просто использовать их в инструкции SQL. Используйте значения mysqli_real_escape_string или bind (как показано ниже). Это важно для обеспечения того, чтобы вы не были подвержены атакам SQL-инъекций. Он также защищает вас от невинных ошибок, которые могут возникнуть, если только что вставленное значение содержит зарезервированный символ.

  3. Вместо того, чтобы пытаться просто json_encode результат mysqli_query, вы должны построить более значимый ассоциативный массив. Например, вы можете проверить результат вызова mysqli и вернуть один JSON, если он был успешным, а другой - при сбое. Я мог бы предположить, что выдача отказа возвращает сообщение об ошибке.

  4. Вы должны протестировать свой PHP либо в веб-браузере, либо протестировать его с устройства, используя что-то вроде Чарльза. Убедитесь, что вы возвращаете JSON, который вы ожидали, прежде чем заходить слишком далеко с вашим кодом клиента. Внизу, посмотрите, можете ли вы протестировать код клиента и код сервера изолированно друг от друга (или сначала сохранить его как можно проще).

  5. Я не знаком с этим $_SERVER['HTTP_JSON']; построить. Если это работает для вас, отлично, но это не работает на моем сервере. Я исторически сделал fopen php://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 этого используйте sendAsynchronousRequest (или любое из множества других асинхронных методов). Никогда не высылайте синхронные запросы из основного потока.

  2. При анализе ответа resString будет содержать исходный JSON. Я не знаю, какую переменную jsonData вы ссылаетесь при создании jsonString, но это выглядит неправильно.

    Если вы хотите проанализировать ответ, это будет:

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

    Кстати, вышесказанное предполагает, что вы возвращаете словарь JSON в своем ответе, как и в моем примере, а не то, что сделал ваш оригинальный JSON.

  • 0
    спасибо Роб, PHP был изменен, чтобы быть более защищенным. Вопрос: если бы я хотел включить значение, скажем, значение поля «широта» в массиве как часть ответа, как бы я это сделал? В данный момент я делаю что-то вроде $ response = array ("success" => false, "message" => $ mysqli-> error, "latitude" => $ latitude, ...); но значение в широте равно нулю, когда я возвращаю json в Xcode, даже если в моей таблице есть значение для широты поля. Спасибо
  • 0
    Да, такой способ построения $response выглядит хорошо, поэтому я подозреваю, что при $latitude переменной $latitude произошла ошибка. Я бы предложил опубликовать новый вопрос с подробностями вашего пересмотренного PHP ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню