Un moteur de recherche surpuissant en PHP (TNTSearch)

PrimFX Boris ('PrimFX') Le 7 février 2022

Découvrons TNTSearch, une librairie ultra simple & efficace qui permet de mettre en place en quelques minutes un moteur de recherche en PHP !

En effet, si vous avez déjà implémenté un moteur de recherche à coup de mots-clés et de LIKE en SQL, vous avez probablement été confronté à des problèmes de pertinence des résultats et/ou de rapidité : avec ce moteur de recherche, on règle les deux problèmes d'un coup ;-)

Code source :

  • config.php
    <?php
    require('./vendor/autoload.php');
    
    /**
     * SQL permettant de créer la table "articles" :
     * create table articles (id int primary key auto_increment, title varchar(255), author varchar(255), content text, description text, imageUrl text, publishedAt datetime);
     */
    
    try {
      $db = new PDO("mysql:host=localhost;dbname=search_engine", 'root', 'root');
      $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch(PDOException $e) {
      echo "Connection failed: " . $e->getMessage();
    }
  • import.php
    <?php
    require('./config.php');
    
    $apiKey = "VOTRE_CLE_API";
    
    $categories = ['technology', 'sports', 'science', 'business', 'entertainment'];
    foreach ($categories as $category) {
        $endpoint = "https://newsapi.org/v2/top-headlines?category=$category&pageSize=100&country=fr&apiKey=$apiKey";
    
        $response = file_get_contents($endpoint);
        $response = json_decode($response);
        var_dump($response);
    
        foreach ($response->articles as $article) {
            $q = $db->prepare('INSERT INTO articles (title, author, content, description, imageUrl, publishedAt) VALUES (:title, :author, :content, :description, :imageUrl, :publishedAt)');
            $q->bindValue('title', $article->title);
            $q->bindValue('author', $article->author);
            $q->bindValue('content', $article->content);
            $q->bindValue('description', $article->description);
            $q->bindValue('imageUrl', $article->urlToImage);
            $q->bindValue('publishedAt', date("Y-m-d H:i:s", strtotime($article->publishedAt)));
            $q->execute();
        }
    }
  • index.php
    <?php
    require('./config.php');
    use TeamTNTTNTSearchTNTSearch;
    
    $articles = [];
    if (!empty($_GET['q'])) {
    
        $tnt = new TNTSearch;
    
        $tnt->loadConfig([
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'search_engine',
            'username'  => 'root',
            'password'  => 'root',
            'storage'   => '.',
            'stemmer'   => TeamTNTTNTSearchStemmerPorterStemmer::class
        ]);
        $tnt->selectIndex("articles.index");
    
        $searchResult = $tnt->search($_GET['q'], 10);
        $ids = implode(", ", $searchResult['ids']);
    
        $q = $db->query("SELECT * FROM articles WHERE id IN ($ids) ORDER BY FIELD(id, $ids)");
    
    
        $q = $db->query("SELECT * FROM articles WHERE CONCAT(title, content) LIKE '%" . $_GET['q'] . "%'");
        $articles = $q->fetchAll(PDO::FETCH_ASSOC);
    }
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Recherche</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    
        <form method="GET">
            <input type="search" placeholder="Rechercher..." name="q">
            <button type="submit">OK</button>
        </form>
        
        <?php if ($articles): ?>
            <h2>
                Résultats<br>
                <small><?= $searchResult['hits'] ?> résultats en <?= $searchResult['execution_time'] ?></small>
            </h2>
    
            <ul>
                <?php foreach ($articles as $article): ?>
                    <li>
                        <h3>[#<?= $article['id'] ?>] <?= $article['title'] ?></h3>
                        <?= $article['content'] ?>
                    </li>
                <?php endforeach ?>
            </ul>
        <?php endif ?>
        
    </body>
    </html>

A propos de l'auteur

PrimFX
Boris ('PrimFX')

Je m'appelle Boris, j'ai 22 ans et je suis passionnĂ© d'informatique. Suite Ă  mes Ă©tudes (Licence Informatique puis MSc Computer Science au Trinity College Dublin), je gĂšre l'entreprise Single Quote co-fondĂ©e en 2019 et je profite de mon temps libre pour partager ma passion Ă  travers des vidĂ©os & articles 😃

Votre commentaire

Vous devez ĂȘtre connectĂ© pour poster un commentaire. Se connecter ou CrĂ©er un compte

Commentaires 5

  • bsalissou Le 2 mai, Ă  16:17 | RĂ©pondre

    Bonjour,
    Merci pour ce Tuto

  • InstantAssignmentHelp24 Le 13 dĂ©cembre, Ă  07:33 | RĂ©pondre

    Very insightful article, really appreciate it. As it help me in assignment writing service

  • sullymaz Le 28 aoĂ»t, Ă  18:36 | RĂ©pondre

    Merci pour ce tuto complet et trÚs bien expliqué.
    J'ai un peu de mal à utiliser Fuzziness si je peux avoir un exemple d'intégration rapide merci.

  • lilo Le 1 novembre, Ă  08:50 | RĂ©pondre

    @lilo PROBLEME RESOLU.pour ceux qui pourraient avoir le meme probleme que moi j'ai activé sqlite 3 dans le fichier php.ini et tout fonctionne bien.

  • lilo Le 31 octobre, Ă  21:34 | RĂ©pondre

    slt besoin d'aide.Ă  l'installation de tnt search j'ai ce message dans le terminal Cannot use teamtnt/tntsearch's latest version v3.0.0 as it requires ext-sqlite3 * which is missing from your platform.
    pourtant j'ai sqlite3 installé et php 7.2.
    Ă  l'execution du fichier generate-index.php j'ai ce message:Fatal error: Uncaught Error: Class 'TeamTNT\TNTSearch\Stemmer\FrenchStemmer' not found in C:\
    besoin d'une solution.merci