Я несколько раз использовал функцию mysqli_stmt_bind_param. Однако, если я разделяю переменные, которые я пытаюсь защитить от внедрения SQL, я сталкиваюсь с ошибками.
Вот пример кода:
function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol ) { $statement = $mysqli->prepare("INSERT INTO " .$new_table . " VALUES (?,?,?,?,?,?,?);"); mysqli_stmt_bind_param( $statment, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol ); $statement->execute(); }
Возможно ли каким-то образом заменить .$new_table.
конкатенация с другим выражением вопросительного знака, создание другого оператора параметра привязки или добавление существующего для защиты от SQL-инъекции?
Как это или в какой-то форме:
function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol ) { $statement = $mysqli->prepare("INSERT INTO (?) VALUES (?,?,?,?,?,?,?);"); mysqli_stmt_bind_param( $statment, 'ssssisss', $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol ); $statement->execute(); }
Короткий ответ на ваш вопрос – «нет».
В строгом смысле, на уровне базы данных подготовленные операторы позволяют только привязывать параметры к битам «values» инструкции SQL.
Один из способов думать об этом – «вещи, которые можно заменить во время выполнения инструкции без изменения ее значения». Имя (и) таблицы не является одним из этих значений времени выполнения, поскольку оно определяет правильность самого оператора SQL (то есть, какие имена столбцов являются допустимыми) и изменение его во время выполнения потенциально может изменить, является ли оператор SQL действительным.
На немного более высоком уровне даже в интерфейсах базы данных, которые эмулируют подстановку подготовленного оператора, а не фактически посылают подготовленные операторы в базу данных, такие как PDO, которые могли бы позволить вам использовать местозаполнитель в любом месте (так как местозаполнитель заменяется перед отправкой база данных в этих системах), значение заполнителя таблицы будет строкой и заключено как таковое в SQL, отправленное в базу данных, поэтому SELECT * FROM ?
с mytable
в качестве параметра на самом деле в конечном итоге отправить SELECT * FROM 'mytable'
в базу данных, что является недопустимым SQL.
Лучше всего просто продолжать
SELECT * FROM {$mytable}
но вы абсолютно должны иметь белый список таблиц, который вы проверяете первым, если этот $mytable
поступает с пользовательского ввода.
В конце концов, я получаю прекрасный ответ. как написать имя таблицы в инструкции подготовки динамически. все трюки происходят с '{}'. вы должны использовать свою переменную внутри этого '{}'. он работает в моем коде.
$tablename = "run_time_variable"; $stmt = $conn->prepare("INSERT INTO `{$tablename}` (name, address, phone ) VALUES (?,?,?)"); $stmt->bind_param("sss", $name, $address, $phone ); $stmt->execute();