Si chaque type de colonne est un PDO::PARAM_STR
, il est assez simple de lier vos paramètres marqueurs unamed de paramter utilisant PDOStatement::execute. Toutefois, si les types de colonne varient, vous devez spécifier le type de colonne pour chaque colonne lorsque vous liez avec PDOStatement::bindParam. Accepter les noms de table et de colonne à partir de ce qui semble être une entrée utilisateur n'est pas une bonne idée. La requête échouera si les noms de table ou de colonne sont incorrects, mais vous devez être très prudent pour vous assurer que les noms de table et de colonne sont sûrs à utiliser. L'exemple suivant vérifie la table et les noms de colonnes contre une liste blanche, avant d'exécuter une 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.
Mais, comme on peut le lire dans la documentation (http://php.net/manual/en/pdo.quote .php), vous feriez mieux d'utiliser prepare().Vous pouvez facilement créer dynamiquement une chaîne sql avec des espaces réservés et ensuite appeler bindParam/bindValue pour les lier à l'instruction. –
Oui, en effet. Bien que si je boucle sur mes données '$ _POST' (ou n'importe quel tableau que j'utilise) je peux aussi agir sur des données. Par exemple, dictez les mots de passe avant qu'ils ne soient utilisés dans la requête ou la paire clé/valeur si je mets à jour et si l'utilisateur n'a rien entré comme nouveau mot de passe. Si je n'ai pas supprimé la clé, une chaîne vide sera hachée et interrompra la connexion de l'utilisateur. Juste un scénario à penser. –
@Dennis: Malheureusement, vous ne pouvez pas facilement lier des valeurs de tableau à des instructions préparées. Donc, l'approche ci-dessus est OK. Bien sûr, vous pouvez créer dynamiquement l'instruction SQL préparée (en ajoutant autant d'espaces réservés que vous le souhaitez), puis lier chaque élément de tableau à cette instruction. –