WordPressで製作したサイトで、「Cannot modify header information」の表示がでてしまったので、その時の対処法です。
発生状況
サイトのホームは通常通り表示されるが、下層ページを開くと、下記のように「Cannot modify header information – headers already sent by (output started at ~ と表示される。
エラー文以外は真っ白で、想定しているデザインは全く表示されていない状態。
今回エラーとなってしまったサイトの環境や状況は以下の通り
- 使用したサーバーはレンタルサーバー
- WordPressファイルは
hoge.com/wordpress
ディレクトリに置いてあり、hoge.com
でアクセスできるようになっている。 - php5.3で動いていた結構古いWordPressサイトのリニューアル(リリースと同時にphpは7.4に上げた)
- ローカル環境や別のサーバーでは発生しなかったので、このサーバー環境の問題と推定。
- 全ての下層ページがエラーになるわけではなく、URLをベタ書きしたものと、home_url( )関数を使っているところのリンクからアクセスすると発生する模様。
エラー内容
これはphpのエラーで、HTMLを送信する前段階のプレヘッダーが既に送信されているので、プレヘッダー情報を付与できないというもの。header関数より前に何かを出力したりすると現れるそうで、<?php のコードの前に空欄があったりすると発生する模様。
対処方法
以下の順に確認していきました。
WordPress公式サイトにこのエラーの対処法が書かれているので、そちらを参考にします。
エラーファイルの確認
メッセージを見ると、ルートディレクトリにあるindex.phpの1行目が怪しいので確認します。
pluggable.php on line 1329
という表記もありますが、(output started at ~)にあるファイルが問題の箇所で、後に続くpluggable.phpはその影響を受けているだけなので、見るのはindex.phpの方です。
index.phpは以下のとおり。
これと言って、<?php の前に空欄があるわけでもないので、たぶん問題はなさそう…(特別触るファイルでもないし、他の環境では動いていたので問題ないと推測)
<?php
/**
* Front to the WordPress application. This file doesn't do anything, but loads
* wp-blog-header.php which does and tells WordPress to load the theme.
*
* @package WordPress
*/
/**
* Tells WordPress to load the WordPress theme and output it.
*
* @var bool
*/
define('WP_USE_THEMES', true);
/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wordpress/wp-blog-header.php' );
phpの設定を確認する
今度はphpの設定を確認してみます。
適当なファイルをひとつ作って、以下のコードを書きサーバーにアップします。
今回はhoge.php
としたので、http://hoge.com/hoge.phpにアクセスします。
<?php phpinfo(); ?>
こんな感じで情報が表示されます。
ワーニングの表示を消す
調べていくとメッセージはwarningなので、これ自体は表示されないように消してしまっても問題はないという情報にだどりついたので、メッセージ自体を消してみます。
display_errorsをoffにします。(そもそもセキュリティ的には通常はoffにしておくようである)
php.iniに記載するのがいいのですが、レンタルサーバーであまり大元は触りたくなかったので、代わりにuser.iniを使って、このサイトがあるディレクトリに反映させました。
display_errors = Off
さきほどのhttp://hoge.com/hoge.phpで、display_errorsがoffになっていることも確認OKです(user.iniで設定しているのでLocal Valueの方)
結果、確かにエラー文は出なくなったけど、ただメッセージが消えただけで画面が真っ白のままなので、これだけではダメでした。
バッファリングをさせる
output_bufferingをONにして、バッファリングさせると解決するという情報を元にこちらも設定します。これがOFFだとクライアントに都度結果を送るが、ONにするとまとめて行ってくれるようになる模様。
先ほど書いたuser.iniにoutput_buffering = On
を追記します。
display_errors = Off
output_buffering = On
結果、無事にページが表示されました!他のページに遷移してもエラーも出ませんので、無事解決です。なので、このoutput_bufferingがOFFになっていたのが原因みたいですね。
ちなみに参考に今回使用したものとは別会社のサーバーのphp.iniを見てみたらデフォルトでONに設定されていました。