PHP
HTML
Web
laravel
blade

Laravelで投稿された{{}}をエスケープする

Laravelで投稿された{{}}をエスケープする方法

Laravelのbladeファイルで{{}}を表示(エスケープ)させた際のメモ。

はじめに

Laravelで掲示板やSNSを作成する際に、ユーザーが投稿した文字列を出力したい場合があると思います。
この場合、入力された文字列に対してhtmlタグを特殊文字にエスケープすることで、HTML上で発火しないようにすることはよく行われていると思います。

しかし、Laravelのbladeファイル内では{{}}を利用することでphpの変数の値を表示することができます。例: {{$hoge}}

これにより、投稿文字列に{{hoge}}と入力し出力しようとした場合に、bladeファイル内で実行されアプリケーションが正しく実行されなくなる(崩壊する)ことがあります(実際今回なってしまいました)。

なので、{,}をエスケープしたいのですが、この二つには特殊文字がないためエスケープすることができません。

しかし、入力された内容を変更して表示はしたくない…。

そんな時に私が行なったことを紹介します。

やったこと

ゼロ幅空白を使う

こちらの記事(2. スペースは" "だけじゃない的な話)で紹介されていますが、スペースにはたくさんの種類が存在しています。
その中には、幅をもたず見た目上は何も文字列がないように見える空白があるのです。それをゼロ幅空白というのですが、今回はこれを特殊文字として挿入することで{}をエスケープしたいと思いました。

よって今回は以下のように処理を書くことで、エスケープを行ないました。

<?php
$msg = "{{hoge}}";

$pattern = '/{/';
  $msg = preg_replace_callback(
            $pattern,
            function($matches){
              return '{&#8203;';
            },
            $msg
          );

$pattern = '/}/';
  $msg = preg_replace_callback(
            $pattern,
            function($matches){
              return '&#8203;}';
            },
            $msg
          );

echo $msg;     // {&#8203;{&#8203;hoge&#8203;}&#8203;}

// html上では{{hoge}}と表示される

?>

入力文字の"{{hoge}}"をphpの組み込み関数であるpreg_replace_callbackで文字列置換します。
今回の場合は、正規表現/{/,/}/のどちらかに該当した場合にそれぞれ{&#8203;,&#8203;}に文字列置換を行い、置換された文字列を$msgに格納しています。

今回はこの方法でうまくエスケープすることができました。

ただ、これが最善だとは思っていないのでいい方法があったらぜひ教えてください。

調べてもこのエスケープに関する記事が見つからなかったので、同じ悩みを抱えている人は参考にしていただけると嬉しいです。