Introduction
Admettons que nous possédions une table "articles" contenant une cellule "quelleCategorie". Dans cette cellule nous indiquons une ou plusieurs catégories pour chaque articles comme dans l'exemple suivant :
id | nomArticle | quelleCategorie | dateCreation
1 | banane | fruits | 5
2 | jus d'orange | jus de fruits | 9
3 | tomate | fruits ; legumes | 22
4 | maison | immobilier | 42
Admettons que nous désirons récupérer tout les articles ayant "fruit" dans "quelleCategorie". Avec l'option LIKE nous allons pouvoir spécifier un filtrage par motif (ou "pattern matching") afin de récupérer banane, jus d'orange et tomate et ce même si chacun possède une version légèrement différente de la catégorie.
À noter que vous pouvez aussi utiliser NOT LIKE qui vous permet de faire exactement l'inverse : demander à MySQL de ne retourner que les chaînes où n'est PAS présent le pattern.
Attention : une mauvaise utilisation de LIKE peut engendrer une chute des performances et une augmentation du travail pour le CPU du serveur MariaDB/MySQL.
L'exemple suivant va sélectionner dans la table "articles" tout les éléments ayant dans leur cellule "quelleCategorie" la sous-chaîne contenue dans la variable $categorieChoisie, classés du plus récent aux plus anciens.
<?php
$bdd_hostname = "localhost";
$bdd_name = "nomDeMaBase";
$bdd_login = "loginDeMaBase";
$bdd_password = "passowrdDeMaBase";
try {
$bdd = new PDO('mysql:host='.$bdd_hostname.';dbname='.$bdd_name.';charset=utf8', $bdd_login, $bdd_password);
} catch( Exception $e){
error_log("Error BDD connexion from ".$_SERVER["PHP_SELF"]);
}
$categorieChoisie = "fruit";
$requestSQL = $bdd->prepare('SELECT `*` FROM articles WHERE `quelleCategorie` LIKE %{:categorieChoisie}% ORDER BY `dateCreation`');
$requestSQL->bindParam(':categorieChoisie', strval($categorieChoisie), PDO::PARAM_STR);
$requestSQL->execute();
$myArticles = $requestSomeArticles->fetchAll(PDO::FETCH_CLASS);
print_r($myArticles);
?>
Explication en détails :
- On tente de connecter PDO à la base de données, si on réussi on obtient l'objet $bdd si non on retourne une erreur dans les logs (/var/log/apache2/error.log pour apache2)
try {
$bdd = new PDO('mysql:host='.$bdd_hostname.';dbname='.$bdd_name.';charset=utf8', $bdd_login, $bdd_password);
} catch( Exception $e){
error_log("Error BDD connexion from ".$_SERVER["PHP_SELF"]);
}
- On défini notre sous chaîne à rechercher : fruit
$categorieChoisie = "fruit";
- On demande a PDO de préparer notre requête à partir de l'objet $bdd
$requestSQL = $bdd->prepare('SELECT `*` FROM articles WHERE `quelleCategorie` LIKE %{:categorieChoisie}% ORDER BY `dateCreation`');
- Ici on lui demande de tout (*) récupérer dans "articles" où "quelleCategorie" ressemble à la chaîne injectée, ordonnée (ORDER BY) par leur date de création.
- On injecte le paramètre de recherche (fruit)
$requestSQL->bindParam(':categorieChoisie', strval($categorieChoisie), PDO::PARAM_STR);
- On exécute la requête SQL
$requestSQL->execute();
- On récupère le résultat de la requête SQL sous forme d'objet
$myArticles = $requestSomeArticles->fetchAll(PDO::FETCH_CLASS);
- Si vous préférez récupérer sous forme de tableau, remplacez la précédente ligne par les suivantes
$myArticles = array();
while($tmpArticle = $requestSomeArticles->fetch(PDO::FETCH_ASSOC)){
$myArticles[] = $tmpArticle;
}
- On affiche le résultat
print_r($myArticles);
Farm Link
- MySQL query String contains
- CommentCaMarche - Mysql like '%
- Mysql Doc - Pattern Matching
- tutorialspoint.com - MySQL LIKE Clause
- W3School - SQL LIKE Operator
- SQL.sh - SQL ORDER BY
- Tuto Ajax - afficher au format JSON des articles e-shop depuis MySQL-MariaDB grâce à PHP
- [PHP] MySQL - chercher présence sous chaine dans une cellule avec LIKE (tuto d'origine)
# Autre façon
Posté par harlock974 . Évalué à 1 (+0/-0).
Bonjour,
Tout d'abord merci d'avoir partagé ces sympathiques tutos :)
Je commente celui-ci car, sans être un spécialiste du php, il m'arrive de programmer des requêtes de ce type, mais dans un style assez différent du tien. En particulier, je n'utilise pas de connexion PDO (que je ne connaissais d'ailleurs pas), et donc l'injection de paramètre est superflue. Voilà comment je fais, en reprenant ton exemple :
Maintenant je ne sais pas s'il y a un avantage à l'une ou l'autre méthode.
[^] # Re: Autre façon
Posté par EauFroide . Évalué à 2 (+0/-0). Dernière modification le 04 mars 2017 à 01:53.
Le but des requêtes préparées (et donc de "l'injection" que j'utilise) c'est de lutter contre les failles SQL.
En gros si je me rappel bien, avec les requêtes préparées si un utilisateur envoie du SQL dans une variable : se sera traité comme une chaîne de caractère ou tout autre type que l'on peut forcé dans la requête. (notons que je n'ai pas encore vérifié tient)
PS: merci pour ton partage ;)
Donation Bitcoin : 1N8QGrhJGWdZNQNSspm3rSGjtXaXv9Ngat
Envoyer un commentaire
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.