You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类环境下使用remove_action移除内部函数时触发TypeError错误求助

类环境下使用remove_action移除内部函数时触发TypeError错误求助

嘿,我最近碰到个棘手的问题,一直弹出Uncaught TypeError: call_user_func_array():这个错误,搞得我头大。之前这段代码没封装进类里的时候运行完全正常,一放进类里就出问题了。对了,我用remove_action是为了防止触发无限循环,有没有大佬能帮我排查下哪里错了?

下面是我的代码:

namespace Resources;

class ResourcesSettings
{
    /* Add resource to course - if its added as a block within topic but forgotten to add to course.
    -----------------------------------------------------*/
    public static function add_resource_to_course($post_id, $post)
    {
        /*
        -----------------------------------------------------
        // PERMISSIONS
        -----------------------------------------------------
        */

        // bail out if this is an autosave
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }

        // Check permissions
        if ('page' == $post->post_type) {
            if (!current_user_can('edit_page', $post_id))
                return;
        } else {
            if (!current_user_can('edit_post', $post_id))
                return;
        }

        // 剩余业务逻辑代码...
    }
}

从你遇到的报错和类封装的背景来看,大概率是**remove_action调用时的回调格式不对**导致的。因为在类环境下,静态方法作为钩子回调时,不能直接传方法名字符串,得用数组形式指定类和方法的关联:

  • 如果是在类内部调用remove_action,正确的回调格式应该是:[__CLASS__, 'add_resource_to_course']
  • 如果是在类外部调用,就得用完整的命名空间类名:[\Resources\ResourcesSettings::class, 'add_resource_to_course']

举个实际的例子,假设你之前是这么注册钩子的:

add_action('some_action_hook', [__CLASS__, 'add_resource_to_course'], 10, 2);

那对应的remove_action必须完全匹配这个回调格式,包括优先级和参数个数,不然PHP找不到正确的方法,就会触发call_user_func_array的类型错误。

另外要注意,remove_action必须在add_action之后调用,不然也会失效或者报错。你说要防止无限循环,那正确的写法大概是这样:

public static function add_resource_to_course($post_id, $post)
{
    // 先移除钩子,防止递归调用
    remove_action('some_action_hook', [__CLASS__, 'add_resource_to_course'], 10, 2);

    // 你的权限检查、业务逻辑代码...

    // 执行完逻辑后再把钩子加回去
    add_action('some_action_hook', [__CLASS__, 'add_resource_to_course'], 10, 2);
}

如果之前你remove_action的时候只传了方法名字符串,比如remove_action('some_action_hook', 'add_resource_to_course'),那PHP肯定找不到这个方法——因为它现在是类的静态方法,不属于全局函数范畴了,这就会导致call_user_func_array找不到可调用的目标,最终抛出TypeError。

备注:内容来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 12:23:03