Laravel/PHPで改行込みの取得データをJavascriptでいじろうとした時にコーテーションの違いを知った

1 min read読了の目安(約1200字

やりたかったこと

Laravel の Blade で、テキストを取得して javascript で変化を与えたかった。
テキストは改行されているものだった。

失敗

const message = '{{ str_replace(array("\r", "\n"), "", $message) }}';

成功

const message = "{{ str_replace(array('\r', '\n'), '', $message) }}";

経緯

まず、普通に

const message = '{{$message}}';

とした場合。
Uncaught SyntaxError: Invalid or unexpected token
となり、デベロッパーツールで見てみると、改行場所を起点に構文エラーが出ていることがわかった。
なので、改行を取り除いてみることにしてみた。

const message = '{{ str_replace(array("\r", "\n"), "", $message) }}';

すると全く同じように、
Uncaught SyntaxError: Invalid or unexpected token
となった。

ではシングルとダブルを入れ替えただけの正しいパターンで試してみる

const message = "{{ str_replace(array('\r', '\n'), '', $message) }}";

動いた。

なぜ結果が違うのか

PHP の仕様でシングルクォーテーション ' 内を文字列として扱うという決まりがあるらしい。
つまり、"\r"や"\n"の方は文字列としてではなく特殊文字(改行)として扱われていたということみたいです。
なので、文字列変換がうまくいっていなくて、改行部分がそのままエラーになっていたようです。
噂では、ちょっと違うと聞いていたので、初めてこれによるエラーに会うことができました 🎉

ローカルだと普通に動くという罠

なぜ今回この記事を書いたのかという理由としては、ローカルだと失敗例でも想定どおりの動きをしていたのに、本番環境に上げたら構文エラーとなったところです。
うそやんって思いました。

書いてて思った

const message = @json($message)

こうすれば早かったかもしれない。
正直、ここら辺は複数通り試して動いたやつを使うみたいな感じなので理解が甘いと思っています。
次回同じ状況になったら試してみたい。

まとめ

PHP では、シングルコーテーションは完全に文字列
ダブルコーテーションは、ちょっと文字列じゃない