📚 Fiche de Révision - Séance 14 : Barre de recherche avancée et LIKE

🎯 Objectifs de la séance

📖 Concepts Fondamentaux

1. La clause LIKE en SQL

La clause LIKE permet de rechercher des motifs dans les données. Elle utilise deux caractères spéciaux :

Symboles LIKE :

2. Exemples d'utilisation LIKE

-- Chercher un mot n'importe où
SELECT * FROM ARTICLE WHERE libTitrArt LIKE '%bleu%';

-- Chercher au début
SELECT * FROM ARTICLE WHERE libTitrArt LIKE 'SQL%';

-- Chercher à la fin
SELECT * FROM ARTICLE WHERE libTitrArt LIKE '%PHP';

-- Chercher un caractère spécifique
SELECT * FROM ARTICLE WHERE libTitrArt LIKE 'c_t'; -- 'cat', 'cut'

3. Utilisation sécurisée avec PDO

Ne jamais concaténer directement les variables dans les requêtes. Utiliser les requêtes paramétrées :

<?php
// ✓ BON : requête paramétrée
$keyword = $_POST['keyword'];
$request = $connect->prepare("SELECT * FROM ARTICLE WHERE libTitrArt LIKE :keyword");
$request->execute(['keyword' => '%' . $keyword . '%']);

// ✗ MAUVAIS : injection SQL possible
$request = $connect->query("SELECT * FROM ARTICLE WHERE libTitrArt LIKE '%$keyword%'");
?>
⚠️ Attention : Les symboles '%' doivent être ajoutés dans le tableau de paramètres, pas directement dans la requête SQL.

💡 Exercice 1 - Recherche Simple

Créer une barre de recherche qui cherche uniquement dans le titre de l'article.

Structures utilisées :
<?php
if(isset($_POST['submit']) && isset($_POST['keyword'])){
    $keyword = $_POST['keyword'];
    $request = $connect->prepare("SELECT * FROM ARTICLE WHERE libTitrArt LIKE :keyword");
    $request->execute(['keyword' => '%' . $keyword . '%']);
    $search_result = $request->fetchAll();
    
    if(count($search_result) > 0) {
        echo "<table>";
        foreach($search_result as $res) {
            echo "<tr><td>" . $res['libTitrArt'] . "</td></tr>";
        }
        echo "</table>";
    } else {
        echo "Aucun résultat trouvé.";
    }
}
?>

🔍 Exercice 2 - Recherche Multi-champs

Chercher le mot-clé dans plusieurs colonnes de l'article (titre, chapô, accroche, paragraphes, sous-titres, conclusion).

Champs à chercher :

Technique : Construire dynamiquement le WHERE

<?php
$tab_champs = ["libTitrArt", "libChapoArt", "libAccrochArt", "parag1Art", "libSsTitr1Art", "parag2Art", "libSsTitr2Art", "parag3Art", "libConclArt"];
$where = "";
$first = true;

foreach($tab_champs as $champ){
    if(!$first){
        $where .= " OR ";
    }
    $first = false;
    $where .= $champ . " LIKE :keyword ";
}

// Résultat : "libTitrArt LIKE :keyword OR libChapoArt LIKE :keyword OR ..."

$request = $connect->prepare("SELECT * FROM ARTICLE WHERE " . $where);
$request->execute(['keyword' => '%' . $keyword . '%']);
?>

Fonction str_contains() pour vérifier la présence du mot-clé

<?php
// Fonction pour PHP < 8.0
if (!function_exists('str_contains')) {
    function str_contains($haystack, $needle) {
        return $needle !== '' && mb_strpos(strtolower($haystack), strtolower($needle)) !== false;
    }
}

// Utilisation
if(str_contains($res['libChapoArt'], $keyword)) {
    echo $res['libChapoArt'];
}
?>
💡 Astuce : str_contains() retourne true si le mot-clé est trouvé, false sinon. C'est utile pour afficher uniquement les champs qui contiennent le mot-clé.

⭐ Exercice 3 - Surligner les résultats

Mettre en évidence le mot-clé dans les résultats de recherche.

Utiliser str_replace() ou str_ireplace()

<?php
// str_replace() : sensible à la casse
$text = str_replace($keyword, "<span style='background-color: yellow'>" . $keyword . "</span>", $text);

// str_ireplace() : insensible à la casse
$text = str_ireplace($keyword, "<span style='background-color: yellow'>" . $keyword . "</span>", $text);
?>
Exemple complet :
<?php
$keyword = "bleu";
$text = "Le ciel est bleu";
$highlighted = str_ireplace($keyword, "<span style='background-color: yellow'>$keyword</span>", $text);
// Affiche : "Le ciel est <span style='background-color: yellow'>bleu</span>"
?>

🚀 Exercice 4 - Recherche Multi-mots (Facultatif)

L'utilisateur peut entrer plusieurs mots (ex: "bleu réseaux"). Tous les mots doivent être présents dans l'article, mais pas forcément côte à côte.

Technique : Utiliser explode() et boucles

<?php
$keywords = $_POST['keyword'];
$keywords = explode(" ", trim($keywords)); // ["bleu", "réseaux"]

$tab_champs = ["libTitrArt", "libChapoArt", "libAccrochArt", "parag1Art", "libSsTitr1Art", "parag2Art", "libSsTitr2Art", "parag3Art", "libConclArt"];
$where = "";
$first_keyword = true;

foreach($keywords as $key => $keyword){
    if(!$first_keyword){
        $where .= " AND ";
    }
    $first_keyword = false;
    
    $where .= "(";
    $first_field = true;
    foreach($tab_champs as $champ){
        if(!$first_field){
            $where .= " OR ";
        }
        $first_field = false;
        $where .= $champ . " LIKE :keyword" . $key . " ";
    }
    $where .= ")";
}

// Résultat : "(libTitrArt LIKE :keyword0 OR ...) AND (libTitrArt LIKE :keyword1 OR ...)"

$tab_keywords = array();
foreach($keywords as $id => $keyword){
    $tab_keywords["keyword" . $id] = "%" . $keyword . "%";
}

$request = $connect->prepare("SELECT * FROM ARTICLE WHERE " . $where);
$request->execute($tab_keywords);
?>
💡 Logique : Avec "bleu réseaux", la requête cherche "bleu" ET "réseaux" dans n'importe quel champ, mais les deux mots doivent être présents dans l'article.

🎯 Exercice 5 - Guillemets pour phrases exactes (Facultatif)

Si l'utilisateur entre "lion bleu", chercher la phrase exacte côte à côte. Sinon, chercher les mots séparément.

Exemple :

Complexité : Cet exercice nécessite de parser les guillemets dans l'entrée utilisateur et adapter la requête SQL en conséquence.

📝 Résumé

Concept Exemple
LIKE '%mot%' Cherche le mot n'importe où
LIKE 'mot%' Cherche au début
explode() Séparer une chaîne en tableau
str_contains() Vérifier si une chaîne contient un mot
str_ireplace() Surligner le mot-clé dans le texte

🔗 Ressources utiles