DevTips – przestrzenie nazw w PHP

Opublikowany: 2020-03-06

Około rok temu WordPress zdecydował się zaktualizować wymaganą minimalną wersję PHP, z 5.2 (używanej od 2010 roku) do bardziej aktualnej. W rzeczywistości, dzisiaj minimalna wersja PHP zalecana przez WordPress to jedna z najnowszych: PHP 7.3.

Jeśli jesteś prostym użytkownikiem WordPressa, prawdopodobnie nie wpłynie to na ciebie zbytnio (poza tym, że te nowe wersje zapewniają lepszą wydajność).

Ale jeśli jesteś programistą, te nowe wersje PHP mają kilka niesamowitych funkcji, których możesz użyć w swoich wtyczkach i motywach. A dzisiaj, konkretnie, chciałbym porozmawiać o jednym, który jest z nami od dawna, ale: przestrzeniach nazw.

WordPress i prefiksy kodu

Jedną z pierwszych zasad, których uczysz się jako programista WordPress, jest „używanie przedrostków we wszystkim, co robimy”, aby uniknąć „kolizji nazw”. Jak możemy przeczytać w najlepszych praktykach WordPressa:

Kolizja nazw ma miejsce, gdy wtyczka używa tej samej nazwy dla zmiennej, funkcji lub klasy, co inna wtyczka.

[Aby uniknąć kolizji nazw], wszystkie zmienne, funkcje i klasy powinny być poprzedzone unikalnym identyfikatorem. Prefiksy uniemożliwiają innym wtyczkom nadpisanie twoich zmiennych i przypadkowe wywołanie twoich funkcji i klas. Uniemożliwi ci to również zrobienie tego samego.

Najlepsze praktyki tworzenia wtyczek WordPress

Tak więc, na przykład, zamiast tworzyć funkcję taką jak get_site_id , lepiej nazwać ją nelio_content_get_site_id . W ten sposób jesteśmy w stanie szybko zidentyfikować wtyczkę ( nelio_content ) lub motyw, do którego należy określona funkcja ( get_site_id ) i uniknąć krytycznych błędów, jeśli kilka wtyczek próbuje zdefiniować tę samą funkcję.

Używanie przedrostków to podstawowy sposób tworzenia „przestrzeni nazw”; obejście, które musieliśmy wdrożyć, gdy nie mieliśmy lepszej alternatywy. Wszystkie te elementy, które używają tego samego prefiksu, są częścią tego samego zestawu lub przestrzeni nazw. Powoduje to jednak niepotrzebnie bardziej złożony kod: nazwy są dłuższe z powodu prefiksów, które służą jedynie do emulacji przestrzeni nazw.

Przestrzenie nazw PHP

PHP w wersji 5.3 wprowadził pojęcie przestrzeni nazw . Definicja, którą podają w dokumentacji, wydaje mi się doskonała, więc odtwarzam ją tutaj:

W najszerszej definicji przestrzenie nazw to sposób na hermetyzację elementów. W wielu miejscach można to postrzegać jako abstrakcyjne pojęcie. Na przykład w dowolnym systemie operacyjnym katalogi służą do grupowania powiązanych plików i działają jako przestrzeń nazw dla plików w nich zawartych. Jako konkretny przykład, plik foo.txt może istnieć zarówno w katalogu /home/greg , jak iw /home/other , ale dwie kopie pliku foo.txt nie mogą współistnieć w tym samym katalogu.

W świecie PHP przestrzenie nazw mają na celu rozwiązanie dwóch problemów, które napotykają autorzy bibliotek i aplikacji podczas tworzenia elementów kodu wielokrotnego użytku, takich jak klasy lub funkcje:

1. Kolizje nazw między utworzonym przez Ciebie kodem a wewnętrznym kodem PHP lub kodem innej firmy.

2. Możliwość aliasowania (lub skracania) Extra_Long_Names , poprawiająca czytelność kodu źródłowego.

Dokumentacja PHP

Jak stworzyć przestrzeń nazw

Tworzenie przestrzeni nazw w PHP jest niezwykle proste. Na początku tworzonego pliku PHP dodaj dyrektywę namespace z nazwą, której chcesz użyć i „wszystko”, co zdefiniujesz w tym pliku, będzie należeć do tej przestrzeni nazw:

 <?php namespace Nelio_Content;

Tak, to takie proste! Teraz „wszystko”, co tam utworzymy, będzie znajdować się w przestrzeni nazw Nelio_Content . Na przykład, jeśli zdefiniuję funkcję taką jak ta, o której wspomniałem na początku:

 <?php namespace Nelio_Content; function get_site_id() { // ... }

teraz wiemy, że get_site_id znajduje się w przestrzeni nazw Nelio_Content . W ten sposób nie musimy już używać prefiksu nelio_content_ podczas definiowania funkcji. Świetnie!

Wyjątki od przestrzeni nazw

Jeśli przyjrzysz się uważnie temu, co ci powiedziałem do tej pory, zobaczysz, że pisałem „wszystko” w cudzysłowie: „'wszystko', co tam dodamy, będzie należało do określonej przestrzeni nazw”. Dlaczego to zrobiłem? Ponieważ przestrzenie nazw nie dotyczą absolutnie całego kodu, który piszemy… są pewne wyjątki.

Przestrzenie nazw PHP obejmują tylko następujące elementy PHP:

  • Klasy
  • Interfejsy
  • Cechy
  • Funkcje
  • Stałe zadeklarowane z const , ale nie z define

Ponadto istnieje kilka dodatkowych rzeczy w WordPressie, które również wymagają własnych przestrzeni nazw i niestety przestrzenie nazw PHP nie obejmują: uchwytów skryptów , opcji bazy danych lub niestandardowych typów treści i ich metadanych itp. We wszystkich tych przypadkach musisz kontynuuj używanie przedrostków.

Jak importować elementy z jednej przestrzeni nazw do innej?

Jeśli potrzebujesz użyć elementu, który znajduje się we własnej przestrzeni nazw, nie musisz robić nic specjalnego: po prostu nazwij go po nazwie. Na przykład w następującym fragmencie kodu:

 <?php namespace Nelio_Content; function get_site_id() { // ... } function get_auth_token() { $site_id = get_site_id(); // ... }

Widać, że zdefiniowaliśmy dwie funkcje: get_site_id i get_auth_token , obie w przestrzeni nazw Nelio_Content . Kiedy get_auth_token musi użyć get_site_id , po prostu wywołuje go jak zwykle.

Jeśli z drugiej strony musisz użyć get_site_id w innej przestrzeni nazw, musisz wywołać funkcję, używając jej pełnego identyfikatora:

 <?php namespace Something_Else; function do_some_action() { $site_id = Nelio_Content\get_site_id(); // ... }

lub musisz zaimportować funkcję ze słowem kluczowym use :

 <?php namespace Something_Else; use Nelio_Content\get_site_id; function do_some_action() { $site_id = get_site_id(); // ... }

Osobiście bardzo podoba mi się druga opcja: używając słowa kluczowego use do importowania funkcji z innych przestrzeni nazw, możesz szybko spojrzeć na nagłówek swojego pliku i zidentyfikować jego zależności.

Filtry i akcje WordPress z przestrzeniami nazw PHP

Jest ważny szczegół, o którym należy pamiętać podczas korzystania z przestrzeni nazw obok filtrów i działań WordPress. Kiedy określasz wywołania zwrotne filtra i akcji, zwykle robisz to, podając nazwę wywołania zwrotnego jako ciąg:

 <?php // ... add_action( 'init', 'do_some_action' );

Problem polega na tym, że jeśli ta funkcja znajduje się w przestrzeni nazw, poprzedni hak nie będzie działał zgodnie z oczekiwaniami; musisz podać WordPressowi pełną nazwę funkcji. Innymi słowy, musisz uwzględnić jego przestrzeń nazw (jeśli ją posiada).

Czy dodajesz hak w pliku, w którym definiujesz samą przestrzeń nazw? Nie ma znaczenia, użyj pełnego imienia i nazwiska:

 <?php namespace Nelio_Content; function do_some_action() { // ... } add_action( 'init', 'Nelio_Content\do_some_action' );

Czy jesteś w innej przestrzeni nazw, ale zaimportowałeś funkcję przy use ? To też nie ma znaczenia, użyj pełnej nazwy:

 <?php namespace Something_Else; use Nelio_Content\do_some_action; // ... add_action( 'init', 'Nelio_Content\do_some_action' );

Używanie aliasów z naszymi przestrzeniami nazw

Kolejną bardzo ciekawą funkcjonalnością przestrzeni nazw jest aliasing. Wyobraź sobie następujący scenariusz:

 <?php namespace Nelio_Content; function get_site_id() { // ... }

Jeśli chcę użyć tej funkcji w innej przestrzeni nazw, widzieliśmy już, że mogę to zrobić za pomocą use . Ale jak mam użyć tej funkcji, jeśli moduł, w którym chcę jej użyć, ma już funkcję o nazwie get_site_id ?

Cóż, na szczęście dla mnie możemy aliasować nasze importy pod nowymi nazwami:

 <?php namespace Something_Else; use Nelio_Content\get_site_id as get_nc_site_id(); function get_site_id() { // ... } function do_some_action() { $nc_site_idd = get_nc_site_id(); // ... }

Zacznij korzystać z przestrzeni nazw już dziś!

Przestrzenie nazw to fantastyczne narzędzie pozwalające uniknąć kolizji nazw i uporządkować nasz kod. W rzeczywistości, chociaż nie skomentowałem tego postu, istnieją standardy, takie jak PSR-4, które pozwalają PHP na automatyczne ładowanie klas w oparciu o strukturę używanych przestrzeni nazw i sposób organizowania kodu w katalogi i pliki.

Jeśli jeszcze nie używasz przestrzeni nazw w swoich projektach, zalecamy rozpoczęcie tego od teraz. Opowiedz nam o swoim doświadczeniu w komentarzach!

Polecane zdjęcie autorstwa Chaitanya Tvs na Unsplash.