Сообщение от Зосимов
|
не пойму - что именно плохого?
|
Подставлять в запрос не фильтрованные данные поступающие извне, это беспечность, которая вполне может закончится очень большими неприятностями.
Ваш запрос не делает элементарного, экранирование данных. Но если это и будет сделано, то это будет означать только одно - текущий запрос исключает sql-инъекцию. Но данные помещенные в базу могут служить источником данных вложенных запросов впоследствии, а значит нужно будет всегда помнить об этом и производить их экранирование. Все потому, что вы данные не фильтруете, вас вообще не интересует действительно ли это ваши данные, соответствуют ли они типам ожидаемым.
Контекст вашей темы, это оптимизация. А что такое по вашему оптимизация - красиво выполнить действия на клиенте? А на сервере как получится?
Если СУБД не позволяет записать в базу набор данных в рамках одного запроса, это плохо, но придется выполнять массу запросов. Но если позволяет, то почему же вы не думаете об оптимизации? Я ведь показывал что нужно сделать, да даже если бы и не показал, вы, думая об оптимизации, просто обязаны изучить возможности СУБД, дабы сделать запись оптимальной.
Это вы обязаны знать -
http://fi2.php.net/manual/ru/security.database.php.
Это очень желательно знать -
http://fi2.php.net/manual/ru/book.filter.php.
Это
http://fi2.php.net/manual/ru/book.mysqli.php или это
http://fi2.php.net/manual/ru/book.pdo.php нужно использовать вместо этого
http://fi2.php.net/manual/ru/book.mysql.php.
Используя оригинальное расширение MySQL, вы обязаны сами экранировать данные подставляемые в запрос функцией mysql_real_escape_string(). При этом ожидаемые данные типа integer можно приводить к данному типу, и при этом помещать их в кавычки совсем не требуется.
Допустим, если в ключах knb и inb ожидаем integer, а в cdt строку, то данные первых двух ключей приводим к integer, а последнего экранируем функцией mysql_real_escape_string() и обрамляем кавычками. Подготовив таким образом данные для запроса, делаем запрос:
if($data = json_decode($_POST['kye'])) {
//каждое вложение $data при таком декодировании будет объектом
//подготавливаем запрос
$sql = 'INSERT INTO FROM table (...) VALUES ' . implode(',', array_map(function($v) {
return '(' . (int)$v->kbn . ',' . (int)$v->inb . ',"' . mysql_real_escape_string($v->cdt) . '")';
}, $data));
//выполняем запрос
mysql_query($sql);
}
При подготовке запроса можно не просто приводить данные к типу и экранировать, а производить их фильтрацию - если (int)$v->kbn или (int)$v->inb ноль, а это не должно быть, значит липовые данные, завершаем работу. Дату ли содержит $v->cdt или "Привет Федя!" ведь тоже не проблема проверить. То есть, либо if((int)$v->kbn) ..., либо используем класс Filter.
А в mysqli и PDO все, кроме фильтрации в контексте "то ли пришло?", можно возложить на sql-драйвер, указав типы и используя подстановки. Драйвер подготовит запрос корректно экранируя и подставив данные в запрос. Запрос будет выглядеть как
'INSERT INTO FROM table (...) VALUES (?,?,?),(?,?,?),(?,?,?),...'
На исполнение отдается этот запрос и массив данных - все вложенные массивы помещаются в один одномерный. Декодирование JSON при этом должно возвращать массив, указывая функции json_decode вторым параметром true/1.
И почитайте о различиях разбора в РНР строковых значений помещенных в одинарные и двойные кавычки.