{"id":233871,"date":"2023-02-24T10:06:00","date_gmt":"2023-02-24T07:06:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233871"},"modified":"2022-11-11T12:54:53","modified_gmt":"2022-11-11T09:54:53","slug":"jak-zaimplementowac-autoloader-z-przestrzeniami-nazw-w-motywie-lub-wtyczce-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/jak-zaimplementowac-autoloader-z-przestrzeniami-nazw-w-motywie-lub-wtyczce-wordpress\/","title":{"rendered":"Jak zaimplementowa\u0107 Autoloader z przestrzeniami nazw w motywie lub wtyczce WordPress?"},"content":{"rendered":"\n<p>Je\u015bli piszesz kod obiektowy, autoloader jest konieczno\u015bci\u0105. Bez autoloadera musia\u0142by\u015b doda\u0107 lini\u0119 z do\u0142\u0105czonym plikiem klasy, zanim b\u0119dziesz m\u00f3g\u0142 go zainicjowa\u0107. Mo\u017ce to szybko sta\u0107 si\u0119 uci\u0105\u017cliwe, gdy pracujesz z wieloma klasami. Autoloader to funkcja, kt\u00f3ra uruchamia si\u0119 za ka\u017cdym razem, gdy instancja nowej klasy jest tworzona i zawiera plik klasy, zanim nast\u0105pi instancja.<\/p>\n<p>Przestrzenie nazw to spos\u00f3b strukturyzacji i hermetyzacji kodu, kt\u00f3ry pomaga unikn\u0105\u0107 kolizji nazw. Je\u015bli zamierzasz pisa\u0107 OOP, zaleca si\u0119 r\u00f3wnie\u017c u\u017cywanie przestrzeni nazw. Pami\u0119taj, \u017ce mo\u017cesz zaimplementowa\u0107 autoloader bez u\u017cywania przestrzeni nazw w kodzie OOP.<\/p>\n<p>Mo\u017cesz u\u017cy\u0107 tego kodu do motywu lub wtyczki WordPress lub dowolnego kodu PHP poza WordPress \u2013 po prostu odpowiednio zmodyfikuj \u015bcie\u017cki. W tym przyk\u0142adzie tworz\u0119 autoloader dla motywu WordPress.<\/p>\n<h2>Zasady dotycz\u0105ce przestrzeni nazw i struktury klas<\/h2>\n<p>Wdro\u017cenie autoloadera wymaga\u0142oby pewnych zdefiniowanych regu\u0142 dla struktury kodu i tego, gdzie je znale\u017a\u0107. Korzystanie z przestrzeni nazw upraszcza to nieco, poniewa\u017c przestrze\u0144 nazw mo\u017ce odnosi\u0107 si\u0119 do folderu, w kt\u00f3rym znajduj\u0105 si\u0119 klasy.<\/p>\n<p>Najpierw podejmij decyzj\u0119, jaka powinna by\u0107 nazwana twoja przestrze\u0144 nazw. Zwykle jest to co\u015b unikalnego dla twojego kodu, na przyk\u0142ad nazwa motywu. Na przyk\u0142ad przestrze\u0144 nazw dla motywu tej witryny to <code>AWhitePixelTheme<\/code>. Oznacza to, \u017ce aby autoloader dzia\u0142a\u0142, wszystkie klasy musz\u0105 znajdowa\u0107 si\u0119 w tej przestrzeni nazw.<\/p>\n<pre><code>namespace AWhitePixelTheme;<\/code><\/pre>\n<p>Moj\u0105 pierwsz\u0105 zasad\u0105 jest to, \u017ce ka\u017cdy plik klasy b\u0119dzie zawsze zawiera\u0142 tylko jedn\u0105 klas\u0119, a nazwa klasy musi by\u0107 taka sama jak nazwa pliku. Na przyk\u0142ad; klasa <code>MyTest<\/code>musi by\u0107 zdefiniowana w pliku <code>MyTest.php<\/code>.<\/p>\n<p>Moja druga zasada to struktura klas w folderach. Postanawiam, \u017ce wszystkie zaj\u0119cia znajduj\u0105 si\u0119 w folderze <code>src<\/code>w moim motywie. Mog\u0119 umie\u015bci\u0107 pliki klas bezpo\u015brednio w tym folderze, a do tego musz\u0105 one znajdowa\u0107 si\u0119 w zdefiniowanej powy\u017cej przestrzeni nazw \u201eroot&quot;. Ale je\u015bli chc\u0119 tworzy\u0107 podfoldery i umieszcza\u0107 w nich pliki klas, ich przestrzenie nazw musz\u0105 zawiera\u0107 struktur\u0119 folder\u00f3w. Na przyk\u0142ad klasa plik <code>MyTest.php<\/code>, kt\u00f3ry znajduje si\u0119 w folderze <code>src\/Test\/<\/code>, musi mie\u0107 zdefiniowan\u0105 t\u0119 przestrze\u0144 nazw:<\/p>\n<pre><code>namespace AWhitePixelThemeTest;<\/code><\/pre>\n<h2>Tworzenie autoloadera<\/h2>\n<p>Lubi\u0119 przechowywa\u0107 autoloader w osobnym pliku i poza <code>src\/<\/code>folderem, kt\u00f3ry jest zdefiniowany tylko dla plik\u00f3w klas w przestrzeni nazw. Jako przyk\u0142ad utworz\u0119 plik <code>autoloader.php<\/code>w folderze <code>inc\/<\/code>w moim motywie.<\/p>\n<p>PHP ma wbudowan\u0105 funkcj\u0119 autoloadera: <a href=\"https:\/\/www.php.net\/manual\/en\/function.spl-autoload-register.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">spl_autoload_register<\/a>. Podajesz nazw\u0119 swojej funkcji autoloadera jako parametr, aw tej funkcji otrzymujesz \u017c\u0105dan\u0105 klas\u0119 jako argument (to, co <code>new<\/code>wstawiasz podczas tworzenia instancji klasy). Podczas tworzenia instancji klas z przestrzeniami nazw, np <code>new AWhitePixelThemeTestMyTest()<\/code>., dostarczon\u0105 zmienn\u0105 do tej funkcji b\u0119dzie <code>\"AWhitePixelThemeTestMyTest\"<\/code>.<\/p>\n<p>Dodajmy funkcj\u0119 autoloadera, a w niej zdefiniujemy wymagan\u0105 przestrze\u0144 nazw dla autoloadera:<\/p>\n<pre><code>&lt;?php\nspl_autoload_register('awhitepixel_autoloader');\nfunction awhitepixel_autoloader($class) {\n    $namespace = 'AWhitePixelTheme';\n\u00a0\n}<\/code><\/pre>\n<p>Nast\u0119pnie musimy do\u0142\u0105czy\u0107 ten plik, aby nasz autoloader zosta\u0142 zarejestrowany. Poniewa\u017c jest to w motywie, dodam uwzgl\u0119dnienie w motywie <code>functions.php<\/code>. Je\u015bli u\u017cywasz tego dla wtyczki, umie\u015b\u0107 go w plikach wtyczki. Plik autoloadera musi zosta\u0107 dodany wcze\u015bniej, przed utworzeniem instancji klas. Umieszczam to w pierwszym wierszu mojego <code>functions.php<\/code>:<\/p>\n<pre><code>require_once(get_template_directory(). '\/inc\/autoloader.php');<\/code><\/pre>\n<p>Je\u015bli u\u017cywasz go do motywu potomnego lub wtyczki, zmodyfikuj \u015bcie\u017ck\u0119 do swoich potrzeb.<\/p>\n<p>I to wszystko. Teraz automat \u0142aduj\u0105cy jest na miejscu, ale nic nie robi. Wr\u00f3\u0107my do funkcji autoloadera i zako\u0144czmy j\u0105.<\/p>\n<h2>Pisanie i testowanie funkcji autoloadera<\/h2>\n<p>Najpierw musimy upewni\u0107 si\u0119, \u017ce \u017c\u0105dana nazwa klasy faktycznie znajduje si\u0119 w naszej przestrzeni nazw. Po prostu sprawdzamy, czy podana nazwa klasy przestrzeni nazw zawiera ci\u0105g przestrzeni nazw, a je\u015bli nie, wychodzimy z funkcji. Nast\u0119pnie usuwamy nazw\u0119 przestrzeni nazw z ci\u0105gu, dzi\u0119ki czemu mo\u017cemy opracowa\u0107 dowolne podfoldery i plik klasy.<\/p>\n<pre><code>&lt;?php\nspl_autoload_register('awhitepixel_autoloader');\nfunction awhitepixel_autoloader($class) {\n    $namespace_name = 'AWhitePixelTheme';\n\u00a0\n    if (strpos($class, $namespace) !== 0) {\n        return;\n    }\n    $class = str_replace($namespace, '', $class);\n}<\/code><\/pre>\n<p>Teraz przekszta\u0142cimy podan\u0105 przestrze\u0144 nazw w rzeczywist\u0105 \u015bcie\u017ck\u0119 do pliku. Najpierw zast\u0105pimy wszelkie odwrotne uko\u015bniki <code>\"\"<\/code>w przestrzeni nazw znakiem separatora folderu \u2013 do tego u\u017cywamy sta\u0142ej PHP <code>DIRECTORY_SEPARATOR<\/code>. Na samym ko\u0144cu dodajemy <code>\".php\"<\/code>. I na koniec przed napisem dodajemy pe\u0142n\u0105 \u015bcie\u017ck\u0119 g\u0142\u00f3wn\u0105. Poniewa\u017c jest to wewn\u0105trz motywu, u\u017cywam <code>get_template_directory()<\/code>. Je\u015bli u\u017cywasz tego dla wtyczki, u\u017cyj metody, kt\u00f3ra zwraca pe\u0142n\u0105 \u015bcie\u017ck\u0119 do wtyczki.<\/p>\n<pre><code>    ...\n    $class = str_replace($namespace, '', $class);\n\u00a0\n    $class = str_replace('', DIRECTORY_SEPARATOR, $class). '.php';\n    $directory = get_template_directory();\n    $path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;\n}<\/code><\/pre>\n<p>Wszystko, co musimy teraz zrobi\u0107, to sprawdzi\u0107, czy plik istnieje, a je\u015bli tak, za\u017c\u0105da\u0107 go.<\/p>\n<pre><code>    ...\n    $path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;\n\u00a0\n    if (file_exists($path)) {\n        require_once($path);\n    }\n}<\/code><\/pre>\n<p>Ot\u00f3\u017c \u200b\u200bto!<\/p>\n<p>Przetestujmy to. Utw\u00f3rz podfolder <code>Test<\/code>w folderze swojego motywu <code>src\/<\/code>, a wewn\u0105trz niego umie\u015b\u0107 plik php o nazwie <code>MyTest.php<\/code>. Zdefiniuj w nim klas\u0119 <code>MyTest<\/code>, przestrzegaj\u0105c zasad przestrzeni nazw: <code>AWhitePixelThemeTest<\/code>. Po prostu dodam wypis \u201eSukces&#8221; w funkcji konstrukcji, aby\u015bmy mogli \u0142atwo zobaczy\u0107, \u017ce faktycznie inicjuje ona klas\u0119.<\/p>\n<pre><code>&lt;?php\nnamespace AWhitePixelThemeTest;\n\u00a0\nclass MyTest {\n    public function __construct() {\n        var_dump('Success!');\n    }\n}<\/code><\/pre>\n<p>W naszym functions.php, po za\u017c\u0105daniu autoloadera, po prostu tworzymy instancj\u0119 klasy:<\/p>\n<pre><code>$test = new AWhitePixelThemeTestMyTest();<\/code><\/pre>\n<p>Od\u015bwie\u017c swoj\u0105 witryn\u0119 WordPress i zobacz, \u017ce otrzymujesz \u201eSukces!&#8221; wyprowadzane.<\/p>\n<p>Autoloader automatycznie \u0142aduje wszystkie pliki klas, kt\u00f3re znajduj\u0105 si\u0119 w naszej zdefiniowanej przestrzeni nazw, i post\u0119puje zgodnie z poprawnymi regu\u0142ami. Mo\u017cesz tworzy\u0107 wyst\u0105pienia klas z dowolnego miejsca w motywie, nawet w samych klasach.<\/p>\n<h2>Pe\u0142na funkcja automatycznego \u0142adowania<\/h2>\n<p>Dla por\u00f3wnania, oto nasza ostateczna funkcja automatycznego \u0142adowania:<\/p>\n<pre><code>spl_autoload_register('awhitepixel_autoloader');\nfunction awhitepixel_autoloader($class) {\n    $namespace = 'AWhitePixelTheme';\n\u00a0\n    if (strpos($class, $namespace) !== 0) {\n        return;\n    }\n\u00a0\n    $class = str_replace($namespace, '', $class);\n    $class = str_replace('', DIRECTORY_SEPARATOR, $class). '.php';\n\u00a0\n    $directory = get_template_directory();\n    $path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;\n\u00a0\n    if (file_exists($path)) {\n        require_once($path);\n    }\n}<\/code><\/pre>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Przewodnik, jak napisa\u0107 autoloader, kt\u00f3ry pozwala na przestrzenie nazw dla kodu obiektowego w motywie lub wtyczce WordPress.<\/p>\n","protected":false},"author":1,"featured_media":224072,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[897,721,721,919,897,919,1110,836,836,845,929,929,845,866,866],"tags":[1169],"class_list":{"0":"post-233871","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-kod","8":"category-deweloper","10":"category-inny","13":"category-n-a","14":"category-przewodnik-dla-poczatkujacych","16":"category-samouczki","17":"category-tematy","20":"category-wordpress-7","22":"tag-affiai-pl"},"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233871","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=233871"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233871\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/224072"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=233871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=233871"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=233871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}