WordPress 子主题制作出现 Cannot redeclare 错误的原因及解决方法

前段时间,我尝试以子主题的模式制作了一个主题。原以为制作起来 So Easy,可是,却没有想象的那么容易。首当其冲的是函数替换问题。

WordPress 官方给出的替换方法

<?php
if (!function_exists('theme_special_nav')) {
    function theme_special_nav() {
        //  Do something.
    }
}
?>

事实上却没有那么简单。有些函数替换会报 Cannot redeclare 错误,怎么回事呢?

出错的原因

大家翻开支持子主题的主题的 Functions.php(这句话真绕口),会发现,那些可以替换的函数,在 Functions.php 中也是使用:

<?php
if (!function_exists('theme_special_nav')) {
    function theme_special_nav() {
        //  Do something.
    }
}
?>

写的,这样就是可以替换的原因,然而那些不能替换的函数呢?一般就是这样的写法:

<?php
function theme_special_nav() {
    //  Do something.
}
add_action('xxx', 'theme_special_nav');
?>

那么不能替换的函数怎么替换呢?其实也可以巧妙解决的。本文就以 theme_special_nav 这个函数为例,说一下怎么解决的。

解决方法

假设父主题的 Functions.php 是这样写的:

<?php
function theme_special_nav() {
    //  Do something.
}
add_action('xxx', 'theme_special_nav');
?>

其实已经隐含着替换方法了,我们可以在子主题加入以下代码:

<?php
function remove_parent_theme_hook() {
	remove_action('xxx', 'theme_special_nav');
}
add_action('after_setup_theme', 'remove_parent_theme_hook');
function nikbobo_theme_special_nav() {
	// Do Something.
}
add_action('xxx', 'theme_special_nav');
?>

原理就是利用 WordPress 的 Hook 机制,在 after_setup_theme 即主题设置完成这个时机删除掉原来的 Hook,然后添加自己的 Hook,为什么一定要在 after_setup_theme 这个时机呢?直接一句:

<?php
remove_action('xxx', 'theme_special_nav');
?>

不就行了么?

大家有无留意到,WordPress 的子主题介绍上有一句话:

其实它会在父主题文件加载之前先载入

也就意味着,你 remove_action 的时候,这个 Hook 还没有建立,结果你自然知道了。

此文章是由nikbobo发表在旧博客分类目录的。将固定链接加入收藏夹。

关于 nikbobo

Nikbobo,本名刘永强,记忆空间站长,男,1998 年出生于广东茂名,至今(2022 年)23 岁,目前(2022 年)就读于广州大学华软软件学院,常以“nikbobo”这个网名混迹互联网。如无特殊注明,Nikbobo 在本站发表的文章,遵循 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议。详情请参阅关于页面的作者介绍。

发表回复

您的电子邮箱地址不会被公开。