子テーマのfunctions.phpを編集したら「Fatal error: Cannot redeclare … previously declared …」と表示されるとき
子テーマを作ってテーマをカスタマイズするときは、
- style.css --- 子テーマに記述した内容が優先される
- 各テンプレート --- 子テーマディレクトリにコピーして編集すれば、そちらが優先される
ですが、functions.phpは違います。
親テーマと同じ内容を子テーマのfunctions.phpに記述すると、「Fatal error: Cannot redeclare … previously declared…」というエラーメッセージが表示され、画面が真っ白になる場合があります。
親テーマと同じ内容とは、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」というエラーメッセージは表示されなくなります。
つまり、
- 親テーマのfunctions.phpにあるfunctionを子テーマにコピーする
- 親テーマのfunctionを「if (!function_exists('名前')) { }」でくくる
- 子テーマにコピーしたfunctionを編集(カスタマイズ)する
という流れになります。
functionとセットになっているadd_filter(...略...)は、そのまま放置しておいて大丈夫です(子テーマにコピーする必要もありません)。
※function_existsは、関数が存在するか調べるためのPHPの命令です。「!function_exists」は「function_exists('twentytwelve_wp_title') == false」(その関数が存在しなければ)の短縮形です。