Visualiser une révision

Tuto - Chercher présence d'une sous chaîne dans une chaîne avec MySQL grâce à LIKE

EauFroide : révision n°12 (27 juin 2017 20:42:43)

# 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](https://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html) nous allons pouvoir spécifier un [filtrage par motif (ou "pattern matching")](https://fr.wikipedia.org/wiki/Filtrage_par_motif) 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](https://fr.wikipedia.org/wiki/Pattern).
Attention : une mauvaise utilisation de LIKE peut engendrer une chute des performances et une augmentation des ressourcesu 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
<?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 : #
1. **On tente de [connecter PDO](http://php.net/manual/fr/pdo.connections.php) à la base de données, si on réussi on obtient l'[objet](https://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_objet#L.27objet_.28attribut_et_m.C3.A9thodes.29) _$bdd_ si non on retourne une erreur dans les logs (_/var/log/apache2/error.log_ pour apache2)**

```php
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"]);
}
```

1. **On défini notre sous chaîne à rechercher : _fruit_**

```php
$categorieChoisie = "fruit";
```

1. **On demande a PDO de préparer notre requête à partir de l'[objet](https://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_objet#L.27objet_.28attribut_et_m.C3.A9thodes.29) _$bdd_**

```php
$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.

1. **On injecte le paramètre de recherche (_fruit_)**

```php
$requestSQL->bindParam(':categorieChoisie', strval($categorieChoisie), PDO::PARAM_STR);
```

1. **On exécute la requête SQL**

```php
$requestSQL->execute();
```

1. **On récupère le résultat de la requête SQL sous forme d'objet**

```php
$myArticles = $requestSomeArticles->fetchAll(PDO::FETCH_CLASS); 
```

1. **Si vous préférez récupérer sous forme de tableau, remplacez la précédente ligne par les suivantes**

```php
$myArticles = array();
while($tmpArticle = $requestSomeArticles->fetch(PDO::FETCH_ASSOC)){
	$myArticles[] = $tmpArticle;
}
```

1. **On affiche le résultat**

```php
print_r($myArticles);
```



# Farm Link #
* [MySQL query String contains](http://stackoverflow.com/questions/2602252/mysql-query-string-contains)
* [CommentCaMarche - Mysql like '%](http://www.commentcamarche.net/forum/affich-2278267-mysql-like)
* [Mysql Doc - Pattern Matching](https://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html)
* [tutorialspoint.com - MySQL LIKE Clause](https://www.tutorialspoint.com/mysql/mysql-like-clause.htm)
* [W3School - SQL LIKE Operator](https://www.w3schools.com/SQl/sql_like.asp)
* [SQL.sh - SQL ORDER BY](http://sql.sh/cours/order-by)
* [Tuto Ajax - afficher au format JSON des articles e-shop depuis MySQL-MariaDB grâce à PHP](https://linuxfr.org/wiki/tuto-ajax-afficher-au-format-json-des-articles-e-shop-depuis-mysql-mariadb-grace-a-php)
* [[PHP] MySQL - chercher présence sous chaine dans une cellule avec LIKE](https://www.0rion.netlib.re/forum4/viewtopic.php?f=9&t=538) (tuto d'origine)