Подтвердить что ты не робот

Можно ли параметризовать имя таблицы в подготовленном заявлении?

Я использовал функцию 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();
}
4b9b3361

Ответ 1

Короткий ответ на ваш вопрос - "нет".

В строгом смысле, на уровне базы данных подготовленные операторы только позволяют привязывать параметры к битам "values" инструкции SQL.

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

На немного более высоком уровне даже в интерфейсах базы данных, которые эмулируют подстановку подготовленного оператора, а не фактически посылают подготовленные операторы в базу данных, такие как PDO, которые могли бы позволить вам использовать местозаполнитель в любом месте (так как заменяемый заменитель перед отправляемый в базу данных в этих системах), значение заполнителя таблицы будет строкой и заключено как таковое в SQL, отправленное в базу данных, поэтому SELECT * FROM ? с mytable, поскольку параметр действительно завершит отправку SELECT * FROM 'mytable' в базу данных, которая является недопустимой SQL.

Лучше всего только продолжить

SELECT * FROM {$mytable}

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

Ответ 2

В конце концов, я получаю прекрасный ответ. как написать имя таблицы в инструкции подготовки динамически. все трюки происходят с '{}'. вы должны использовать свою переменную внутри этого '{}'. он работает в моем коде.

$tablename = "run_time_variable";     
$stmt = $conn->prepare("INSERT INTO `{$tablename}` (name, address, phone ) VALUES (?,?,?)");
$stmt->bind_param("sss", $name, $address, $phone );
$stmt->execute();