WordPressで「Fatal error: Cannot redeclare」と表示されるとき
WordPressでPHPの編集時に「Fatal error: Cannot redeclare …」と表示されて画面が真っ白(HTTP 500 エラー)になることがあります。ここでは、WordPressユーザーの目線から「Fatal error: Cannot redeclare …」が起きる理由や対処法を紹介していきます。
この記事の内容
WordPressで「Fatal error: Cannot redeclare …」が起きる原因
「Fatal error: Cannot redeclare …」とは「関数が二重定義になっているため処理を停止する」という意味です。「関数の二重定義」の意味は後で説明するとして、WordPressでこのエラーが起きる原因の多くがfunctions.phpの修正ミスです。
たとえば、親テーマのfunctions.phpからすべてのコードをコピーして子テーマのfunctions.phpにペーストしていませんか?
一般的な子テーマを使ったカスタマイズ方法として「使いたいファイルを子テーマにコピーする」と聞いたかもしれませんがfunctions.phpは別です。単純に親テーマのfunctions.phpの内容をコピーして子テーマのfunctions.phpにペーストすると、「Fatal error: Cannot redeclare …」になります。
この場合、対処法は簡単で、子テーマのfunctions.phpにコピーペーストした部分を削除すれば大丈夫です。
なぜ「Fatal error: Cannot redeclare …」になるのか
なぜ「Fatal error: Cannot redeclare …」になるのか、仕組みを説明します。
同じ機能は作成できない
functions.phpの内容を子テーマにコピーペーストするとエラーになる理由は、同じ名前の機能を作成できないからです。functions.phpはサイトで使う機能の集合です。カスタム投稿タイプ、ヘッダー画像、サイドバー、各種ショートコードなど、膨大な機能が定義されています。
これらの膨大な機能は呼び出しやすいように「function」という単位でまとまっているのが一般的です。たとえば、「こんにちは!」と表示するショートコード[hello]を作るため次のような「function」が作成されているかもしれません。
/* あいさつを表示 */ function disp_hello() { return "こんにちは!"; } add_shortcode('hello', 'disp_hello');
同じ名前のfunction(関数)は作成できないため、次のように同じfunctionを2つ作成するとエラーになります。
/* あいさつを表示 */ function disp_hello() { return "こんにちは!"; } add_shortcode('hello', 'disp_hello'); /* あいさつを表示 */ function disp_hello() { return "おはよう!"; } add_shortcode('hello', 'disp_hello');
親テーマから子テーマにfunctionをコピーペーストするとエラーに
上記と同じ仕組みですが、親テーマのfunctions.phpから個々のfunctionを抜粋してコピーペーストしてもエラーになります。同じfunctionができてしまうからです。
対処法としては、安易に親テーマのfunctionを子テーマにコピーペーストしないことです。
functionをコピーしても良い場合
どうしても子テーマでカスタマイズしたい場合もあるでしょうから、親テーマから子テーマにfunctionをコピーペーストしても問題ないケースを紹介します。
「関数が存在しないときのみ」の条件が付いている場合
親切なテーマの場合、親テーマのfunctionが子テーマにコピーペーストされることを想定したコードになっている場合があります。具体的にはifとfunction_existsという命令を使って「関数が存在しない場合のみ、次の関数を定義してください」と書いてある場合があります。
たとえば、次のようなコードです。
if (!function_exists( 'disp_hello' ) ) { /* あいさつを表示(こんにちは) */ function disp_hello() { return "こんにちは!"; } add_shortcode('hello', 'disp_hello'); }
このように「関数が存在しなければ」のif文で囲んである関数は親テーマから子テーマのfunctions.phpにコピーペーストしても問題ありません。関数の存在チェックをしているので同じfunctionが重複せず、「Fatal error: Cannot redeclare」になりません。
このようなテーマではfunctionを子テーマのfunctions.phpにコピーペーストしてカスタマイズすれば、そちらが親テーマより優先されるので自由にカスタマイズできるようになります。
/* あいさつを表示 */ function disp_hello() { return "おはよう!"; } add_shortcode('hello', 'disp_hello');
後から読み込まれる親テーマでは同じfunctionが作成されないので子テーマのカスタマイズ内容が反映されます。
一時的に親テーマを編集する場合
同名関数の存在チェックがないテーマで、どうしても子テーマでfunctionをカスタマイズしたい場合は、一時しのぎですが親テーマのfunctionを「関数が存在しなければ」のif文で囲んでみる方法があります。
たとえば、親テーマに次のようなfunctionがあります。
/* あいさつを表示 */ function disp_hello() { return "こんにちは!"; } add_shortcode('hello', 'disp_hello');
これを「関数が存在しなければ」というif文で囲みます。
if (!function_exists( 'disp_hello' ) ) { /* あいさつを表示 */ function disp_hello() { return "こんにちは!"; } add_shortcode('hello', 'disp_hello'); }
これで親テーマのfunction(この例ではdisp_hello関数)を子テーマのfunctions.phpにコピーペーストして自由に編集できるようになります。
ただし、親テーマをアップデートするとfunctions.phpが上書きされて元に戻り「Fatal error: Cannot redeclare …」が発生する可能性があるのでアップデート前に対処が必要です。あくまで、「親テーマをカスタマイズするとアップデート時に全部消えてしまうので子テーマでカスタマイズしたい」の一時しのぎです。
まとめ
以上、WordPressで「Fatal error: Cannot redeclare …」が発生する典型的な例と対処法を紹介しました。原因は安易なコピーペーストがほとんどです。functionが重複できないという仕組みを理解して、エラーに対応できるようにしましょう。