忘備録
── mbstring と headers already sent の正体(Xserver 共用サーバ)
PHP を 8.3 から 8.4 にアップデートした際、
Xserver の共用サーバ環境で、以下のエラー/警告が大量に出力されるようになった。
Deprecated: PHP Request Startup: Use of mbstring.internal_encoding is deprecated
Deprecated: PHP Request Startup: Use of mbstring.http_input is deprecated
Deprecated: PHP Request Startup: Use of mbstring.http_output is deprecated
Warning: Session ini settings cannot be changed after headers have already been sent
一見すると、
- mbstring の deprecated
- セッション関連の warning
という 別々の問題に見えるが、実際には PHP 起動時の ini 設定とエラー出力が連鎖した結果だった。
本記事では、
- なぜ PHP 8.4 でこの警告が出るようになったのか
- なぜ
headers already sentが同時に発生したのか - Xserver 共用サーバ +
.user.iniという前提で、どう直すのが正解か
を整理する。
環境
- サーバ:Xserver 共用サーバ
- PHP:8.4
- PHP 設定:
.user.ini - 構成:WordPress + 独自 PHP スクリプト混在
何が起きていたのか
PHP 8.4 に切り替えた直後から、
- ページアクセス時に Deprecated 警告が表示される
- それに続いて session 関連の warning が大量に出る
という状態になった。
エラーメッセージの特徴は、すべて
in Unknown on line 0
となっていた点である。
これは 特定の PHP ファイルではなく、PHP の起動フェーズ(Request Startup)で発生していることを示している。
原因①:mbstring の非推奨設定が読み込まれていた
PHP の mbstring に関する以下の ini 設定は、PHP 5.6 の頃から非推奨(deprecated)扱いとされてきた。
mbstring.internal_encoding
mbstring.http_input
mbstring.http_output
これらはかつて日本語環境では一般的に利用されていたが、現在では default_charset を中心とした設計に移行しており、公式ドキュメントでも使用は推奨されていない。
重要なのは、
値が空でも「設定として存在しているだけで」非推奨扱いになる
という点である。
.user.ini に以下のような記述が残っていると、
mbstring.internal_encoding =
mbstring.http_input =
mbstring.http_output =
PHP の起動フェーズ(Request Startup)で Deprecated 警告が出力される。
今回のケースでは、PHP 8.4 で新たに問題が発生したというよりも、以前から残っていた非推奨設定が、バージョンアップを契機に明確に警告として表面化したと考える方が正確である。
原因②:display_errors=On による副作用
問題をややこしくしていたのが、display_errors が有効になっていた点である。
display_errors = On
display_startup_errors = On
この状態だと、
- PHP 起動時に mbstring の Deprecated が発生
- その警告が 画面出力される
- 出力が行われた時点で HTTP ヘッダが確定
- その後に行われる session 初期化処理で
headers already sentが発生
という 連鎖が起きる。
対応内容
deprecated な mbstring 設定を削除
.user.ini から、以下の設定を 完全に削除した。
mbstring.internal_encoding
mbstring.http_input
mbstring.http_output
本番環境では display_errors を Off にする
display_errors=0
display_startup_errors=0
log_errors=1
なぜ PHP 8.4 で「突然」問題が起きたように見えたのか
この問題は PHP 8.4 固有の不具合ではない。
むしろ、長年残っていた非推奨設定が、PHP のバージョン進行により警告として顕在化したケースである。
PHP 8 系では、従来黙認されていた設定や挙動に対して、より明確な Deprecated 警告が出るようになっている。
そのため、設定自体は以前から存在していても、PHP の更新をきっかけに「突然壊れた」ように見えることがある。
まとめ
- PHP 8.4 で発生した mbstring の Deprecated は設定の問題
- headers already sent は二次被害
.user.iniの整理とエラー出力制御で解消できる- PHP のアップデート時は コードより先に ini を疑う