Что делает bind param?

Я учусь избегать SQL-инъекций, и я немного смущен.

при использовании bind_param, я не понимаю цели. На странице руководства я нашел следующий пример:

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

Теперь, предполагая, что эти 4 переменные были введены пользователем, я не понимаю, как это предотвращает SQL-инъекции. Насколько я понимаю, они все еще могут вводить туда все, что захотят.

Я тоже не могу найти объяснение 'sssd' там. Что он делает? Заключаться в том что делает его безопасным?

последний вопрос: я читал на другой вопрос, что mysqli_real_escape_string устарел, но в руководстве об этом не говорится. Как это устарело? Может ли он больше не избегать специальных символов по какой-то причине?

Примечание: этот вопрос объяснил, что bind_param, но я все еще не понимаю, почему это безопаснее и более защищенными. Bind_param объяснение

2 ответов


теперь, предполагая, что эти 4 переменные были введены пользователем, я не понимаю как это предотвращает SQL-инъекции. Насколько я понимаю, они все еще могут введите все, что они хотят.

основной принцип там использует подготовленный оператор который конструирован для отправки безопасного запроса к серверу БД, это может быть сделано путем избегать входного сигнала потребителя который нет части реального запроса, и также проверять запрос без любого (где предложение) для проверки валидности запрос перед использованием любых параметров.

отсюда вопрос: PDO отправляет необработанный запрос MySQL в то время как Mysqli отправляет подготовленный запрос, оба производят тот же результат

$stmt = $mysqli->prepare("SELECT * FROM users WHERE username =?")) {
$stmt->bind_param("i", $user);
$user = "''1''";

логи сервера:

  130802 23:39:39   175 Connect   ****@localhost on testdb
    175 Prepare   SELECT * FROM users WHERE username =?
    175 Execute   SELECT * FROM users WHERE username =0
    175 Quit

используя подготовленный оператор, сервер БД проверит запрос без любого параметра, на этом этапе, ошибки можно обнаружить перед связывать любой параметр, тогда, если запрос был действителен, то параметры также будут отправлены в сервер для завершение запроса.

из руководства PHPhttp://php.net/manual/en/mysqli.quickstart.prepared-statements.php:

экранирование и SQL-инъекция

связанные переменные будут автоматически экранированы сервером. Этот сервер вставляет их экранированные значения в соответствующие места в шаблон инструкции перед выполнением. Подсказка должна быть предоставлена сервер для типа связанной переменной, чтобы создать соответствующий преобразование. Увидеть mysqli_stmt_bind_param() функция для более информация.

..

Я также не могу найти объяснение для "sssd" там. Что это делать? Это то, что делает его безопасным?

ответ здесь:http://php.net/manual/en/mysqli-stmt.bind-param.php

i
corresponding variable has type integer

d
corresponding variable has type double

s
corresponding variable has type string

b
corresponding variable is a blob and will be sent in packets

последний вопрос: я читал на другой вопрос, что mysqli_real_escape_string устарел, но он не говорит, что в руководство. Как это устарело? Может ли он не избежать специальных символов больше по какой-то причине?

можете ли вы дать ссылку? Я думаю, вы неправильно поняли (mysql_real_escape_string())


используя подготовленные операторы, вы отделяете SQL-запросы от введенных пользователем данных. Вместо входных данных вы ставите заполнители ('?'char) в вашем SQL-запросе. Затем вы отправляете запрос на сервер СУБД (например, MySQL) с помощью метода "mysqli:: prepare". Таким образом, сервер проверяет, что все в порядке, и если это так, он ждет входных данных. Теперь он уже знает ваш запрос. Просто он должен ждать, пока входные данные будут привязаны к запросу.

в этот момент "bind_param" входит в действие, привязка заполнителей к введенным пользователем данным. Заметьте, что bind_param связывает данные только с заполнителями, оставляя неизменным запрос. Таким образом, нет способа изменить исходный SQL-запрос, поскольку он уже отправлен на сервер с помощью метода prepare и поскольку вы отправляете SQL-запросы и входные данные отдельно, поэтому введенные пользователем данные не могут мешать запросам.

в любом случае...

фактической целью использования подготовленного оператора в SQL является сократите стоимость обработки запросов, чтобы не отделять данные от запроса. Это то, как он используется сейчас, а не то, как он был разработан для использования в первую очередь.

'sssd' означает "строка", "строка", "строка"и " двойной". Фактически: $code-это строка, $language-строка, $official-строка, а $percent-двойной тип.

mysqli_real_escape_string не устарел, но mysql_real_escape_string устарел (первый-mysqlI, где я стою за "улучшенный.)"