以下代码中使用的REMOVE_FILTER的说明

时间:2019-12-10 作者:Alt C

我很困惑开发人员在这里做了什么。这是在一个类中。。过滤器已添加,然后删除,再添加。这段代码也会导致许多错误。

add_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), -1, 4);
和回调函数

public static function get_post_metadata($meta_value, $post_id, $meta_key, $single){
        if (is_admin()){
            return null;
        }

        remove_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), 0);
        $child_meta = get_metadata(\'post\', $post_id, $meta_key, false);
        $meta=null;
        if (WPKWP::get_parent()){
            $parent_meta = get_metadata(\'post\', WPKWP::get_parent(), $meta_key, false);

            if (is_array($parent_meta) && is_array($child_meta)) {
                $meta = array_merge($parent_meta, $child_meta);
            } else {
                $meta = $parent_meta;
            }
        } else {
            $meta = $child_meta;
        }
        add_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), 0, 4);
        return $meta;
    }

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

这个remove_filter() 是避免递归调用回调所必需的,这将由于无休止的函数执行而导致内存问题。

这种递归可能会发生,因为回调连接到get_post_metadata 通过调用get_metadata() 回调调用的函数。

因此,您需要首先“unhook”/从挂钩中注销回调,然后才能调用get_metadata().

否则,您最终会遇到以下情况:

WP applies the filter (calls apply_filters( \'get_post_metadata\', ... ))
- your callback is called
- the callback calls get_metadata()
- WP applies the filter
  - your callback is called
  - the callback calls get_metadata()
  - WP applies the filter
      - your callback is called
      - the callback calls get_metadata()
      - WP applies the filter.....
或:

your_callback() {
  your_callback() {
    your_callback() {
      your_callback() {
        ..... it never ends ...
因此,您的代码很好,因为它避免了不必要的递归。

但是,我注意到您没有正确卸下过滤器:

// You added the filter like so:
add_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), -1, 4);

// Then in the callback, you\'re removing it like this:
remove_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), 0);

// And later in that callback, the filter is added back:
add_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), 0, 4);
问题是,删除筛选器/操作时,接受的参数的优先级和数量必须与添加筛选器时使用的相同值相匹配:

// If you added the filter like so:
add_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), -1, 4);

// Then use the same parameters when removing the filter:
remove_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), -1, 4);

// And not like this — priority should be -1 and this is missing the fourth parameter:
remove_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), 0);
如果您最初是这样添加过滤器的,那么也应该以同样的方式将其添加回回调中;使用相同的参数:

// Like this:
add_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), -1, 4);

// Not this: (priority doesn\'t match)
add_filter(\'get_post_metadata\', array(WPKWP::CLASS_NAME, \'get_post_metadata\'), 0, 4);

相关推荐

为内置钩子调用do_action和Apply_Filters是否安全?

我正在开发一个插件,它需要复制一些内置的WordPress逻辑。(此逻辑不能用任何内置方法调用,也不能独立连接到。)在这个动作序列中,WordPress的正常行为是调用动作挂钩(do_action(\'wp_login\', ...)) 和过滤器挂钩(apply_filters(\'login_redirect\', ...)).如果在对应于在Core中调用它们的时间点调用它们,那么直接从我的插件调用这些内置钩子是否安全(并且是可以接受的做法)?或者,其他与此相关的开发人员期望在非常特定的时间执行操作的风