Anonymous filters and actions can be removed natively using the following:
remove_filter( $tag, function(){}, $priority )
When generating the unique id using spl_object_hash()
, anonymous functions are comparable to one another, so the full closure object doesn't need to be re-created again.
If multiple filters or actions are connected to the same tag with the same priority, then it'll remove the latest filter or action which was added. If there's one you need to keep, you would have to remove all the filters up to the one you need removed, then re-add the others as necessary.
// Filter which was added and needs to be removed
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 );
} );
// Removes the last anonymous filter to be added
remove_filter( 'manage_edit-comments_columns', function(){} );
This will generally come back to best practices. I'll only ever use anonymous functions as part of a custom theme I'm developing for a client, where I don't want the filter to be overwritten or removed. In any public theme or plugin I develop, I'll use a factory to initialise a class, add all my filters and actions, then store the instance as a static variable.
EDIT
remove_filter
using an anonymous function doesn't appear to be working with the latest versions of WordPress and PHP. The function _wp_filter_build_unique_id
has been updated since WordPress 5.3.0, and it removed some `spl_object_hash' workarounds, which in turn prevent filters being removed in this manner.
The only way I can now see to remove filters is by manually adjusting the $wp_filter
global variable.
global $wp_filter;
unset( $wp_filter[ $tag ]->callbacks[ $priority ][ $identifier ] );
// or
foreach ( $wp_filter[ $tag ]->callbacks[ $priority ] as $identifier => $callback ) {
// Match identifier as necessary
}
// or
array_pop( $wp_filter[ $tag ]->callbacks[ $priority ] );