Namespaces gebruiken en Autoloading in WordPress-plug-ins, deel 4

Als dit de eerste zelfstudie is die u in deze serie leest, raad ik u aan een inhaalslag te maken met wat we tot nu toe hebben besproken.

In wezen kom je aan het einde van de show binnen. Op dit punt hebben we de basis gelegd voor onze plug-in, de plug-in geschreven en gedefinieerde en onderzochte naamruimten en autoloaders. Het enige dat overblijft, is toepassen wat we hebben geleerd.

Dus in deze tutorial gaan we alle stukjes samenvoegen. In het bijzonder gaan we de broncode van onze plug-in, naamruimte alle relevante klassen opnieuw bekijken en een autoloader schrijven zodat we al onze include-instructies kunnen verwijderen.

Ik zal alles in detail bespreken terwijl we de code doornemen. Nogmaals, als dit de eerste zelfstudie is die je in deze serie leest, inhaalslag met wat we tot nu toe hebben behandeld en keer dan terug naar deze tutorial.

Voordat we een code schrijven

Op dit punt moet u bekend zijn met hoe we onze ontwikkelomgeving hebben opgezet. Als een opfriscursus, hier is een kort overzicht van de software die we gebruiken:

  • ten minste PHP 5.6.20
  • de Apache-webserver
  • een MySQL-databaseserver
  • WordPress 4.6.1
  • een praktische kennis van de WordPress Plugin API

Je hebt ook een kopie nodig van de broncode van de plug-in waarmee we werken. Je kunt hier een kopie van krijgen. Ervan uitgaande dat het is geïnstalleerd, geactiveerd en je IDE wordt uitgevoerd, laten we aan de slag gaan.

Naamgeving van de code

Terugroepen van de vorige zelfstudie, ik ben er fan van om ervoor te zorgen dat onze naamruimten de organisatie van de bestanden op schijf volgen. Als je kijkt naar de directorystructuur van onze plug-in of als je de reeks tot nu toe gevolgd hebt, zou je zoiets als dit moeten zien:

Merk op dat als je je plug-in anders hebt ingesteld, dat prima is. Je naamruimten zullen waarschijnlijk anders zijn, maar dat mag niets veranderen aan de inhoud van deze reeks.

Gebruik de directorystructuur als leidraad en laten we alle PHP-bestanden die deel uitmaken van onze plug-in doorlopen en hun naamruimten definiëren. Dit doen is eenvoudig: het is gewoon een kwestie van het sleutelwoord namespace gebruiken en een gekwalificeerde naam bovenaan elk bestand plaatsen.

Ik zal ze hieronder allemaal opnoemen.

tutsplus-namespace-demo.php

class-meta-box.php

class-meta-box-display.php

-interface-assets.php

class-css-loader.php

class-vraag-reader.php

Er zijn een paar dingen om op te letten over de conventies die ik hierboven heb gebruikt:

  • De hoofdmapnaamruimte is Tutsplus_Namespace_Demo, die overeenkomt met de mapnaam van de plug-in.
  • De rest van de naamruimten zoals Tutsplus_Namespace_Demo \ Admin en Tutsplus_Namespace_Demo \ Admin \ Util komen ook overeen met hun respectievelijke mappen; de directorynamen zijn echter ingesloten (in tegenstelling tot in kleine letters).

Als u ten slotte hebt geprobeerd de pagina te verversen of u hebt geprobeerd om door WordPress te navigeren sinds u de naamruimte-instructies introduceerde, ziet u waarschijnlijk een fout in uw console die er ongeveer zo uitziet:

En het bevat de volgende boodschap:

PHP Waarschuwing: call_user_func_array () verwacht dat parameter 1 een geldige callback is, functie 'tutsplus_namespace_demo' niet gevonden of ongeldige functienaam in /Users/tommcfarlin/Dropbox/Projects/tutsplus/wp-includes/plugin.php on line 524

Of misschien laat het zien:

PHP Fatale fout: klasse 'Meta_Box' niet gevonden in /Users/tommcfarlin/Dropbox/Projects/tutsplus/wp-content/plugins/tutsplus-namespace-demo/tutsplus-namespace-demo.php on line 48

Of u ziet mogelijk een aantal andere soortgelijke foutmeldingen. Dat is goed. Het is normaal.

Maar het werpt de vraag op: hoe zit het met onze plug-in? Gelukkig niets. Dit is het verwachte gedrag.

Het eerste bericht dat je ziet mei het resultaat zijn van een andere plug-in die u hebt geïnstalleerd. Ik kon het niet zelfstandig reproduceren; wanneer ik echter een paar van de andere plug-ins die ik heb gedeactiveerd, genereert de plug-in het tweede bericht (dit is het bericht dat ik wilde laten zien).

Wanneer u de naamcode opgeeft, verwacht PHP een klasse binnen een bepaalde naamruimte te vinden. Conceptueel kun je denken aan je klassen die nu behoren tot hun eigen pakket (of subpakket) of hoe je het ook definieert. En om een ​​functie toegang te geven tot een klasse binnen een pakket, moet het bewust worden gemaakt van de pakketten die er zijn.

Dit is waar extra namespace-functionaliteit en autoloading in het spel komen. Dus voordat we proberen onze code te openen via hun naamruimten, laten we werken aan een autoloader.

Alles over Autoloading

Het schrijven van een autoloader vereist het volgende:

  1. het begrijpen van een PHP-functie genaamd spl_autoload_register
  2. een functie schrijven die onze namespaced-bestanden automatisch laadt
  3. inclusief onze aangepaste autoladerfunctie

Laat de naam niet spl_autoload_register intimideer je. Het betekent gewoon dat dit een functie is die deel uitmaakt van de "Standard PHP Library" en het is hoe we een "autoload" -functie "registreren". Het is een mondvol om te zeggen en veel karakters om te schrijven, maar het is gewoon een functie die we zullen gebruiken om PHP te vertellen hoe naamruimten en klassennamen moeten worden ontleed en waar het onze bestanden kan vinden.

Met deze functie kunnen we onze eigen aangepaste code schrijven voor het automatisch laden van bestanden en deze functie vervolgens koppelen aan PHP. Dat wil zeggen, we gaan PHP vertellen waar we onze bestanden kunnen vinden en hoe we naamruimten, bestandsnamen, enzovoort moeten analyseren, zodat het de bestanden zal bevatten.

Met dat alles gezegd, zijn we klaar om daadwerkelijk een autoloader te schrijven.

Een autoloader schrijven

Bij het schrijven van een autoloader is het zaak om in gedachten te houden hoe onze bestanden zijn georganiseerd. Dat wil zeggen, we willen weten hoe onze namespaces in onze mappen kunnen worden geplaatst. 

In het voorbeeld dat we gebruiken, is het eenvoudig: de naamruimten zijn cased-versies van de directorystructuur. Dit geldt niet altijd voor andere projecten; het is echter nog een andere reden waarom ik mijn bestanden graag logisch organiseer op basis van hun fysieke locatie.

Wanneer PHP een klasse probeert te laden, moet onze autoloader het volgende doen:

  1. Splits de naamruimte op basis van de slashes.
  2. Splits het pakket en de subpakketten op basis van onderstrepingstekens en vervang ze door streepjes (indien nodig).
  3. Weet hoe klasnamen, interfaces enzovoort aan bestandsnamen moeten worden toegewezen.
  4. Maak een tekenreeksrepresentatie van de bestandsnaam op basis van de bovenstaande informatie.
  5. Voeg het bestand toe.

Met al deze punten gemaakt, hebben we ons werk voor ons uitgesneden. Maak in de plugin-map een submap met de naam inc, en in de inc map maak een bestand aan met de naam autoload.php.

Binnen dat bestand laten we de functie die we gaan gebruiken om onze bestanden automatisch te laden, uitprinten. Het zou er ongeveer zo uit moeten zien:

Vanzelfsprekend doet dit nog niets.

Een kanttekening bij het schrijven van een autoloader

Merk op dat ik de code zal schrijven en opmerkingen zal coderen om grondig uit te leggen wat we aan het doen zijn. Als u zich hier voor het eerst alleen op toelegt, kan het schrijven van een autoloader en het gebruik van naamruimten en werken met bestanden een beetje frustrerend zijn. Dit is waar een debugger en logboekbestanden van pas kunnen komen. 

Dit valt buiten het bestek van deze tutorial, maar weet dat het schrijven van een autoloader niet iets is dat je misschien meteen goed krijgt als je het voor het eerst doet.

De autoloader voltooien

Laten we wat functionaliteit toevoegen, gezien de stappen die aan het begin van dit gedeelte worden vermeld.

Eerst moeten we een lus instellen die achterwaarts gaat doorlopen door de delen van de bestandsnaam die worden doorgegeven aan de autoladerfunctie. We doen dit omdat het het gemakkelijker maakt om een ​​pad naar het te laden bestand te bouwen.

 0; $ i--) // Meer om te komen ... 

Hierna moeten we kijken naar de $ file_parts en vervang alle occurrences van het onderstrepingsteken door een koppelteken omdat al onze klassenamen en interface onderstrepingstekens gebruiken terwijl onze bestandsnamen koppeltekens gebruiken.

De volgende twee regels zijn de eerste twee regels in de lus die we hierboven hebben uitgezet:

Vervolgens hebben we een voorwaardelijke nodig die een paar dingen doet.

  1. Het moet controleren om te zien welke ingang van het pad van de bestandsnaam die we aan het lezen zijn.
  2. Als we bij het eerste item staan, staan ​​we bij de bestandsnaam; anders zijn we in de naamruimte.
  3. Als we nu de eerste invoer lezen, moeten we bepalen of we een interface proberen te laden of we laden een klasse.
  4. Als dit de eerste is, moeten we de naam van de interface aanpassen, zodat we deze correct laden op basis van de bestandsnaam; anders laden we de klasse op basis van de waarde in de $ huidige veranderlijk.

Het leest als veel, maar het zou niet erg ingewikkeld moeten zijn om te lezen. Zie de commentaarcode hieronder:

Met dat gedaan, is het tijd om een ​​volledig gekwalificeerd pad naar het bestand te bouwen. Gelukkig is dit weinig meer dan een basisreeksaaneenschakeling:

Ten slotte moeten we ervoor zorgen dat het bestand bestaat. Als dit niet het geval is, wordt een standaard WordPress-foutbericht weergegeven:

En op dit punt hebben we een volledige autoloader (die kan worden opgehaald door de bestanden te downloaden van de link in de zijbalk van dit bericht, omdat de broncode wat lang zou zijn om hier in de tutorial te plaatsen).

Ten slotte is het belangrijk op te merken dat deze specifieke functie als een klasse kan (of moet) worden herschreven. Verder moet de klas uit meerdere kleinere functies bestaan ​​waarvan testbaar is, een enkele verantwoordelijkheid heeft en duidelijker leest dan wat hierboven staat. Misschien zal ik in een bonushandleiding het proces doorlopen van hoe dat eruit zou zien.

Maar we zijn nog steeds inclusief bestanden

Als je in de buurt van de bovenkant van het hoofdinvoegbestand kijkt (of het bootstrap-bestand dat we vaak hebben genoemd), zul je verschillende omvatten statements die er als volgt uitzien:

Gezien het werk dat we tot nu toe hebben gedaan, kunnen we eindelijk deze verklaringen verwijderen en deze vervangen door slechts één:

Voor de duidelijkheid, we vervangen het met onze autoloader. Op dit moment zouden we klaar moeten zijn met onze plug-in.

Alles samenvoegen

Nu we onze code hebben geïmplementeerd om een ​​logische organisatie van gerelateerde klassen te bieden en een autoloader hebben geschreven om automatisch bestanden op te nemen op basis van de naamruimte en bestandslocatie van elke klasse, moeten we onze plug-in kunnen starten en laten uitvoeren zoals hij deed tijdens de eerste succesvolle iteratie.

Het laatste dat we moeten doen, is ervoor zorgen dat we het bootstrap-bestand bijwerken, zodat we PHP opdracht geven om de naamruimten te gebruiken voor de Meta_Box, Meta_Box_Display, de Question_Reader, en de CSS_Loader.

in het(); $ Meta_box-> init (); 

Let op in de bovenstaande code gebruiken we PHP's gebruik zoekwoord en we geven onze klassenamen voor met hun directe subpakketten. U kunt meer lezen over gebruik in de handleiding, maar het is kort:

De gebruik sleutelwoord moet worden gedeclareerd in de buitenste scope van een bestand (de globale scope) of in namespace-declaraties. Dit komt omdat het importeren gebeurt tijdens het compileren en niet in de runtime, dus het kan geen block scoped zijn. 

Met dat gezegd en ervan uitgaande dat alles correct werkt, zou je in staat moeten zijn om naar de Voeg nieuwe bericht toe pagina (of Bericht bewerken) pagina, bekijk onze metabox en zie een vraagprompt bovenaan de zijbalk:

Als dat zo is, dan gefeliciteerd. Je hebt je plug-in succesvol ingesteld op je namespaces en autoloading. Als dit niet het geval is, controleert u de code tegen wat we hier hebben gedeeld, bekijkt u uw foutenlogboeken en zorgt u ervoor dat niets ongewoon verschijnt in het WordPress-beheerdersscherm..

als jij do zie iets, de kans is dat het te maken heeft met iets kleins. Bekijk de code die we hebben behandeld, vergelijk deze met wat hier is bijgevoegd bij dit bericht (in de zijbalk samen met de grote blauwe knop) en kijk of je het probleem kunt beperken.

Conclusie

Op dit punt hebben we het einde van onze serie bereikt. Gedurende de laatste vier tutorials hebben we veel terreinen behandeld:

  • We hebben een plug-in gebouwd die gebruikers met vragen oproept om hun blog aan het werk te zetten.
  • We hebben PHP-functies gebruikt voor het lezen van bestanden van het bestandssysteem en om het op het scherm weer te geven.
  • We hebben naamruimten en autoloading gedefinieerd en bekeken hoe ze kunnen worden toegepast.
  • We hebben onze code georganiseerd en onze eigen autoloader geschreven, waardoor de code leesbaarder, overzichtelijker en minder rommelig is.

Uiteindelijk kan veel van het materiaal dat in deze serie wordt behandeld, worden gebruikt in bestaande en toekomstige projecten waar u misschien aan werkt. 

Vergeet niet dat u ook andere WordPress-gerelateerde producten kunt vinden op onze marktplaats. En als u meer wilt weten over het ontwikkelen van oplossingen voor WordPress, kunt u al mijn zelfstudies en series vinden op mijn profielpagina. Aarzel niet om mij te volgen op mijn blog of op Twitter, want ik bespreek bijna dagelijks softwareontwikkeling in de context van WordPress.

En vergeet niet dat de link voor het downloaden van de uiteindelijke broncode in de zijbalk staat onder een knop getiteld Bijlage downloaden. Natuurlijk, aarzel niet om vragen te stellen in de comments!

Middelen

  • spl_autoload_register
  • gebruik