When a plugin registers a named function on a hook and a normal remove_filter() call still leaves it attached, I remove a filter hook forcefully by scanning $wp_filter at that priority and comparing the stored callable with === before calling remove_filter() again.

When remove_filter is not enough
For a plain function callback, the helper walks the priority bucket and removes the match. For an object method, prefer core remove_filter() with the real instance—[ $object_instance, 'prefix_get_item_data' ]—when you have it. Both patterns show up in the snippet below (WooCommerce woocommerce_get_item_data as the example hook).

Helper to remove a filter hook forcefully
The helper takes three arguments: the hook tag (e.g. woocommerce_get_item_data), the callable you want gone, and the priority (default 10—must match whatever the plugin used in add_filter).
Inside the function, global $wp_filter is WordPress’s live registry of hooks. If that tag was never registered, or nothing sits at your priority, we return early so we do not touch unrelated callbacks.
Otherwise we loop the callbacks at that priority. Each entry has a function value (string name, or [ $object, 'method' ]). When it strictly equals (===) the $callback you passed, we call core remove_filter() with that exact stored callable—so WordPress removes the real registration, not a guess.
function remove_obj_filter_forcefully( $tag, $callback, $priority = 10 ) {
global $wp_filter;
if ( empty( $wp_filter[ $tag ] ) ) {
return;
}
$callbacks = $wp_filter[ $tag ]->callbacks;
if ( empty( $callbacks[ $priority ] ) ) {
return;
}
foreach ( $callbacks[ $priority ] as $filter_id => $filter_callback ) {
if ( $filter_callback['function'] === $callback ) {
remove_filter( $tag, $filter_callback['function'], $priority );
}
}
}
// uses with function
remove_obj_filter_forcefully(
'woocommerce_get_item_data',
'prefix_get_item_data',
10
);
// uses with an object method
remove_filter(
'woocommerce_get_item_data',
[ $object_instance, 'prefix_get_item_data' ],
10
);Usage 1 — named function: call remove_obj_filter_forcefully() with the hook, the function name string ('prefix_get_item_data'), and priority 10. That is the “forceful” path when a plain remove_filter( $tag, 'prefix_get_item_data' ) is not sticking.
Usage 2 — object method: if you have the same object instance that registered the filter, skip the helper and use core remove_filter( $tag, [ $object_instance, 'prefix_get_item_data' ], 10 ). WordPress needs that array form to match how the plugin added it.
Swap the hook name, callback, and priority for your plugin. Run the remove late enough that the original filter already exists—wp_loaded or after the plugin’s own init is usually safe. Then reload the screen that used the filter (cart, checkout, etc.) and confirm the old behavior is gone.
Prefer a Code Snippets Plugin?
Hate editing functions.php on production? Keep this helper in a snippets plugin instead—WPCode, Code Snippets, or FluentSnippets all work.
Create a PHP snippet, paste the helper plus the usage lines you need (function helper and/or object remove_filter), then scope it to where the target hook runs—front end for most WooCommerce cart filters. Label the snippet clearly so you can disable it while debugging.
Load it only after the conflicting plugin registers its filter; if the remove runs too early, schedule the call on wp_loaded or a later hook inside the same snippet.

Quick checks
- Confirm the priority matches the original
add_filtercall. - For the helper, pass the same callable type that was added (function name string). Use core
remove_filterwith the object instance for methods. - Test the page that used the filter (e.g. cart) after removing it.
- Related shop cleanup: filter shipping rates from checkout fields.
FAQ
Is this safe on every site?
The helper only calls remove_filter() on an exact match. Prefer core remove_filter / remove_action when you already have the instance; use the helper for stubborn named function callbacks.
Does it work with closures?
No. Closures have no stable identity for === matching against a name string. Use the plugin’s remove API, or override earlier with your own filter.
Wrong priority?
If nothing is removed, dump $wp_filter['your_tag'] or check the plugin’s add_filter priority and pass that third argument.
Can I use it for actions too?
Yes. Actions live in the same $wp_filter structure, so the helper works for action tags as well.
Wrap-up
That is how I remove a filter hook forcefully in WordPress: scan the priority bucket, match with ===, then remove_filter()—and use core remove with the object instance when you have it. Verify on the front end after the conflicting plugin has loaded.
Source
Original snippet: Remove Filter Hook Forcefully gist.

