Un heredoc est une chaîne sur plusieurs lignes. Commencez-le par <<<EOT, écrivez le texte sur les lignes suivantes, et terminez-le par EOT; seul sur sa ligne. Les variables à l'intérieur sont remplacées comme dans une chaîne entre guillemets doubles.
L'identifiant (ici EOT) est une lettre ou un tiret bas suivi de lettres, chiffres ou tirets bas. On choisit en général un nom qui dit ce qu'est le texte : HTML, SQL, TEXT. Certains éditeurs, dont PhpStorm, colorent le corps dans ce langage quand le nom est HTML ou SQL.
Construire un template HTML avec heredoc
Le heredoc est la façon la plus claire d'écrire un bloc de HTML contenant des valeurs, car le balisage garde sa forme et rien n'a besoin d'être échappé. La sortie est du HTML, donc l'éditeur l'affiche dans l'onglet Page.
Deux détails dans ce bloc : l'élément de tableau est entouré d'accolades, {$product['name']}, et le signe dollar littéral avant le prix est échappé en \$. Changez le nom ou ajoutez une balise et relancez.
Les valeurs venant des utilisateurs doivent être échappées avant d'aller dans du HTML. Voir htmlspecialchars pour savoir pourquoi et comment.
Nowdoc : du texte sans interpolation
Un nowdoc met l'identifiant entre guillemets simples : <<<'EOT'. Rien n'est remplacé à l'intérieur, donc les signes dollar et les barres obliques inverses restent tels quels. Utilisez-le pour des exemples de code, des expressions régulières et tout texte contenant $.
Indenter le marqueur de fin
Depuis PHP 7.3, le marqueur de fin peut être indenté, et cette indentation est retirée de chaque ligne du corps. Un heredoc placé dans une fonction ou un if peut ainsi suivre l'indentation du code sans que les espaces se retrouvent dans la chaîne.
La ligne json_encode rend le résultat visible caractère par caractère : 8 espaces ont été retirés de chaque ligne, car le TEXT; final est indenté de 8.
Une ligne du corps moins indentée que le marqueur de fin est une erreur de syntaxe :
$html = <<<HTML
<p>Hello</p>
HTML;
PHP Parse error: Invalid body indentation level (expecting an indentation level of at least 4) in /home/index.php on line 3
Tableaux, objets et appels de méthode dans un heredoc
Le heredoc suit les mêmes règles que les guillemets doubles. Les variables simples fonctionnent seules ; pour les clés de tableau entre guillemets, les tableaux imbriqués, les propriétés et les appels de méthode, utilisez des accolades.
Un heredoc comme argument de fonction
Depuis PHP 7.3, le marqueur de fin peut être suivi d'autre code sur la même ligne, donc un heredoc peut être passé directement à une fonction ou placé dans un tableau. Avec sprintf, vous obtenez un template dont les marqueurs sont remplis plus tard.
Erreur fréquente : point-virgule manquant ou texte en trop après le marqueur
L'identifiant de fin doit être écrit exactement comme à l'ouverture (même casse), et ce qui le suit sur cette ligne doit avoir un sens en PHP. EOT; termine une instruction, EOT, continue une liste d'arguments. Une lettre ou un chiffre juste après le marqueur (EOTX;) le masque, donc la chaîne continue jusqu'à la fin du fichier et PHP signale syntax error, unexpected end of file. Le piège inverse est une ligne du corps qui commence par l'identifiant suivi d'un espace ou d'une ponctuation, comme EOT is the marker : elle termine la chaîne trop tôt, et le reste de la ligne est lu comme du PHP (syntax error, unexpected identifier "is"). Choisissez un identifiant qui n'apparaît jamais en début de ligne dans le texte, comme HTML pour du balisage ou SQL pour une requête.
Questions fréquentes
Qu'est-ce qu'un heredoc en PHP ?
Une façon d'écrire une chaîne sur plusieurs lignes sans guillemets : commencez par <<<EOT et un saut de ligne, écrivez le texte, et terminez par EOT; seul sur sa ligne. Les variables à l'intérieur sont remplacées, exactement comme dans une chaîne entre guillemets doubles, et vous pouvez utiliser " et ' librement.
Quelle est la différence entre heredoc et nowdoc ?
Un heredoc (<<<EOT) remplace les variables et les séquences d'échappement comme une chaîne entre guillemets doubles. Un nowdoc (<<<'EOT', identifiant entre guillemets simples) ne fait ni l'un ni l'autre et garde chaque $ et chaque barre oblique inverse tels quels, comme une chaîne entre guillemets simples.
Le marqueur de fin d'un heredoc peut-il être indenté ?
Oui, depuis PHP 7.3. L'indentation du marqueur de fin est retirée de chaque ligne du corps, vous pouvez donc indenter un heredoc comme le reste de votre code. Chaque ligne du corps doit être indentée au moins autant que le marqueur de fin, sinon PHP s'arrête sur une erreur de syntaxe.
Comment appeler une fonction dans un heredoc ?
Le heredoc n'interpole que les variables, les éléments de tableau, les propriétés et les appels de méthode. Appelez d'abord la fonction et stockez le résultat, ou gardez le nom de la fonction ou une closure dans une variable et appelez-la entre accolades : $e = 'htmlspecialchars'; puis {$e($text)}.