Guide complet de la recherche en temps réel dans Laravel

Dernière mise à jour: Décembre 5 2025
  • Laravel vous permet de tout implémenter, des moteurs de recherche simples avec AJAX aux recherches plein texte avancées utilisant Laravel Scout et des moteurs de recherche externes comme Algolia, Meilisearch ou Elasticsearch.
  • Pour les recherches légères, le filtrage côté client avec Alpine.js ou avec des requêtes fetch natives évite de surcharger le serveur et améliore l'expérience utilisateur pour les petites listes.
  • Laravel Scout centralise l'intégration avec différents moteurs de recherche et facilite le marquage des modèles comme indexables, la gestion des index et le lancement uniforme des requêtes.
  • Le choix du moteur (SaaS, open source ou base de données) doit être basé sur le volume de données, la complexité des recherches et les exigences de performance et de maintenance du projet.

Recherche en temps réel dans Laravel

Lorsque vous commencez à travailler avec Laravel et que vous avez besoin d'un moteur de recherche en temps réel qui répond instantanémentIl est facile de se perdre parmi les mille approches possibles : AJAX avec fetch, jQuery, Alpine.js, Scout avec Algolia ou Meilisearch, filtrage côté client, etc. La bonne nouvelle, c’est que l’écosystème Laravel fournit déjà pratiquement tout ce dont vous avez besoin pour mettre en place une recherche fluide et rapide sans y laisser votre peau.

Dans cet article, vous verrez comment assembler différents types de recherche en temps réel dans LaravelDe l'autocomplétion AJAX classique aux recherches plein texte avec Laravel Scout et des moteurs de recherche comme Algolia, Meilisearch, la base de données elle-même, ou encore Elasticsearch, vous trouverez des solutions plus complètes. Des alternatives plus légères avec Alpine.js permettent également de filtrer les données directement dans le navigateur lorsque le volume de données est faible.

Qu'est-ce qu'une recherche en temps réel dans Laravel et comment fonctionne son principe de base ?

L'idée derrière une recherche en temps réel est que, lorsque l'utilisateur saisit du texte dans un champ de texteUne requête est déclenchée et les résultats sont mis à jour sans rechargement de la page. Techniquement, cela repose sur trois éléments clés : le backend Laravel, le JavaScript du navigateur et l’échange de données au format JSON.

D'une part, Laravel fait office de couche serveur Il est chargé de recevoir les requêtes, d'interpréter les paramètres de recherche (le texte saisi), d'interroger la base de données et de renvoyer une réponse structurée, généralement au format JSON. Cette réponse peut indiquer le succès de la recherche, une erreur ou l'absence de résultats.

À l'autre extrémité, JavaScript est chargé d'écouter les événements utilisateur. Lors de la recherche, envoyez des requêtes asynchrones (AJAX) au serveur et affichez les données renvoyées sur la page sans recharger complètement le navigateur. Ceci peut être réalisé avec la fonction `fetch` native, jQuery AJAX ou de petites bibliothèques réactives comme Alpine.js.

Grâce à ce mécanisme de base, vous pouvez construire à partir d'un Saisie semi-automatique simple avec quelques enregistrements, jusqu'à un moteur de recherche plein texte avancé avec pertinence, pagination et filtres, pris en charge par des bibliothèques comme Laravel Scout et des moteurs de recherche externes optimisés pour la recherche.

Modèle, itinéraires et contrôleur pour un moteur de recherche temps réel basique

Avant de vous plonger dans JavaScript, vous devez vous assurer que la partie Laravel est bien organisée : un modèle Eloquent pour la recherche, le dégagement des itinéraires et un contrôleur dédié gérer la logique de recherche en temps réel.

La première étape consiste à disposer d'un modèle Eloquent représentant la table dans laquelle vous allez effectuer la recherche. Imaginez une table de pays et un modèle appelé Pays Très simple, sans horodatage et avec possibilité d'affectation en masse :

Exemple de modèle Eloquent minimal pour les recherches:

namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Pais extends Model
{
use HasFactory;
protected $guarded = [];
public $timestamps = false;
}

Il est indiqué ici que le modèle Pais se trouve dans l'espace de noms standard de Laravel.Elle hérite de Model et vous permet d'assigner n'importe quel champ avec create() en laissant le tableau protégé vide. En désactivant les horodatages avec public $timestamps = false, vous évitez les problèmes si la table ne contient pas les colonnes created_at et updated_at.

L'étape suivante consiste à définir les routes qui géreront à la fois l'affichage du moteur de recherche et les requêtes AJAXUn schéma très courant combine une route GET pour afficher la vue et une route POST conçue pour recevoir les requêtes en temps réel :

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BuscadorController;

Route::get('/', function () {
return view('welcome');
});

Route::get('buscador', [BuscadorController::class, 'index']);
Route::post('buscador', [BuscadorController::class, 'buscar']);

La route racine renvoie une vue de bienvenue, tandis que l'URL /search est réservé à la fonction de rechercheLa méthode index() du contrôleur affiche le formulaire et le champ de recherche, tandis que la méthode search() traite les requêtes asynchrones envoyées par le navigateur.

Dans le contrôleur, vous pouvez implémenter un modèle très pratique : Préparez un tableau de réponse par défaut en cas d'erreur. et ne la remplacez que lorsqu'il s'agit bien d'une requête AJAX valide et que celle-ci s'exécute sans problème.

Le contrôleur pourrait avoir un structure similaire à cette:

namespace App\Http\Controllers;

use App\Models\Pais;
use Illuminate\Http\Request;

class BuscadorController extends Controller
{
public function index()
{
return view('welcome');
}

public function buscar(Request $request)
{
$response = [
'success' => false,
'message' => 'Hubo un error',
];

if ($request->ajax()) {
$data = Pais::where('nombre', 'like', $request->texto.'%')
->take(10)
->get();

$response = [
'success' => true,
'message' => 'Consulta correcta',
'data' => $data,
];
}

return response()->json($response);
}
}

À ce stade, vous avez déjà Le cycle complet du backend : requête AJAX entrante, vérification qu’il s’agit bien d’une requête AJAX, requête avec clause WHERE et limitation des résultats Le nombre d'itérations est limité à un nombre raisonnable grâce à la fonction `take(10)` afin d'éviter de surcharger la base de données. La réponse est toujours envoyée au format JSON, ce qui simplifie considérablement le travail du frontend.

Vue Blade et récupération JavaScript pour la recherche réactive

Une fois le modèle, les routes et le contrôleur prêts, il est temps de construire la partie visible : un formulaire avec un champ de recherche et un bloc pour afficher les résultats, plus le code JavaScript chargé d'effectuer les requêtes en arrière-plan.

La vue Blade peut être très simple, s'appuyant sur Jeton CSRF que Laravel injecte pour valider les requêtes POST et dans un champ de recherche facile à utiliser :

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<strong><meta name="csrf-token" content="{{ csrf_token() }}"></strong>
<title>Laravel</title>
</head>
<body>

<form action="" method="post">
<input type="search" name="texto" id="buscar">
</form>

<div id="resultado"></div>

<script>
window.addEventListener('load', function () {
const buscar = document.getElementById('buscar');
const resultado = document.getElementById('resultado');

buscar.addEventListener('keyup', function () {
fetch('/buscador', {
method: 'post',
body: JSON.stringify({ texto: buscar.value }),
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': document.head.querySelector('[name~="csrf-token"][content]').content,
},
})
.then(response => response.json())
.then(data => {
let html = '';
if (data.success) {
html += '<ul>';
for (let i in data.data) {
html += '<li>' + data.data[i].nombre + '</li>';
}
html += '<ul>';
} else {
html += 'No existen resultados';
}
resultado.innerHTML = html;
});
});
});
</script>

</body>
</html>

Dans cet exemple, le script Surveillez l'événement keyup sur le champ de recherche.Chaque frappe au clavier déclenche une requête de récupération vers le chemin /search. Le texte actuel du champ est envoyé au format JSON, et des en-têtes clés tels que X-Requested-With sont inclus pour indiquer qu'il s'agit d'une requête AJAX, ainsi que le jeton CSRF pour contourner la protection native de Laravel.

Lorsque la réponse arrive, elle est transformée en JSON et générée dynamiquement. une petite liste HTML avec les résultatsOu encore un message du type « Aucun résultat trouvé » lorsque la requête ne renvoie aucune donnée. Le tout sans recharger la page, de manière intuitive pour l’utilisateur.

Ce modèle peut être affiné davantage grâce à de petits détails d'expérience utilisateur, comme l'ajout d'un délai (anti-rebond) Entre les frappes au clavier, afficher un indicateur de chargement ou gérer les erreurs réseau pour éviter que l'interface ne paraisse figée en cas de problème.

Recherche en direct avec Laravel et AJAX utilisant jQuery

Bien que le terme « fetch » ait beaucoup gagné du terrain de nos jours, jQuery AJAX reste très populaire Que ce soit dans des projets existants ou au sein d'équipes l'ayant déjà implémenté, le principe reste le même : capturer le texte saisi par l'utilisateur, effectuer une requête asynchrone et actualiser le DOM.

Un flux de travail typique avec jQuery dans Laravel pour la recherche en direct comprend généralement ces étapes de base : Définir un itinéraire spécifique, créer un contrôleur dédié, construire la vue Blade avec le champ de recherche Enfin, ajoutez le code jQuery qui déclenche une requête AJAX au fur et à mesure de sa saisie.

Le processus fonctionne comme suit : lorsque l'utilisateur commence à taper, jQuery envoie une requête au serveur Laravel filtre les informations de la base de données à l'aide de la chaîne de recherche, renvoie un JSON contenant les résultats correspondants, et jQuery met à jour un conteneur HTML sur la page pour refléter ces correspondances, le tout en quelques millisecondes.

L'avantage d'utiliser jQuery est que Cela résume assez bien la syntaxe d'AJAX. Et sa lecture est très simple si vous avez déjà la bibliothèque dans votre projet. Cependant, vous ajoutez une dépendance supplémentaire qui pourrait être inutile si vous utilisez JavaScript moderne et la fonction `fetch` native.

Filtrage et recherche en temps réel côté client avec Alpine.js

Lorsque les données à afficher sont relativement petites (par exemple, moins de 50 XNUMX articles), il n'est pas toujours judicieux de mettre en place un système dorsal avec des recherches complexes. Dans ces cas-là, une option très pratique est Filtrez directement dans le navigateur avec Alpine.js, sans envoyer de requêtes au serveur pendant que l'utilisateur saisit du texte.

L'idée est de précalculer une chaîne de recherche pour chaque élément (par exemple, nom, description et catégorie en minuscules), de la stocker dans un attribut data-search-text et de laisser Alpine.js gérer le reste. afficher ou masquer des éléments en fonction du texte écrit dans un champ de recherche.

Le composant Alpine.js peut avoir une structure similaire à celle-ci : éléments filtrés

{
search: '',
hasResults: true,
selectedValue: '',
init() {
this.$watch('search', () => this.filterItems());
this.$nextTick(() => this.$refs.searchInput?.focus());
},
filterItems() {
const searchLower = this.search.toLowerCase().trim();
const cards = this.$el.querySelectorAll('.item-card');
let visibleCount = 0;

cards.forEach(card => {
const text = card.dataset.searchText || '';
const isVisible = searchLower === '' || text.includes(searchLower);
card.style.display = isVisible ? '' : 'none';
if (isVisible) visibleCount++;
});

this.hasResults = visibleCount > 0;
},
}

Dans cette vue, chaque carte ou ligne de données comporterait un attribut data-search-text avec le texte déjà préparé en minusculesLe filtre se réduit donc à une fonction includes() en JavaScript, ce qui est très rapide pour les listes courtes :

<input type="search" x-model="search" x-ref="searchInput" placeholder="Buscar..." />
<div>
<div class="item-card" data-search-text="formulario contacto simple">
<h3>Formulario de contacto</h3>
<p>Formulario de contacto simple</p>
</div>
</div>

De plus, vous pouvez afficher un bloc d'état vide uniquement lorsque Aucun résultat ne correspond à la recherche actuelle.inviter l'utilisateur à modifier le texte ou à effacer le champ grâce à un bouton qui réinitialise simplement la recherche à une chaîne vide.

Cette approche présente des avantages évidents : Aucune requête serveur n'est effectuée pendant la recherche.L'interaction est quasi instantanée et la logique reste très locale, ce qui facilite le débogage. C'est la solution idéale pour les sélecteurs rapides, les fenêtres modales de sélection d'articles ou les petits catalogues intégrés à une page Laravel.

Laravel Scout : Recherche plein texte avec des moteurs spécialisés

Quand la situation devient sérieuse et que vous avez besoin des recherches plein texte rapides, pertinentes et évolutivesLa voie naturelle dans Laravel est Laravel Scout. Scout est une couche d'intégration qui vous permet de connecter facilement vos modèles Eloquent à des moteurs de recherche comme Algolia, Meilisearch, votre propre base de données, des collections en mémoire, ou même Elasticsearch via des contrôleurs externes.

Pour commencer avec Scout, la procédure habituelle est : créer un nouveau projet Laravel ou réutiliser un projet existantPour le déployer, utilisez Docker (par exemple, avec Laravel Sail) puis installez la bibliothèque avec Composer. Une fois cette étape terminée, publiez le fichier de configuration scout.php et ajustez les variables d'environnement en fonction du pilote souhaité.

Un flux de travail typique consisterait à installer Scout avec Composer, à publier sa configuration, et activer la file d'attente d'indexation avec SCOUT_QUEUE=true Dans le fichier .env, veillez à ce que les opérations gourmandes en ressources soient exécutées en arrière-plan afin d'améliorer les temps de réponse de l'application. De plus, vous devez vous assurer que la variable d'environnement DB_HOST pointe vers la base de données que vous utilisez, ce qui est particulièrement important si vous utilisez des conteneurs Docker.

Pour qu'un mannequin puisse participer aux recherches des scouts, il est nécessaire que Pour le marquer explicitement comme consultable, ajoutez le trait Searchable.Par exemple, si vous avez un modèle Train qui représente une table de trains avec un champ titre, vous pouvez le définir comme ceci :

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Train extends Model
{
use Searchable;

protected $fillable = ['title'];

public function searchableAs()
{
return 'trains_index';
}
}

La méthode searchableAs permet personnaliser le nom de l'index dans le moteur de rechercheAu lieu d'utiliser le nom par défaut issu du modèle, c'est Scout qui prend le relais. Scout gère alors la synchronisation des opérations de création, de mise à jour et de suppression avec l'index distant ou local, selon le pilote choisi.

Laravel Scout avec Algolia : Recherche SaaS ultra-rapide

Algolia est un service SaaS axé sur offrir des recherches très rapides et pertinentes sur de grands volumes de donnéesIl dispose d'un panneau web pour la gestion des index, des règles de pertinence, des synonymes, etc., et s'intègre parfaitement à Laravel via Scout et le client PHP officiel.

Pour utiliser Algolia avec Scout, vous devrez installer son client PHP avec Composer, enregistrer vos identifiants dans le fichier .env (ID d'application et clé API d'administration), et définir SCOUT_DRIVER=algolia Pour indiquer à Scout d'utiliser ce moteur, vous pouvez obtenir l'identifiant de l'application et la clé d'administration depuis le panneau Algolia.

Une fois l'environnement configuré, vous pouvez utiliser des méthodes telles que Train::search('texte')->paginate(6) directement dans vos contrôleurs pour effectuer des recherches sur les champs indexés, en recevant les résultats au format Eloquent paginé, prêts à être transmis à une vue Blade.

Par exempleVous pourriez avoir une manette indice qui liste tous les trains ou effectue une recherche si un paramètre titlesearch est reçu, et une méthode create pour insérer de nouveaux trains dans l'index :

public function index(Request $request)
{
if ($request->has('titlesearch')) {
$trains = Train::search($request->titlesearch)->paginate(6);
} else {
$trains = Train::paginate(6);
}

return view('Train-search', compact('trains'));
}

public function create(Request $request)
{
$this->validate($request, ['title' => 'required']);
Train::create($request->all());
return back();
}

Dans la vue correspondante, vous pouvez combiner un formulaire pour l'enregistrement des nouveaux trains Un autre formulaire GET avec un champ de recherche par titre déclenche la recherche lors de la soumission. Il suffit ensuite de parcourir la collection de trains et d'afficher leurs champs dans un tableau, en tirant parti des liens de pagination générés par Laravel.

Explorez avec Meilisearch, base de données et collections

Si vous préférez éviter les services externes, Meilisearch est un moteur de recherche open source que vous pouvez déployer localement ou sur votre infrastructure. Scout s'intègre à Meilisearch de manière très similaire à Algolia, en changeant simplement le pilote et en ajoutant les variables MEILISEARCH_HOST et MEILISEARCH_KEY au fichier .env.

Pour l'utiliser, vous installez le client PHP Meilisearch, vous configurez SCOUT_DRIVER=meilisearch et définissez MEILISEARCH_HOST sur l'URL de l'instance (par exemple, http://127.0.0.1:7700). Si vous disposiez déjà d'enregistrements, vous pouvez les indexer avec la commande php artisan scout:import "App\Models\Train" afin que le moteur puisse les utiliser.

Pour les applications de plus petite ou moyenne envergure, vous pouvez également choisir le Base de données des conducteurs de scoutsCette méthode exploite les index de recherche plein texte et les commandes LIKE de votre base de données MySQL ou PostgreSQL. Dans ce cas, aucun service externe n'est requis ; il suffit de définir SCOUT_DRIVER=database pour que Scout utilise la base de données elle-même comme moteur de recherche.

Une autre option intéressante est le collection de pilotes, qui fonctionne sur les collections Eloquent en mémoireCe moteur filtre les résultats à l'aide de clauses WHERE et du filtrage par collection, et est compatible avec toutes les bases de données prises en charge par Laravel. Vous pouvez l'activer avec `SCOUT_DRIVER=collection` ou en modifiant le fichier de configuration de Scout pour des paramètres plus spécifiques.

Intégration avec Elasticsearch via Explorer

Si vos besoins de recherche impliquent travailler avec d'énormes volumes de données et effectuer des analyses en temps réelElasticsearch est un classique. Dans l'écosystème Laravel, une méthode moderne pour l'intégrer à Scout consiste à utiliser le contrôleur Explorer, qui sert d'interface entre vos modèles et un cluster Elasticsearch.

Pour ce faire, on utilise généralement Docker, ainsi qu'un fichier docker-compose riche qui, en plus des services classiques (Laravel, MySQL, Redis, Merriam-Webster, etc.), Conteneurs Elasticsearch et KibanaEnsuite, vous installez le paquet jeroen-g/explorer via Composer et publiez son fichier de configuration pour indiquer quels modèles doivent être indexés.

Dans le fichier config/explorer.php, vous pouvez enregistrer vos modèles sous la clé indexes, par exemple en ajoutant App\Models\Train::classDe plus, vous devez modifier le pilote Scout en elastic dans le fichier .env avec SCOUT_DRIVER=elastic afin que tout pointe vers Elasticsearch.

Dans le modèle Train, l'interface Explored doit être implémentée et la méthode surchargée. mappableAsqui définit la correspondance entre les champs qui seront envoyés à l'index. Un exemple minimal serait :

use JeroenG\Explorer\Application\Explored;
use Laravel\Scout\Searchable;

class Train extends Model implements Explored
{
use Searchable;

protected $fillable = ['title'];

public function mappableAs(): array
{
return [
'id' => $this->id,
'title' => $this->title,
];
}
}

À partir d'ici, Vous pouvez lancer des recherches sur Elasticsearch en utilisant la même interface Scout., bénéficiant ainsi de temps de réponse très courts et de toute la puissance de requête de ce moteur, sans quitter l'écosystème Laravel.

Avec toutes ces approches, allant de l'autocomplétion basique avec fetch ou jQuery, au filtrage frontend avec Alpine.js, en passant par les recherches plein texte avec Laravel Scout et divers pilotes, Laravel vous offre un large éventail d'options pour implémenter des recherches en temps réel. adapté à la taille de votre projet, aux performances dont vous avez besoin et à l'infrastructure que vous êtes prêt à maintenir.

  Que fait un responsable de développement logiciel ?