Laravel:MYSQLに格納したHTMLタグをそのまま出力したい
Laravel:MYSQLに格納したHTMLタグをそのまま出力したい
現在マニュアル作成を進めていますが、マニュアルテーブルにはHTMLをサニタイジングして格納しました。
そして、Viewで呼び出したところHTMLタグがそのまま記載されている...。
何故だ!
そこには1年間Laravelを触っていたため慣れてしまった落とし穴がありました。
と言う事で、繰り返さないための備忘録です。
まずは解決方法から
LaravelのViewでよく使う【 {{ }} 】2重波かっこをやめ【 <?= ;?> 】での記載に変える。
何故HTMLタグがそのまま記載されてしまうか
使い慣れてくるとすっかり忘れてしまいますが、{{ }} の意味をもう一度呼び起こす必要があります。
{{ }} の中ではサニタイジングが行われている
私の持っているテキストには、コードをそのまま登録され攻撃される事を回避するために{{ }} を使いましょうと書いてありました。そうなんですよね。そこなんですよね。
なので、こんな記載は全てHTMLとして出力してくれません。
#ケース_01
{{ $item->text }}
#ケース_02
{{ htmlspecialchars_decode($item->text) }}
#ケース_03
{{ html_entity_decode($item->text) }}
#ケース_04
{{ e($item->text) }}
{{ }}で囲っている場合、内部ではサニタイジングが行われているので、例えばHTMLタグ<br> は文字<br> として表示されます。{{ }} 使っちゃダメです、はい。
もうすっかり忘れてました。
htmlspecialcharsとhtmlentitiesの違い
- htmlentitiesは適用可能な文字を全て HTML エンティティに変換
- htmlspecialcharsは特殊文字を HTML エンティティに変換
例えば以下のような違いが出ます。
htmlspecialchars('¥');
// ¥
htmlentities('¥');
// ¥
htmlentitiesは何でも変換してしまいます。
なので、htmlentitiesでサニタイジングしたものをhtmlspecialchars_decodeで戻すとおかしなパーツが出てきます。
Laravelの{{ }} で行われているのは htmlentities
Laravelの波かっこ内の処理はhtmlentitiesなのだそうです。
ただ、これはあくまでもViewでの処理の事。
デコードはUpdateの際にどちらを利用しているかで使う命令が変わります。
- エンコード:htmlentities => デコード:html_entity_decode
- エンコード:htmlspecialchars => デコード:htmlspecialchars_decode
間違えないようにしなきゃ。
実際のコード
<dl>
@foreach($items as $item)
<dt>{{$item->manual_title}}</dt>
<dd><?= html_entity_decode($item->manual_text); ?></dd>
@endforeach
</dl>
これで $item->manual_text の中に改行<br>が入っていても(<br>と表記されず)改行してくれます。
まとめ
<?= ?> 最近めっきり書かなくなりました。
<?PHP とかで書き出してた時が懐かしいw
そう考えると、この1年濃かったなぁ~と思えます。


