Если каждый тип столбца является PDO::PARAM_STR
, то это довольно просто, чтобы связать ваши параметры unamed маркеров с помощью параметра Я PDOStatement::execute. Однако, если типы столбцов меняются, тогда вам нужно указать тип столбца для каждого столбца при привязке к нему с помощью PDOStatement::bindParam.
Принимая названия таблиц и столбцов от того, что кажется пользователем, не является хорошей идеей. Запрос не удастся, если имена таблиц или столбцов неверны, но вам нужно быть очень осторожными, чтобы гарантировать, что имена таблиц и столбцов безопасны в использовании. Следующий пример проверяет имена таблиц и столбцов против белого списка, перед выполнением каких-либо SQL:
function insert($postValues, $table) {
$dbh = $this->connect();
// Create a simple whitelist of table and column names.
$whitelist = array('my_table' => array('col1', 'col2', 'col3'));
// Check if the table name exists in the whitelist.
if(!array_key_exists($table, $whitelist)) {
exit("$table is not a valid table name.\n");
}
// Count the number of columns that are found in the whitelist.
$cols = count(
array_intersect(
$whitelist[$table],
array_keys($postValues)));
if($cols !== count($postValues)) {
exit("One or more invalid column names have been supplied.\n");
}
// Create a comma separated list of column names.
$columns = implode(', ', array_keys($postValues));
// Create a comma separated list of unnamed placeholders.
$params = implode(', ', array_fill(0, count($postValues), '?'));
// Create a SQL statement.
$sql = "INSERT INTO $table ($columns) VALUES ($params)";
// Prepare the SQL statement.
$stmt = $dbh->prepare($sql);
// Bind the values to the statement, and execute it.
return $stmt->execute(array_values($postValues));
}
echo insert(
array(
'col1' => 'value1',
'col2' => 'value2',
'col3' => 'value3'),
'my_table');
// 1
echo insert(
array(
'col1' => 'value1',
'col2' => 'value2',
'col3' => 'value3'),
'unsafe_table');
// unsafe_table is not a valid table name.
echo insert(
array(
'col1' => 'value1',
'col2' => 'value2',
'unsafe_col' => 'value3'),
'my_table');
// One or more invalid column names have been supplied.
Но, как можно прочитать в документации (http://php.net/manual/en/pdo.quote .php), вам лучше использовать prepare().Вы можете легко динамически создать строку sql с заполнителями и последовательно вызвать bindParam/bindValue, чтобы связать их с инструкцией. –
Да, действительно. Хотя, если я перебираю свои данные '$ _POST' (или любой другой массив, который я использую), я также могу действовать на данные. Например, хэш-пароли до того, как они будут использованы в запросе или пара ключ/значение полностью, если я обновляюсь, и пользователь ничего не вводил в качестве своего нового пароля. Если бы я не удалял ключ, пустая строка была бы хэширована и нарушала бы логин пользователя. Только один сценарий, о котором нужно подумать. –
@Dennis: К сожалению, вы не можете легко привязать значения массива к подготовленным операторам. Таким образом, подход выше - это нормально. Конечно, вы можете динамически строить подготовленный оператор SQL (добавляя столько заполнителей, сколько вам нужно), а затем привязывать каждый элемент массива к этому утверждению. –