Intereting Posts
Редактирование экрана: сделать обновление или опубликовать кнопку Follow The Page Сохранение массива значений (URL-адресов файлов) для update_user_meta ()? Получить сообщения с любым значением в атрибуте загружать файл с представлением переднего плана и пересылать данные по электронной почте shortcode в пользовательском метабоксе Постоянные ссылки с term.html и category / term.html без плагина? Как заполнить родительскую страницу дочерними подстраницами и связанными с ними шаблонами Как добавить страницу пользовательских подробностей для подписчика в панели администратора Зная, является ли сообщение липким в действии save_post. Где мне нужно зацепить? wp_nav_menu проверить, что обе иерархии терпят неудачу? Форма RSVP для событий Facebook из сообщения WordPress? Глубокая привязка к вкладке аккордеона с помощью Visual Composer Как включить комментарий и количество сообщений пользователя в этом пользовательском запросе Добавление тегов при создании нового сообщения Ошибка при отправке формы с использованием AJAX и php

Как удалить фильтр, анонимный объект?

В моем файле functions.php я хотел бы удалить фильтр ниже, но я не уверен, как это сделать, поскольку он находится в классе. Что должно remove_filter() ?

 add_filter('comments_array',array( &$this, 'FbComments' )); 

Это на линии 88 здесь .

Это очень хороший вопрос. Это сводится к темному сердцу API плагина и лучшим практикам программирования.

Для следующего ответа я создал простой плагин, чтобы проиллюстрировать проблему с помощью легко читаемого кода.

 <?php # -*- coding: utf-8 -*- /* Plugin Name: Anonymous OOP Action */ if ( ! class_exists( 'Anonymous_Object' ) ) { /** * Add some actions with randomized global identifiers. */ class Anonymous_Object { public function __construct() { add_action( 'wp_footer', array ( $this, 'print_message_1' ), 5 ); add_action( 'wp_footer', array ( $this, 'print_message_2' ), 5 ); add_action( 'wp_footer', array ( $this, 'print_message_3' ), 12 ); } public function print_message_1() { print '<p>Kill me!</p>'; } public function print_message_2() { print '<p>Me too!</p>'; } public function print_message_3() { print '<p>Aaaand me!</p>'; } } // Good luck finding me! new Anonymous_Object; } 

Теперь мы видим следующее:

введите описание изображения здесь

WordPress требуется имя для фильтра. Мы не предоставили один, поэтому WordPress вызывает _wp_filter_build_unique_id() и создает его. Это имя не предсказуемо, потому что оно использует spl_object_hash() .

Если мы запустим var_export() в $GLOBALS['wp_filter'][ 'wp_footer' ] мы получим что-то вроде этого сейчас:

 array ( 5 => array ( '000000002296220e0000000013735e2bprint_message_1' => array ( 'function' => array ( 0 => Anonymous_Object::__set_state(array( )), 1 => 'print_message_1', ), 'accepted_args' => 1, ), '000000002296220e0000000013735e2bprint_message_2' => array ( 'function' => array ( 0 => Anonymous_Object::__set_state(array( )), 1 => 'print_message_2', ), 'accepted_args' => 1, ), ), 12 => array ( '000000002296220e0000000013735e2bprint_message_3' => array ( 'function' => array ( 0 => Anonymous_Object::__set_state(array( )), 1 => 'print_message_3', ), 'accepted_args' => 1, ), ), 20 => array ( 'wp_print_footer_scripts' => array ( 'function' => 'wp_print_footer_scripts', 'accepted_args' => 1, ), ), 1000 => array ( 'wp_admin_bar_render' => array ( 'function' => 'wp_admin_bar_render', 'accepted_args' => 1, ), ), ) 

Чтобы найти и удалить наше действие зла, нам нужно пройти через связанные фильтры для крюка (действие – это очень простой фильтр), проверьте, является ли он массивом, и если объект является экземпляром класса. Затем мы берем приоритет и удаляем фильтр, не видя реального идентификатора .

Хорошо, давайте введем это в функцию:

 if ( ! function_exists( 'remove_anonymous_object_filter' ) ) { /** * Remove an anonymous object filter. * * @param string $tag Hook name. * @param string $class Class name * @param string $method Method name * @return void */ function remove_anonymous_object_filter( $tag, $class, $method ) { $filters = $GLOBALS['wp_filter'][ $tag ]; if ( empty ( $filters ) ) { return; } foreach ( $filters as $priority => $filter ) { foreach ( $filter as $identifier => $function ) { if ( is_array( $function) and is_a( $function['function'][0], $class ) and $method === $function['function'][1] ) { remove_filter( $tag, array ( $function['function'][0], $method ), $priority ); } } } } } 

Когда мы называем эту функцию? Невозможно точно знать, когда будет создан исходный объект. Может быть, иногда перед 'plugins_loaded' ? Может быть позже?

Мы используем тот же самый крючок, с которым связан объект, и прыгаем очень рано с приоритетом 0 . Это единственный способ быть уверенным. Вот как мы удалим метод print_message_3() :

 add_action( 'wp_footer', 'kill_anonymous_example', 0 ); function kill_anonymous_example() { remove_anonymous_object_filter( 'wp_footer', 'Anonymous_Object', 'print_message_3' ); } 

Результат:

введите описание изображения здесь

И это должно удалить действие из вашего вопроса (не тестировалось):

 add_action( 'comments_array', 'kill_FbComments', 0 ); function kill_FbComments() { remove_anonymous_object_filter( 'comments_array', 'SEOFacebookComments', 'FbComments' ); } 

Вывод

  • Всегда пишите предсказуемый код. Установите читаемые имена для ваших фильтров и действий. Удалите любой крючок.
  • Создайте свой объект на предсказуемом действии, например, на 'plugins_loaded' . Не только когда ваш плагин вызывается WordPress.

Я не уверен, но вы можете попробовать использовать синглтон.
Вы должны сохранить ссылку на объект в статическом свойстве своего класса, а затем вернуть статическую переменную из статического метода. Что-то вроде этого:

 class MyClass{ private static $ref; function MyClass(){ $ref = &$this; } public static function getReference(){ return self::$ref; } } 

Пока вы знаете объект (и вы используете PHP 5.2 или выше – текущая стабильная версия PHP – 5.5, 5.4 по-прежнему поддерживается, 5.3 – конец жизни), вы можете просто удалить ее с помощью remove_filter() . Все, что вам нужно запомнить, это объект, имя метода и приоритет (если используется):

 remove_filter('comment_array', [$this, 'FbComments']); 

Однако вы делаете небольшую ошибку в своем коде. Не префикс $this с амперсандом & , который был необходим в PHP 4 (!), И он давно просрочен. Это может сделать проблемы с вашими крючками проблематичными, поэтому просто не используйте это:

 add_filter('comments_array', [$this, 'FbComments])); 

Вот и все.