Jak wycofać funkcję używaną we wtyczce?

17

Jedną z funkcji, których używam w mojej wtyczce, jest zanieczyszczenie zasięgu globalnego nazwą, która może kolidować z inną funkcją (używaną w innej wtyczce). Więc chyba powinienem to zrobić. Ale jak mam to zrobić?

function foo() {
    echo 'bar';
}

Jestem tego świadomy, _deprecate_function()ale byłbym wdzięczny za przykład pokazujący wszystkie kroki, które powinienem podjąć, aby usunąć funkcję z rdzenia mojej wtyczki.

Patrz: https://developer.wordpress.org/reference/functions/_deprecated_function/

henrywright
źródło
Dobre pytanie, ale czy może nadszedł czas na nazwanie wtyczki? Nadal możesz wywoływać nową przestrzeń nazw z przestarzałej funkcji ...
brianlmerritt
Przestrzeń nazw to opcja, którą chcę zbadać, ale nie do końca zdecydowałem, czy mam zrezygnować z obsługi PHP 5.2.
henrywright
Ładowanie przestarzałej alternatywy, jeśli wersja php jest zbyt niska, ale w przeciwnym razie przestrzeń nazw może dać ścieżkę przejścia. Twoja przestarzała wiadomość może wtedy brzmieć: „Twój dostawca hostingu nie obsługuje PHP 5.3+ bla bla itp”
brianlmerritt

Odpowiedzi:

11

Oprócz odpowiedzi @Welcher:

Istnieje kilka dobrych „ cmentarnych ” przykładów w rdzeniu, w których „ funkcje umierają ”.

Możesz wykorzystać je jako wytyczne, np. Dotyczące dokumentacji.

Oto jeden taki przykład dla permalink_link()podwp-includes/deprecated.php

/**
 * Print the permalink of the current post in the loop.
 *
 * @since 0.71
 * @deprecated 1.2.0 Use the_permalink()
 * @see the_permalink()
 */
function permalink_link() {
        _deprecated_function( __FUNCTION__, '1.2', 'the_permalink()' );
        the_permalink();
}

Oto wbudowana dokumentacja _deprecated_functionfunkcji wyjaśniająca argumenty wejściowe:

/**
 * Mark a function as deprecated and inform when it has been used.
 *
 * There is a hook deprecated_function_run that will be called that can be used
 * to get the backtrace up to what file and function called the deprecated
 * function.
 *
 * The current behavior is to trigger a user error if WP_DEBUG is true.
 *
 * This function is to be used in every function that is deprecated.
 *
 * @since 2.5.0
 * @access private
 *
 * @param string $function    The function that was called.
 * @param string $version     The version of WordPress that deprecated the function.
 * @param string $replacement Optional. The function that should have been called. 
 *                            Default null.
 */
birgire
źródło
1
Dzięki za to. Nie pomyślałem o podejściu rdzenia! Więc zakładam, że są to kroki, które muszę podjąć? 1) usuń całą oryginalną treść z mojej funkcji 2) dodaj wywołanie do _deprecated_function()3) dodaj wywołanie do mojej nowej funkcji, która zastępuje starą
henrywright
1
To brzmi jak omawiany tutaj problem dwustronny - wycofanie i możliwe kolizje nazw. Zajmowałem się tylko pierwszą częścią tutaj, zgodnie z tytułem pytania.
birgire,
1
@MarkKaplun Zgadzam się, że istnieją 2 problemy. Pytanie brzmiało, jak przestać działać i na tym opierała się moja odpowiedź. Zawiadomienie __doing_it_wrong jest przeznaczone dla programistów, którzy wywołują tę metodę w swoich motywach itp., Aby umożliwić im reagowanie na zmiany w interfejsie API, a nie tylko na białe ekranowanie witryny. Log Deprecated Notices to świetna wtyczka dla programistów, która pozwala być na bieżąco z najważniejszymi zmianami i pomogłaby również w tym przypadku.
Welcher
1
@MarkKaplun Rozumiem twój punkt widzenia. Argumentowałbym jednak, że częścią zaniechania jest utrzymanie zgodności wstecznej, dopóki element nie zostanie usunięty z interfejsu API. Celem powiadomienia (bez względu na to, która metoda zostanie użyta do jego wygenerowania) jest poinformowanie programistów korzystających z tej metody, że zostanie ona usunięta, i dać im czas na podjęcie odpowiednich działań. Sposobem na wycofanie czegoś jest zaznaczenie go i usunięcie, właściwym sposobem jest powiadomienie użytkowników jako pierwszy :)
Welcher
2
@MarkKaplun Nie jestem pewien, o co się kłócisz (lub za?). Pytanie brzmiało, jak wycofać metodę, i jest jasne, że PO mówi „moja wtyczka” wie, co oznacza, że ​​wycofanie oznacza, że ​​jest programistą. Wyimaginowany użytkownik, o którym mówisz, nie ma nic wspólnego z tym konkretnym pytaniem. Jeśli obawiasz się, że w dzienniku pojawi się milion powiadomień, omawiane metody będą generowane tylko wtedy, gdy WP_DEBUG jest włączone, a na twoim miejscu nie byłoby to możliwe przez programistów, a na pewno nie w produkcji. Z szacunkiem zamierzam po prostu nie zgodzić się na ruch :)
Welcher
7

Usunięcie wycofania nie zawsze jest równoznaczne z usunięciem, zwykle oznacza to, że element jest oznaczony do WYDARZENIA z API. Czy jest to metoda, która zostanie wywołana zewnętrznie - tak jak w przypadku innych wtyczek lub programistów? Jeśli ta metoda jest używana tylko przez wtyczkę wewnętrznie, prawdopodobnie możesz bezpiecznie usunąć zastąpić ją lepszą funkcją nazwy.

Jeśli nie, utworzę funkcję o lepszej nazwie, a źle nazwane wywołanie wywoła __doing_it_wrongją - przeczytaj o tym w kodeksie. Daje to innym programistom czas na aktualizację odniesień do metody i możesz bezpiecznie usunąć metodę w późniejsza wersja.

function badly_named() {

    __doing_it_wrong( 'badly_named', 'This method has been deprecated in favor of better_named_function' );

    /**
     * Call the better named method
     */
     better_named_function();
}

Mam nadzieję że to pomoże!

Welcher
źródło
Dzięki za to, ale myślę, że powinienem skopiować, jak to robi rdzeń. Na przykład spójrz na odpowiedź @birgire
henrywright
Brzmi dobrze dla mnie :)
Welcher
1

Tworzysz nową wtyczkę i doradzasz użytkownikom migrację do niej, ponieważ bieżąca to EOL.

Nie ma nic bardziej irytującego niż autorzy wtyczek i motywów zmieniający swoje publiczne interfejsy API i starający się traktować to jako „kolejną małą aktualizację”. Nie ma powodu, aby niszczyć witryny z powodu problemu, na który faktycznie nie mają wpływu użytkownicy.

Mark Kaplun
źródło
Byłoby to całkowicie dotknięte przez moich użytkowników, jeśli inna wtyczka ma funkcję o dokładnie takiej samej nazwie (i nie używa przestrzeni nazw).
henrywright
Nie, aktywacja wtyczki zakończy się niepowodzeniem i będą składać skargi do Ciebie lub autora innej wtyczki. Całkowity czas zakłócenia około zera. Jeśli potrzebują obu wtyczek, aktualizacja do nowej nie powinna zająć więcej niż 15 minut bez zakłóceń w funkcjonowaniu strony. Chcesz, aby niektórzy z Twoich użytkowników dokonali aktualizacji i odkryli, że niektóre funkcje nie działają już bez powiadomienia. Czas to naprawić? czy uważasz, że w ogóle mają kopię zapasową i mogą to naprawić?
Mark Kaplun,
Po utworzeniu interfejsu API musisz obsługiwać go przez cały czas, a przynajmniej dopóki nie będzie to całkowicie bez znaczenia, na przykład Wordpress nie usunął żadnego przestarzałego interfejsu API od wersji 3.4, a samo dodanie powiadomienia nic ci nie da.
Mark Kaplun,
1
+1, ponieważ szanuję twoją opinię i podoba mi się ta strona, to różne poglądy, podejścia i rozwiązania problemów, ponieważ zwykle nie ma jednego rozmiaru, który byłby odpowiedni dla wszystkich.
birgire,
1

Sugerowałbym coś takiego:

/**
 * @deprecated Please use good_function_name() instead
 * @since x.y.z Marked deprecated in favor of good_function_name()
 * @see good_function_name()
 */
function bad_function_name() {
    trigger_error(
        'The ' . __FUNCTION__ . ' function is deprecated. ' .
        'Please use good_function_name() instead.',
        defined( 'E_USER_DEPRECATED' ) ? E_USER_DEPRECATED : E_USER_WARNING
    );

    return good_function_name();
}

Powoduje to wyświetlenie w dziennikach ostrzeżenia o wycofaniu oraz śledzenia stosu. Oczywiście będzie to działać tylko wtedy, gdy w WordPress jest włączone rejestrowanie.

Operator trójskładnikowy istnieje, ponieważ stała E_USER_DEPRECATED została wprowadzona tylko w PHP 5.3.0. W starszych wersjach możemy zamiast tego wrócić do prostego ostrzeżenia użytkownika.

Z podręcznika PHP o stałych błędów :

E_DEPRECATED Powiadomienia o czasie wykonywania. Włącz tę opcję, aby otrzymywać ostrzeżenia o kodzie, który nie będzie działał w przyszłych wersjach.

Powodem, dla którego nie lubię używać _doing_it_wrong lub __deprecated_function jest to, że te funkcje są przeznaczone tylko dla rdzenia WordPress. Z odwołania do kodu na temat tych funkcji:

Dostęp do tej funkcji jest oznaczony jako prywatny. Oznacza to, że nie jest przeznaczony do użytku przez twórców wtyczek lub motywów, a jedynie do innych podstawowych funkcji. Podano tutaj kompletność.

alexg
źródło
1
To całkowicie ważny punkt +1 - możemy jednak zauważyć, że wtyczki takie jak Woocommerce używają obu funkcji . bez względu.
birgire,