子テーマのfunctions.phpを編集したら「Fatal error: Cannot redeclare … previously declared …」と表示されるとき

WordPress個別サポート

子テーマを作ってテーマをカスタマイズするときは、

  • style.css --- 子テーマに記述した内容が優先される
  • 各テンプレート --- 子テーマディレクトリにコピーして編集すれば、そちらが優先される

ですが、functions.phpは違います。

親テーマと同じ内容を子テーマのfunctions.phpに記述すると、「Fatal error: Cannot redeclare … previously declared…」というエラーメッセージが表示され、画面が真っ白になる場合があります。

functions.phpの編集後に画面が真っ白になる
functions.phpの編集後に画面が真っ白になる

親テーマと同じ内容とは、functions.phpに記述された「function test() { }」の部分で、PHPではユーザー定義関数と呼びます。

たとえば、Twenty Twelveのfunctions.phpの166行目あたりには、titleタグをカスタマイズするfunction「twentytwelve_wp_title」が定義されています。

function twentytwelve_wp_title( $title, $sep ) {
...略...
}

この処理をカスタマイズしようとして、twentytwelve_wp_titleを子テーマのfunctions.phpにコピーして編集、保存すると、上記のようなエラーメッセージが表示されて、画面が真っ白になってしまいます。

対策:親テーマのfunctionをカスタマイズまたは条件を付加する

functions.phpの「function」に記述された内容をカスタマイズしたい場合、親テーマの記述を直接修正するのが現実的で簡単な対策です。

どうしても親テーマの処理は編集したくない場合、親テーマのfunctionについて「この関数が定義されていなければ」という条件を付加する方法があります。

if (!function_exists('twentytwelve_wp_title')) {
function twentytwelve_wp_title( $title, $sep ) {
...略...
}
}

※if ( ) { } という形になっています。閉じる } を付け忘れないようにしましょう。

これにより、子テーマに同じ名前のfunctionを記述した場合でも、「Cannot redeclare … previously declared」というエラーメッセージは表示されなくなります。

つまり、

  1. 親テーマのfunctions.phpにあるfunctionを子テーマにコピーする
  2. 親テーマのfunctionを「if (!function_exists('名前')) { }」でくくる
  3. 子テーマにコピーしたfunctionを編集(カスタマイズ)する

という流れになります。

functionとセットになっているadd_filter(...略...)は、そのまま放置しておいて大丈夫です(子テーマにコピーする必要もありません)。

※function_existsは、関数が存在するか調べるためのPHPの命令です。「!function_exists」は「function_exists('twentytwelve_wp_title') == false」(その関数が存在しなければ)の短縮形です。