EC-CUBE 4のフロントが全ページ500になり、ログには次の例外だけが記録されている状態の対処です。
No loader is registered for the "yaml_old" format when loading the
"/path/to/eccube/app/Customize/Resource/locale/messages.ja.yaml_old" resource.
原因は、翻訳ファイルのバックアップをlocaleディレクトリに置いたことです。同じバックアップでもファイル名の付け方によって、サイトが落ちる場合と何も起きない場合に分かれます。分かれ目は、messages.ja.yamlのどの部分を書き換えたかです。
落ちる名前と落ちない名前
Symfonyは翻訳ファイルの名前をドメイン.ロケール.拡張子の3つに区切って解釈します。書き換えた場所によって結果が変わります。
| バックアップ名 | ロケール | 拡張子 | 結果 |
|---|---|---|---|
messages.ja.yaml.bak |
– | – | 読み込み対象にならない |
messages.ja_old.yaml_ |
ja_old |
yaml_ |
読み込まれず影響なし |
messages.ja.yaml_old |
ja |
yaml_old |
日本語ページが全て500 |
3行目だけが500になるのは、ロケールがjaのまま残っているためです。日本語のページを表示するとき、Symfonyはjaに属する翻訳ファイルをまとめて読み込みます。このバックアップもそこに含まれますが、拡張子がyaml_oldという未知の形式のため、対応する読み込み処理が見つからず例外になります。
2行目はロケールがja_oldに変わっています。実際には使われないロケールなので読み込まれる機会がなく、拡張子が未知の形式であっても影響が出ません。
読み込み対象になるファイルの条件
どのファイルを翻訳ファイルとして扱うかは、Symfonyのフレームワークバンドルに条件が書かれています。
return 2 === substr_count($file->getBasename(), '.')
&& preg_match('/\.\w+$/', $file->getBasename());
条件はドットがちょうど2個であることと末尾が英数字またはアンダースコアであることの2つです。messages.ja.yaml.bakはドットが3個になるため、この条件から外れて読み込まれません。末尾に.bakを付ける昔ながらの方法が、結果として最も安全ということになります。
注意が必要なのは、正規表現の\wにアンダースコアが含まれる点です。messages.ja.yaml_のように末尾へアンダースコアを1つ足しただけでは、ドットの数が2個のままなので読み込み対象から外れません。
ログから原因を特定する
例外のメッセージにファイル名がそのまま出るため、原因の特定自体は難しくありません。ただしスタックトレースの先頭には、翻訳とは関係のないテンプレート名が並びます。例外が発生するのがテンプレートの描画処理の途中だからです。
実際にこの例外が発生したときは、トップページと商品詳細ページでそれぞれ異なるテンプレートがエラー箇所として記録されていました。ページごとにエラー箇所が変わり、共通しているのはメッセージ本文だけです。記録されたテンプレートを調べても原因は見つからないため、No loader is registeredという文言で検索してください。
バックアップの安全な置き方
最も確実なのはlocaleディレクトリの外に退避することです。読み込み対象のディレクトリから出してしまえば、ファイル名を気にする必要がなくなります。同じディレクトリに置く場合はmessages.ja.yaml.20260226のように、ドットを3個にしてください。
この動作はEC-CUBE固有のものではなく、Symfonyの翻訳機能の仕様です。EC-CUBE 4.0.4以降ではapp/Customize/Resource/locale/に同名のファイルを置いて本体の翻訳を上書きできますが(Customizeディレクトリで翻訳を上書きする方法)、この上書き用のディレクトリも読み込み対象になるため、同じ注意が必要です。
EC-CUBEに関するお問い合わせ
[重要]現在公式にセキュリティサポートが切れていないPHPは8.1以上、MySQLは8.0以上で、対応しているEC-CUBEバージョンは4.2以上です。古いEC-CUBEを使っている方は適切なタイミングでバージョンアップをご検討ください。