ある日、サイトを確認していて気づきました。
PC表示は問題ありません。表示速度もレイアウトも正常です。 ところがスマホで表示してみると、
- 一瞬だけ正常に表示される
- 直後にレイアウトが崩れる
- ページ下部に「このサイトで重大なエラーが発生しました。」と表示される
という、非常に嫌な挙動が発生していました。
まず疑ったこと(しかし違いました)
最初に疑ったのは、よくある原因です。
- CSSの崩れ
- JavaScriptの競合
- スマホ用スタイルの記述ミス
- キャッシュや最適化プラグイン
初めはその線でプラグインを全て無効化してみたり、ブラウザからソースを確認したりしてみましたが、調べた結果実際には、
- キャッシュ系プラグインは使用していなかった
- PC表示は常に安定している
- 「崩れる」というより「処理が途中で落ちている」挙動
これらの点から、CSSやJSではなく、PHP側でエラーが発生している可能性が高いと判断しました。
決定打はサーバーのエラーログ
ブラウザ画面には具体的なエラー内容が表示されませんでした。 このような場合、サーバー側のPHPエラーログを確認する必要があります。
利用しているレンタルサーバーからからエラーログを確認し、 スマホ表示でエラーを再現した直後にログを見たところ、
PHP Fatal error: Call to undefined function is_bot()
というエラーが記録されていました。
原因:未定義関数 is_bot()
エラー内容は非常にシンプルでした。
Call to undefined function is_bot()
みたままですが、存在しない関数を呼び出しているということです。
該当箇所は、使用しているテーマ「THE THOR」の single.php でした。
調べてみると、
- スマホ表示時
- ユーザーエージェント判定などの特定条件
でのみ is_bot() という関数を呼び出す処理があり、 その関数自体がどこにも定義されていない状態でした。
PC表示ではこの分岐を通らないため、 スマホ表示時だけエラーが発生していた、というわけです。
なぜ今まで問題にならなかったのか
考えられる理由は以下の通りです。
- PHP7系では表面化しにくかった
- 特定条件でしか実行されないコードだった
- PHP8系で未定義関数が即Fatal Error扱いになった
いつからエラーが出ていたのか定かではありませんが、PHPのバージョンアップか、テーマのアップデートか、何らかの環境変化によって、 テーマ内部に潜んでいた不整合が表に出たケースだと思います。
対応:子テーマで is_bot() を定義
テーマ本体を直接修正するのは避けたいところです。理由は単純で、アップデート時に修正内容が上書きされてしまうためです。
そのため今回は、子テーマ側で、本体で未定義の関数を補完するという方法を取りました。
手順① 子テーマの functions.php を開く
まず、子テーマの functions.php を開きます。wordpress管理画面にログインできればそこから、もしできないなら
- FTP
- サーバーのファイルマネージャー
等で、以下のファイルを編集します。
/wp-content/themes/(子テーマ名)/functions.php
手順② is_bot() が存在しない場合のみ定義するコードを追記
次に、ファイルの末尾に以下のコードを追加しました。
if ( ! function_exists('is_bot') ) {
function is_bot() {
if ( empty($_SERVER['HTTP_USER_AGENT']) ) {
return false;
}
$bots = [
'Googlebot',
'bingbot',
'Slurp',
'DuckDuckBot',
'Baiduspider',
'YandexBot',
'Sogou',
'Exabot',
'facebot',
'ia_archiver'
];
foreach ( $bots as $bot ) {
if ( stripos($_SERVER['HTTP_USER_AGENT'], $bot) !== false ) {
return true;
}
}
return false;
}
}
ポイントは、function_exists() を使っている点です。これにより、
- 将来テーマ側で is_bot() が定義されても競合しない
- 二重定義によるエラーを防げる
というメリットがあります。
手順③ 保存後、スマホ表示で動作確認
保存後、スマホ表示で該当の記事ページを確認しました。
結果は問題なし。あわせて、サーバーの error_log を確認し、 新しい Fatal Error が出ていないこともチェックしました。
この対応により、テーマ側が本来想定していた処理を壊すことなく、 安全に問題を解消することができました。
結果:スマホ表示も完全に正常化しました
対応後は、
- スマホ表示でのレイアウト崩れなし
- 「重大なエラー」表示も出ない
- PHPエラーログにも新しいエラーは出ない
という状態になり、問題は完全に解消しました。
「スマホ表示だけおかしい」、「一瞬表示されてから崩れる」、このような症状が出た場合、 CSSやJavaScriptを疑う前に、PHPのFatal Errorを確認することが非常に重要だと実感しました。
まとめ
今回の不具合は、
- 表示が一瞬正常に見える
- スマホ表示のみで発生する
- 毎回必ず起きるように見えない(PCでは正常に処理)
といった条件が重なり、原因特定が難しいケースでした。
しかし実際には、未定義の関数が呼び出される以上、条件に入れば必ず Fatal Error になる問題であり、
「不定期に見えた」のは、テーマ内の分岐条件による錯覚でした。テーマ側の実装に起因する不具合であっても、
- ログを確認する
- エラーの正体を把握する
- 子テーマで安全に補完する
という手順を踏めば、テーマ本体を壊さずに現実的な解決策を取ることができます。
すべてをテーマ作者任せにせず、「自分のサイトとしてどう安全に運用するか」を考えることも、WordPress を長く使っていく上では大切だと感じたトラブルでした。