Есть ли предел для перехвата приоритета?

9

Когда я хочу, чтобы мой фильтр или ловушка действий переопределяли все остальные, я назначаю ему приоритет 999. Однако в последнее время я вижу, что некоторые люди используют экстремальные значения для приоритета, такие как 20000, и даже99999

Помимо того, что использование таких высоких приоритетов смешно, будут ли они работать на самом деле? Есть ли предел для перехвата приоритета? Что произойдет, если предел будет превышен? Есть ли разница в производительности при использовании экстремальных приоритетов?

Обновление: @harke предлагает при переполнении стека число ограниченоPHP_INT_MAX

карите
источник
Вы не связались с Ответом @hakre, который говорил об этом? Это должно быть частью Q, и более того, следуйте указаниям, которые он дал, я подозреваю, что он серьезно знает одну или две вещи ...
brasofilo
На какой ответ вы ссылаетесь?
She

Ответы:

13

Там нет ограничений и никаких штрафов за производительность. Чтобы понять почему, вам нужно понять, как все хуки хранятся в экосистеме WP.

Прежде всего вам необходимо понять, где хранятся все хуки и как они это делают. Все хуки для фильтров и действий хранятся в глобальной переменной с именем wp_filterда, хуки действий тоже хранятся в этой переменной. Эта переменная представляет собой связанный массив, где ключ - это имя действия или фильтра, а значение - другой ассоциативный массив. Например, давайте посмотрим на действие 'init', на этом этапе мы увидим следующую структуру:

$wp_filter = array(
    'init' => array(...),
);

Этот подмассив имеет числовые ключи и значения в виде массивов. Цифровые клавиши являются нашими приоритетами. Массивы, связанные с числовыми ключами, содержат список хуков с одинаковым приоритетом. Так что если мы позвоним add_action( 'init', 'wpse8170_my_first_init', 20 ), то позвоним add_action( 'init', 'wpse8170_my_second_init', 20 )и наконец позвоним add_action( 'init', 'wpse8170_my_third_init', 10 ), наш пример будет выглядеть так:

$wp_filter = array(
    'init' => array(
        20 => array(
            'wpse8170_my_first_init' => array(
                'accepted_args' => 1, // the number of accepted arguments by your hook
                'function' => 'wpse8170_my_first_init', // callback function
            ),
            'wpse8170_my_second_init' => array(...),
        ),
        10 => array(
            'wpse8170_my_third_init' => array(...),
        ),
    ),
);

Теперь, когда initдействие запущено, все хуки будут отсортированы с использованием ksortфункции, и наш массив теперь выглядит так:

    array(
        10 => array(
            'wpse8170_my_third_init' => array(...),
        ),
        20 => array(
            'wpse8170_my_first_init' => array(
                'accepted_args' => 1, // the number of accepted arguments by your hook
                'function' => 'wpse8170_my_first_init', // callback function
            ),
            'wpse8170_my_second_init' => array(...),
        ),
    ),

И все хуки будут выполняться в этой очереди: сначала 'wpse8170_my_third_init', потом 'wpse8170_my_first_init'и наконец 'wpse8170_my_second_init'.

Таким образом, вы можете видеть, что нет никаких ограничений и штрафов, и вы можете использовать любое значение, которое приемлемо в качестве ключа для связанного массива вашей средой PHP.

Евгений Мануйлов
источник
2
max( $priorities ) + 1потерпит неудачу, если последний номер равен PHP_INT_MAX. В этом случае вы должны преобразовать значение в строку и добавить что-то к ней.
Fuxia
@ toscho Да, согласен. Обновлен бонусный фрагмент.
Евгений Мануйлов
2
«Бонус» - плохая идея, если определение $wp_filterнавсегда изменится. Он не предназначен для использования непосредственно плагинами. Мы делали модификации в прошлом (в первую очередь по соображениям производительности, кстати).
Эндрю Нацин
@AndrewNacin хорошо, я удалил его, так как это вызывает слишком много вопросов :)
Евгений Мануйлов
6

Это целое число, поэтому в 32-битной системе PHP оно будет ограничено от -2147483648 до 2147483647, а в 64-битной версии PHP оно будет ограничено от -9223372036854775808 до 9223372036854775807.

Изменить: без потери производительности, это целое число.

Но серьезно? :)

webaware
источник
Я понял, что это целое число, но я говорил о реальном механизме хука. Я слышал, как люди говорят, что слишком большой хук вызовет полный провал хука, и обратный вызов не будет выполнен
shea
ВОЗ? Когда? Это просто индекс в массив, и при этом разреженный массив, так что влияние незначительно. Но, честно говоря, большие числа в значительной степени являются показателем непонимания проблемы (например, яростно пытаюсь кроваво что-нибудь, что может сработать!)
webaware
1

@shea - действия WordPress работают именно так, как вы предполагали. Показатель с более высоким приоритетом НЕ будет переопределять другие, и использование PHP_INT_MAX НЕ является какой-то «экстремальной» попыткой принудительно запустить это действие / фильтр перед любыми другими.

Чтобы поместить ваше действие / фильтр в ТОП ордера выполнения, вам нужно использовать приоритет 0.

PHP_INT_MAX просто на противоположном конце; он используется, когда вы хотите, чтобы ваше действие / фильтр запускалось ПОСЛЕ того, как все остальные (нормальные приоритеты) ловушки завершены.

Энди Шмидт
источник
1
Да, это именно та идея. Последний фильтр, который запускается на крючке, сможет изменять переменную, не беспокоясь о каких-либо дальнейших изменениях
shea
Можно также использовать отрицательные целочисленные значения $priority, поэтому обратные вызовы, перехваченные с приоритетом 0, не обязательно будут в верхней части порядка выполнения.
Дейв Ромси,
0

Нет ограничений и нет штрафа за производительность. Из проверки кода вы даже можете использовать строки в качестве приоритетов, хотя я бы не рекомендовал делать это;)

Если ваше действие должно быть последним, то вы можете проверить назначенные приоритеты, просматривая индексы глобала, $wp_actions[your hook]когда вызывается ваше действие, и добавлять его снова с более высоким приоритетом, если это необходимо, но я не вижу причины для такого рода действий вещей.

Марк Каплун
источник
0

Здесь практически нет ограничений, так как хуки фактически хранятся в виде массивов, а приоритет - числовой индекс.

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

Итак, я полагаю, что установка смехотворно большого числа приоритета - который просто переводится в числовой индекс в массиве, где хранятся перехваченные функции - не должна приводить к падению wordpress.

WP Темы
источник