問題描述

這是一個非常糟糕的做法,我必須説。花了兩個小時的時間找到一個解決方案來刪除通過匿名功能添加的操作和過濾器。

這是父主題上使用的代碼,我需要刪除它。

/**
 * Add custom columns to admin comments grid
 *  * Rate that user set.
 */
add_filter( 'manage_edit-comments_columns', function( $default ) {
    $columns['smr_comment_rate']  = __( 'Rate', 'txtdmn' );

    return array_slice( $default, 0, 3, true ) + $columns + array_slice( $default, 2, NULL, true );
});

有了 toscho’s answer,玩了很多,但沒有幫助。那麼還有其他替代方法可以刪除通過匿名函數添加的動作/過濾器嗎?

謝謝

最佳解決方案

問題是你不能區分形式的匿名函數和另一個,所以是的,可以刪除一個閉包 (即匿名函數),但如果多個閉包在同一個過濾器上以同樣的優先級行事,你必須做出選擇,刪除它們,礦石只能移除一個 (不知道哪個) 。

我將展示如何使用從 @toscho 答案中發佈的高度派生的功能刪除它們:

/**
 * Remove an object filter.
 *
 * @param  string $tag                Hook name.
 * @param  string $class              Class name. Use 'Closure' for anonymous functions.
 * @param  string|void $method        Method name. Leave empty for anonymous functions.
 * @param  string|int|void $priority  Priority
 * @return void
 */
function remove_object_filter( $tag, $class, $method = NULL, $priority = NULL ) {
  $filters = $GLOBALS['wp_filter'][ $tag ];
  if ( empty ( $filters ) ) {
    return;
  }
  foreach ( $filters as $p => $filter ) {
    if ( ! is_null($priority) && ( (int) $priority !== (int) $p ) ) continue;
    $remove = FALSE;
    foreach ( $filter as $identifier => $function ) {
      $function = $function['function'];
      if (
        is_array( $function )
        && (
          is_a( $function[0], $class )
          || ( is_array( $function ) && $function[0] === $class )
        )
      ) {
        $remove = ( $method && ( $method === $function[1] ) );
      } elseif ( $function instanceof Closure && $class === 'Closure' ) {
        $remove = TRUE;
      }
      if ( $remove ) {
        unset( $GLOBALS['wp_filter'][$tag][$p][$identifier] );
      }
    }
  }
}

我已經重命名了函數 remove_object_filter,因為它可以刪除所有類型的對象過濾器:靜態類方法,動態對象方法和閉包。

$priority 參數是可選的,但是當刪除閉包時,應該始終使用它,否則該功能將刪除添加到過濾器的任何封閉,無論在哪個優先級,因為當省略 $priority 時,所有使用目標類/方法的過濾器關閉被移除。

如何使用

// remove a static method
remove_object_filter( 'a_filter_hook', 'AClass', 'a_static_method', 10 );

// remove a dynamic method
remove_object_filter( 'a_filter_hook', 'AClass', 'a_dynamic_method', 10 );

// remove a closure
remove_object_filter( 'a_filter_hook', 'Closure', NULL, 10 );

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。