Czy istnieje limit zaczepienia o priorytecie?

9

Kiedy chcę, aby mój filtr lub hak akcji zastąpił wszystkie inne, nadam mu priorytet 999. Jednak ostatnio widziałem, jak niektórzy ludzie używają ekstremalnych wartości dla priorytetu, takich jak 20000, a nawet99999

Czy fakt, że stosowanie priorytetów na tak wysokim poziomie jest absurdalny, czy faktycznie będą działać? Czy istnieje limit zaczepienia o priorytecie? Co się stanie, jeśli limit zostanie przekroczony? Czy występuje różnica w wydajności przy użyciu ekstremalnych priorytetów?

Aktualizacja: @harke sugeruje w przypadku przepełnienia stosu, że liczba jest ograniczonaPHP_INT_MAX

shea
źródło
Nie podałeś linku do odpowiedzi @hakre, która o tym mówiła? Powinien być częścią Q, a ponadto podążać za wskazówkami, które dał, podejrzewam, że poważnie wie jedną lub dwie rzeczy ...
brasofilo
Do jakiej odpowiedzi odnosisz się?
shea

Odpowiedzi:

13

Nie ma ograniczeń i kar za wyniki. Aby zrozumieć dlaczego, musisz zrozumieć, w jaki sposób wszystkie haki są przechowywane w ekosystemie WP.

Przede wszystkim musisz zrozumieć, gdzie są przechowywane wszystkie haki i jak to robią. Wszystkie haczyki dla filtrów i akcji są przechowywane w zmiennej globalnej o nazwie wp_filter, tak tak haki akcji są również przechowywane w tej zmiennej. Zmienna ta jest tablicą powiązaną, gdzie klucz jest nazwą akcji lub filtra, a wartość jest inną tablicą asocjacyjną. Na przykład spójrzmy na akcję „init”, na tym etapie zobaczymy następującą strukturę:

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

Ta podgrupa ma klucze numeryczne i wartości jako tablice. Klawisze numeryczne są naszymi priorytetami. Tablice powiązane z klawiszami numerycznymi zawierają listę haczyków o tym samym priorytecie. Więc jeśli zadzwonimy add_action( 'init', 'wpse8170_my_first_init', 20 ), a następnie zadzwonimy, add_action( 'init', 'wpse8170_my_second_init', 20 )a na końcu zadzwonimy add_action( 'init', 'wpse8170_my_third_init', 10 ), nasz przykład będzie wyglądał następująco:

$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(...),
        ),
    ),
);

Teraz po inituruchomieniu akcji wszystkie haki zostaną posortowane przy użyciu ksortfunkcji, a nasza tablica wygląda teraz:

    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(...),
        ),
    ),

Wszystkie haki zostaną wykonane w tej kolejce: najpierw 'wpse8170_my_third_init', potem 'wpse8170_my_first_init'i na końcu 'wpse8170_my_second_init'.

Możesz więc zobaczyć, że nie ma żadnych ograniczeń i kar, i możesz użyć dowolnej wartości, która jest akceptowana jako klucz do powiązanej tablicy przez twoje środowisko PHP.

Eugene Manuilov
źródło
2
max( $priorities ) + 1zawiedzie, jeśli ostatnia liczba jest równa PHP_INT_MAX. W takim przypadku musisz przekonwertować wartość na ciąg i dodać do niej coś.
fuxia
@toscho Tak, zgadzam się. Zaktualizowano fragment bonusowy.
Eugene Manuilov
2
„Bonus” to zły pomysł, na wypadek gdyby $wp_filterzmieniła się definicja wiecznych. Nie jest przeznaczony do bezpośredniego użycia przez wtyczki. Dokonaliśmy modyfikacji w przeszłości (nawiasem mówiąc, głównie ze względu na wydajność).
Andrew Nacin,
@AndrewNacin ok, usunąłem go, ponieważ powoduje zbyt wiele pytań :)
Eugene Manuilov
6

Jest to liczba całkowita, więc w 32-bitowym systemie PHP będzie ograniczony do -2147483648 do 2147483647, a w 64-bitowym PHP będzie ograniczony do -9223372036854775808 do 9223372036854775807.

Edycja: brak ograniczenia wydajności, jest to liczba całkowita.

Ale ... poważnie? :)

webaware
źródło
Rozumiem, że to liczba całkowita, ale mówiłem o rzeczywistym mechanizmie hakowym. Słyszałem, jak ludzie mówią, że zbyt duży hak spowoduje, że hak całkowicie się zawiedzie, a wywołanie zwrotne nie zostanie wykonane
shea
WHO? Kiedy? To tylko indeks do tablicy, a do tego rzadka tablica, więc wpływ jest znikomy. Ale szczerze mówiąc, duże liczby są raczej wskaźnikiem niezrozumienia problemu (np. Gorączkowe próbowanie cholernego wszystkiego, co mogłoby działać!)
webmaster
2

@shea - akcje WordPress działają dokładnie tak, jak zakładałeś. Liczba o wyższym priorytecie NIE zastąpi innych, a użycie PHP_INT_MAX NIE jest jakąś „ekstremalną” próbą wymuszenia działania tej akcji / filtra przed innymi.

Aby umieścić akcję / filtr na GÓRZE polecenia wykonania, musisz użyć priorytetu 0.

PHP_INT_MAX jest po prostu na drugim końcu; jest używany, gdy chcesz, aby akcja / filtr działał PO zakończeniu wszystkich innych haków (o priorytecie normalnym).

Andy Schmidt
źródło
1
Tak, to jest dokładnie pomysł. Ostateczny filtr uruchamiany na haku będzie mógł modyfikować zmienną bez obawy o dalsze zmiany
shea
Można również użyć ujemnych liczb całkowitych $priority, więc wywołania zwrotne z priorytetem 0niekoniecznie będą znajdować się na górze kolejności wykonywania.
Dave Romsey
0

Bez limitu i nie ma ograniczenia wydajności. Po sprawdzeniu kodu możesz nawet używać ciągów znaków jako priorytetów, chociaż nie poleciłbym tego;)

Jeśli twoja akcja musi być ostatnia, możesz sprawdzić przypisane pririties, patrząc na indeksy globalne, $wp_actions[your hook]gdy twoja akcja jest wywoływana, i dodaj ją ponownie z wyższym priorytetem, jeśli to konieczne, ale nie widzę powodu, dla którego tak naprawdę to robię od rzeczy.

Mark Kaplun
źródło
0

„Praktycznie” nie ma limitu, ponieważ haki są faktycznie przechowywane jako tablice, a priorytetem jest indeks liczbowy.

Ale w rzeczywistości rozmiar tablicy będzie ograniczony ilością pamięci przydzielonej do wykonania skryptu.

Tak więc myślę, że ustawienie absurdalnie dużej liczby priorytetowej - która po prostu przekłada się na indeks liczbowy w tablicy, w której przechowywane są przechwycone funkcje - nie powinno powodować awarii Wordpress.

Tematy WP
źródło