2010-12-15 57 views
2

J'ai une application web avec beaucoup de données, et une fonction de recherche/filtrage avec plusieurs champs, tels que le nom, l'état, la date, etc. J'utilise des requêtes paramétrées comme celui-ci pour les requêtes régulières (non recherche):Requête paramétrée avec plusieurs termes de recherche optionnels

$id = $_POST['itemID']; 
$db = mysqli_connect($host, $username, $password, $database); 
$sql_query = "SELECT * FROM tbl_data WHERE ID = ?"; 
$stmt_query = mysqli_prepare($db, $sql_query); 
mysqli_stmt_bind_params($stmt_query, "i", $id); 
mysqli_stmt_execute($stmt_query); 

//and so on.. 

Comment puis-je protéger SQL-injection de agains avec plusieurs paramètres, en option? Il peut y avoir jusqu'à 10 paramètres distincts qui peuvent ou ne peuvent pas être définis.

Modifier que la question ne semble pas claire:

Mon exemple était avec un paramètre, ce qui est en option. Je sais que cela protège contre sql-injection. Comment est-ce que je ferais ceci avec 10 paramètres, où un ou plusieurs pourraient être placés en même temps? Par exemple. une requête comme celle-ci:

SELECT * FROM tbl_data 
WHERE NAME = ? 
AND STATUS = ? 
AND DATE = ? 
AND PARAM4 = ? 
AND PARAM5 = ? 

où l'utilisateur veut uniquement rechercher le nom et la date. Comment ferais-je la liaison? Ce n'est pas une bonne idée de vérifier chacune des 100 combinaisons possibles de termes de recherche.

+0

Vous utilisez des paramètres liés sur des instructions préparées, de sorte que vous êtes automatiquement protégé contre l'injection SQL. L'injection SQL ne se présente que lorsque vous générez des requêtes sous la forme d'une chaîne à l'aide d'un contenu non contrôlé (non échappé) dérivé des soumissions d'utilisateur. les paramètres liés sont automatiquement échappés par le pilote de base de données, vous n'avez donc pas à vous en préoccuper. – Lee

+0

@Lee, non, il ne l'est pas. Dans ce cas particulier, vous devez vous inquiéter. –

Répondre

3

Vous êtes déjà protégé contre l'injection SQL, car vous utilisez mysqli_stmt_bind_params qui vous échappera correctement.

Modifier. Vous pouvez passer à un cadre de base de données pour avoir un code propre et beau.

Sinon ... c'est si vieux style spaghetti ... mais je l'aime: D

Il est assez facile d'élargir votre code pour travailler avec un nombre inconnu de paramètres. Vous devriez simplement boucler vos paramètres et en même temps 1. construire votre chaîne de requête avec la notation de point d'interrogation, et ajouter vos paramètres à un tableau, que vous passerez à maxdb_stmt_bind_param (ressource $ stmt, string $ types, tableau & $ var).

Donc, cela ressemblerait à ceci. Il suppose qu'au moins un paramètre existe (mais c'est trivial pour éviter cela).

$sql = "SELECT * FROM tbl_data WHERE "; 
$and = ''; 
$types = ''; 
$parameters = array(); 
foreach($_POST as $k => $v) { 
    // check that $k is on your whitelist, if not, skip to the next item 
    $sql .= "$and $k = ?"; 
    $and = " AND "; 
    $parameters[] = $v; 
    $types .= 's'; 
} 
$stmt_query = mysqli_prepare($db, $sql); 
mysqli_stmt_bind_params($stmt_query, $types, $parameters); 
+0

@Palantir Merci, je sais que cela fonctionne, mais je suis après une façon de l'utiliser avec 10 paramètres différents, qui peuvent ou ne peuvent pas être définis. Voir la question éditée pour plus d'informations. – Lizzan

+0

Ah, ok, maintenant je comprends votre point. Voir ma modification. – Palantir

+0

Merci, cette délicieuse assiette de pâtes aide énormément ... = P (Ma base de code entière est 'ancien style spaghetti' pour ce projet - j'ai besoin de me mettre à jour ... =) – Lizzan

1

Je recommande de passer à PDO. Il est construit en PHP comme l'extension mysqli, mais a une syntaxe plus propre et vous permet de transmettre vos valeurs de paramètres sous la forme d'un tableau, que vous pouvez facilement construire dynamiquement avec autant d'éléments que nécessaire.

+0

Merci, je vais regarder dans PDO. Est-ce automatiquement et quels paramètres sont envoyés ou pouvez-vous le spécifier? – Lizzan

+0

Vous écrivez toujours le? dans votre chaîne de requête. Il ne construit pas la requête pour vous. –

+0

Ah, OK, alors je ne vois pas comment cela m'aide, puisque j'ai toujours besoin des 100 permutations de requête différentes. – Lizzan