Передача массива идентификаторов из Swift URLSession в PHP для запроса SQL?

У меня есть приложение для iOS с массивом идентификаторов. Все эти идентификаторы представляют собой числа:

var ids = [Int]() //Id array in my TableView
ids = basketStruct.getAllIds() //Pulling the array of ID's from my basket model.
print("This is how PHP sees the POST") //Debugging purposes
print(self.ids)
print("This is how PHP sees the POST")
basketServer.ids = self.ids //Passing the ID's to my URLSession.

URLSession обрабатывает массив следующим образом:

var ids = [Int]()
func downloadItems() {
    request.httpMethod = "POST"
    let postParameters = "ids="+String(describing: ids)
}

Я воздержался от публикации класса URLSession, поскольку в этом, вероятно, нет необходимости.

Теперь моя консоль XCode выглядит следующим образом:

This is how PHP sees the POST
[1,5,7,8]
This is how PHP sees the POST
Data downloaded
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}

Я не получил никаких результатов. Однако, если я изменил все свои массивы идентификаторов на тип NSArray и запустил, я получу возвращенные результаты, если мой массив содержит только 1 идентификатор. Когда я добавляю в массив более 1 идентификатора, я получаю ту же ошибку.

Теперь, на моем php, если я изменю все на GET, а не POST, и напрямую введу некоторые значения в свою адресную строку и перейду на страницу в браузере, все будет работать так, как должно. Я получаю хороший ответ в формате JSON со всеми идентификаторами, указанными в моей строке URL.

Если я изменю все обратно на POST, а затем получу доступ к моим файлам журнала ошибок apache после попытки запустить мое приложение, они скажут следующее:

[Thu Feb 22 20:51:42.873663 2018] [:error] [pid 18793] [client 192.168.1.46:60790] PHP Fatal error:  Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[1])' at line 1 in /var/www/api/DbOperation.php:92\nStack trace:\n#0 /var/www/api/DbOperation.php(92): PDO->prepare('SELECT * FROM `...')\n#1 /var/www/api/Basket.php(14): DbOperation->basket('[1, 5, 7, 8]')\n#2 {main}\n  thrown in /var/www/api/DbOperation.php on line 92

Я знаю, что эта проблема обширна и состоит из множества частей, но я застрял :( Любая помощь будет принята с благодарностью.

Спасибо

P.S - Если кто-нибудь захочет это увидеть, вот мой PHP-код:

Это страница PHP, на которую распространяется мой URLSession:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
require_once dirname(__FILE__) . '/DbOperation.php';

$ids = $_POST["ids"];

$db = new DbOperation();
$json = $db->basket($ids);

}

Вот DbOperation:

    public function basket($ids) {
    require dirname(__FILE__) .  '/../../dbconnect.php';
    $sql = "SELECT * FROM `Menu` WHERE `ID` IN ($ids)";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $result = $stmt->fetchAll();
    echo json_encode($result);
}

person JamMan9    schedule 22.02.2018    source источник


Ответы (1)


В выводе исключения PHP вы можете видеть, что функция корзины вызывается со строкой, подобной этой:

DbOperation->basket('[1, 5, 7, 8]')

Следовательно, код PHP сгенерирует этот SQL:

$sql = "SELECT * FROM `Menu` WHERE `ID` IN ($ids)";

Который:

SELECT * FROM `Menu` WHERE `ID` IN ([1, 5, 7, 8])

Это недопустимый SQL.

Вы можете добиться этого, преобразовав строку $ ids в формат, который будет работать в SQL.

// Remove '[' and ']' characters
$inValues = str_replace(['[',']'], '', $ids);
$sql = "SELECT * FROM `Menu` WHERE `ID` IN ($inValues)";

Теперь вы получите:

SELECT * FROM `Menu` WHERE `ID` IN (1, 5, 7, 8)
person ryantxr    schedule 22.02.2018
comment
Это уязвимо для SQL-инъекций. - person ishegg; 23.02.2018
comment
Я тебя люблю. Я понимаю точку зрения ishegg, я уже знал, что это было открыто для инъекционной атаки, я просто не мог понять, почему она не работает должным образом. Отмечу тебя как ответ. Спасибо за такое ясное объяснение. - person JamMan9; 23.02.2018