Чи існує обмеження на пріоритет?


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.

Редагувати: без штрафу за ефективність, це ціле число.

Але ... серйозно? :)


Я розумію, що це ціле число, але я говорив про власне механізм гака. Я чув, як люди кажуть, що занадто великий гачок призведе до повного виходу гачка, і зворотний виклик не буде виконаний
she

ВООЗ? Коли? Це просто індекс в масив і рідкий масив при цьому, тому вплив є незначним. Але якщо чесно, великі цифри - це в значній
мірі

2

@shea - Дії WordPress працюють саме так, як ви припустили. Цифра з більш високим пріоритетом НЕ переможе інших, а використання PHP_INT_MAX НЕ є якоюсь "крайньою" спробою змусити цю дію / фільтр виконуватись перед будь-якими іншими.

Щоб поставити свою дію / фільтр у ТОП наказу про виконання, вам потрібно буде використовувати пріоритет 0.

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


1
Так, саме така ідея. Заключний фільтр, який працює на гачку, зможе змінити змінну, не турбуючись про будь-які подальші зміни
ши

Негативні цілі значення також можуть бути використані для $priority, тому зворотні виклики, пов'язані з пріоритетом 0, не обов'язково опинятимуться у верхній частині наказу про виконання.
Дейв Ромсі

0

Немає обмежень і не існує штрафу за виконання. Перевіряючи код, ви навіть можете використовувати рядки як пріоритетні, хоча я б не рекомендував це робити;)

Якщо ваша дія повинна бути останньою, ви можете оглянути призначені пріоритети, переглянувши індекси глобальної, $wp_actions[your hook]коли ваша дія викликається, і додайте її знову з більш високим пріоритетом, якщо це потрібно, але я не бачу причини для насправді такого роду речей.


0

Існує "практично" немає обмеження, оскільки гачки фактично зберігаються як масиви, а пріоритет - числовий показник.

Але насправді розмір масиву буде обмежений обсягом пам'яті, виділеної на виконання сценарію.

Тож, я думаю, встановлення смішно великого номера пріоритету - що просто перекладається на числовий індекс у масиві, де зберігаються зачеплені функції - не повинно збивати wordpress.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.