
Dans une vue Blade, déclarez une variable avec @php $nom = '…'; @endphp, ou passez-la depuis le contrôleur avec view('vue', compact('nom')). Pour l’afficher, {{ $nom }} échappe le HTML et {!! $nom !!} l’insère tel quel. N’utilisez la seconde forme que sur du contenu de confiance : c’est là que se créent les failles XSS.
Deux besoins reviennent sans cesse dans une vue Blade : y déclarer une variable, et décider si son contenu doit être échappé ou rendu tel quel. Le second n’est pas un détail de confort, c’est le point où l’on introduit une faille XSS.
Publié dans le parcours Développement web. Ce guide couvre les deux : faire arriver une variable dans la vue, en déclarer une sur place, et choisir entre {{ }} et {!! !!} en connaissance de cause. Exemples exécutés sur Laravel 13.30.1 avec PHP 8.4.25.
Passer une variable depuis le contrôleur
C’est la voie normale, et celle qu’il faut privilégier : la vue affiche, le contrôleur décide. Le second argument de view() est un tableau associatif dont chaque clé devient une variable.
return view('dashboard', ['name' => 'Gekko']);<p>Bienvenue {{ $name }} !</p>Pour afficher une date issue d’un modèle, voyez la gestion des dates avec Carbon.
Pour plusieurs variables déjà présentes dans des variables PHP, compact() évite de répéter les noms :
$name = 'Gekko';
$reseau = 'gekkode';
return view('dashboard', compact('name', 'reseau'));with() permet d’en ajouter une au passage, ce qui est pratique quand la valeur se calcule au dernier moment :
return view('dashboard', compact('name'))->with('extra', 'valeur ajoutée');Si une variable peut manquer, donnez-lui une valeur de repli dans la vue plutôt que d’ajouter une condition :
{{ $inconnu ?? 'valeur par défaut' }}Déclarer une variable directement dans la vue
Quand la valeur ne sert qu’à l’affichage, la directive @php permet de la déclarer sur place :
@php
$nom = 'Gekko';
$classe = $task->active ? 'is-active' : 'is-done';
@endphp
<p class="{{ $classe }}">Bonjour {{ $nom }}</p>Les balises PHP classiques fonctionnent aussi, mais @php reste plus lisible et cohérent avec le reste du gabarit.
Deux directives couvrent les cas voisins sans passer par une variable. @class construit un attribut de classe à partir de conditions :
<div @class(['actif' => $task->active, 'masque' => $task->hidden])></div>
<!-- rendu quand active vaut true et hidden false -->
<div class="actif"></div>Et @once garantit qu’un bloc n’est rendu qu’une fois, même si la vue est incluse plusieurs fois dans la page :
@once
<script src="/js/carte.js" defer></script>
@endonce@php convient pour une valeur d’affichage. Dès qu’il s’agit d’une requête en base, d’un calcul métier ou d’une boucle de transformation, le code appartient au contrôleur, à un composant Blade ou à un accesseur du modèle. Une vue qui interroge la base génère des requêtes N+1 invisibles depuis le contrôleur.
Afficher du HTML : {{ }} contre {!! !!}
Blade compile {{ $variable }} en un appel à la fonction e(), qui échappe les caractères spéciaux. C’est visible dans la vue compilée, sous storage/framework/views :
<?php echo e($nom); ?>Conséquence : si la variable contient des balises, elles s’affichent en toutes lettres au lieu d’être interprétées.
@php $html = '<strong>gras</strong>'; @endphp
{{ $html }} {{-- affiche : <strong>gras</strong> --}}
{!! $html !!} {{-- affiche : gras, en gras --}}La syntaxe {!! !!} insère la valeur sans aucune transformation. C’est ce qu’il faut pour afficher un corps d’article rédigé en HTML, et c’est aussi la porte d’entrée d’une injection de script si la valeur vient d’un utilisateur.
N’utilisez {!! !!} que sur du HTML dont vous maîtrisez l’origine, ou qui a été nettoyé avant. Avec la valeur <script>alert(1)</script>, {{ }} affiche le texte tandis que {!! !!} exécute le script dans le navigateur du visiteur. Les deux comportements ont été vérifiés.
Pour du contenu venant d’un formulaire, que vous aurez pris soin de protéger contre les envois automatisés, nettoyez avant d’afficher. Une bibliothèque comme HTML Purifier applique une liste blanche de balises, à défaut, stockez du Markdown et convertissez-le au rendu, ce qui vous laisse le contrôle des balises produites.
Les cas particuliers utiles
Pour passer des données à du JavaScript, @json produit un littéral valide et échappé :
<script>
const config = @json(['id' => $task->id, 'titre' => $task->title]);
</script>Pour afficher des accolades sans que Blade les interprète, par exemple dans un gabarit destiné à un framework JavaScript, @verbatim neutralise le bloc entier :
@verbatim
<div id="app">{{ message }}</div>
@endverbatimPour une seule expression, la faire précéder d’un arobase suffit : @{{ message }}.
{{ e($valeur) }} échappe deux fois : <b> devient &lt;b&gt; et s’affiche littéralement à l’écran. {{ }} le fait déjà. La fonction e() ne sert qu’en dehors de Blade, ou à l’intérieur d’un {!! !!} sur une portion précise.
Erreurs fréquentes
<script>alert(1)</script> s’exécute réellement dans le navigateur du visiteur. Nettoyez le HTML avant, ou stockez du Markdown.e(). Le résultat affiche les entités à l’écran au lieu du texte.{{ $var ?? 'défaut' }} évite une erreur si le contrôleur ne l’a pas transmise dans tous les cas.

