DevTips – Spații de nume în PHP

Publicat: 2020-03-06

Acum aproximativ un an WordPress a decis să actualizeze versiunea PHP minimă necesară, de la 5.2 (folosită din 2010) la ceva mai actualizat. De fapt, astăzi versiunea minimă de PHP recomandată de WordPress este una dintre cele mai recente: PHP 7.3.

Dacă sunteți un simplu utilizator WordPress, probabil că acest lucru nu vă va afecta prea mult (dincolo de faptul că aceste versiuni noi oferă performanțe mai bune).

Dar dacă sunteți dezvoltator, aceste noi versiuni PHP au câteva caracteristici minunate pe care le puteți utiliza în pluginurile și temele dvs. Și astăzi, în mod concret, aș vrea să vă vorbesc despre unul care ne este alături de mult timp, dar: spațiile de nume.

WordPress și prefixe de cod

Una dintre primele reguli pe care le înveți ca dezvoltator WordPress este să „folosești prefixe în tot ceea ce facem” pentru a evita „coliziunile de nume”. După cum putem citi în cele mai bune practici WordPress:

O coliziune de denumire are loc atunci când pluginul dvs. folosește același nume pentru o variabilă, funcție sau clasă ca un alt plugin.

[Pentru a evita coliziunile de nume], toate variabilele, funcțiile și clasele ar trebui să fie prefixate cu un identificator unic. Prefixele împiedică alte plugin-uri să vă suprascrie variabilele și să vă apeleze accidental funcțiile și clasele. De asemenea, vă va împiedica să faceți același lucru.

Cele mai bune practici pentru dezvoltarea pluginurilor WordPress

Astfel, de exemplu, în loc să creați o funcție precum get_site_id , este mai bine să o nelio_content_get_site_id . Astfel, putem identifica rapid pluginul ( nelio_content ) sau tema căreia îi aparține o anumită funcție ( get_site_id ) și evităm erorile fatale dacă mai multe plugin-uri încearcă să definească aceeași funcție.

Utilizarea prefixelor este o modalitate rudimentară de a crea un „spațiu de nume”; o soluție pe care a trebuit să o implementăm când nu aveam o alternativă mai bună. Toate acele elemente care folosesc același prefix fac parte din același set sau spațiu de nume. Dar acest lucru are ca rezultat un cod inutil mai complex: numele sunt mai lungi din cauza prefixelor care nu servesc niciunui scop decât emularea spațiilor de nume.

Spații de nume PHP

PHP versiunea 5.3 a introdus conceptul de spațiu de nume . Definiția pe care o dau în documentație mi se pare excelentă, așa că o reproduc aici:

În cea mai largă definiție, spațiile de nume sunt o modalitate de încapsulare a elementelor. Acesta poate fi văzut ca un concept abstract în multe locuri. De exemplu, în orice sistem de operare, directoarele servesc la gruparea fișierelor asociate și acționează ca un spațiu de nume pentru fișierele din ele. Ca exemplu concret, fișierul foo.txt poate exista atât în ​​directorul /home/greg , cât și în /home/other , dar două copii ale foo.txt nu pot coexista în același director.

În lumea PHP, spațiile de nume sunt concepute pentru a rezolva două probleme pe care autorii de biblioteci și aplicații le întâmpină atunci când creează elemente de cod reutilizabile, cum ar fi clase sau funcții:

1. Ciocnirile de nume dintre codul pe care îl creați și codul PHP intern sau codul terță parte.

2. Abilitatea de a alias (sau scurta) Extra_Long_Names , îmbunătățind lizibilitatea codului sursă.

documente PHP

Cum se creează un spațiu de nume

Crearea unui spațiu de nume în PHP este extrem de ușoară. La începutul fișierului PHP pe care îl creați, adăugați o directivă de namespace de nume cu numele pe care doriți să-l utilizați și „tot ce definiți în acel fișier va aparține acelui spațiu de nume:

 <?php namespace Nelio_Content;

Da, atât de simplu! Acum, „totul” pe care îl creăm acolo va fi în spațiul de nume Nelio_Content . De exemplu, dacă definesc o funcție ca cea pe care am menționat-o la început:

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

știm acum că get_site_id se află în spațiul de nume Nelio_Content . În acest fel, nu mai trebuie să folosim prefixul nelio_content_ atunci când definim funcția. Grozav!

Excepții de la spațiile de nume

Dacă te uiți cu atenție la ceea ce ți-am spus până acum, vei vedea că am scris „totul” între ghilimele: „„totul” adăugăm acolo va aparține spațiului de nume specificat.” De ce am făcut asta? Deoarece spațiile de nume nu se aplică pentru absolut tot codul pe care îl scriem... există câteva excepții.

Spațiile de nume PHP acoperă doar următoarele elemente PHP:

  • Clase
  • Interfețe
  • Trăsături
  • Funcții
  • Constante declarate cu const dar nu cu define

În plus, există câteva lucruri suplimentare în WordPress care au nevoie și de propriile spații de nume și, din păcate, spațiile de nume PHP nu acoperă: mânerele dvs. de script, opțiunile de bază de date sau tipurile de conținut personalizate și metadatele acestora etc. În toate aceste cazuri, trebuie să continuați să utilizați prefixe.

Cum să importați elemente dintr-un spațiu de nume în altul

Dacă trebuie să utilizați un element care se află în propriul spațiu de nume, nu trebuie să faceți nimic special: numiți-l după numele său. De exemplu, în următorul fragment de cod:

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

Puteți vedea că am definit două funcții: get_site_id și get_auth_token , ambele în spațiul de nume Nelio_Content . Când get_auth_token trebuie să folosească get_site_id , pur și simplu îl numește ca de obicei.

Dacă, pe de altă parte, trebuie să utilizați get_site_id într-un spațiu de nume diferit, trebuie să apelați funcția folosind identificatorul complet:

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

sau trebuie să importați funcția cu cuvântul cheie use :

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

Mie personal îmi place foarte mult a doua opțiune: folosind cuvântul cheie use pentru a importa funcții din alte spații de nume, puteți arunca o privire rapidă la antetul fișierului dvs. și puteți identifica dependențele acestuia.

Filtre și acțiuni WordPress cu spații de nume PHP

Există un detaliu important de care ar trebui să țineți cont atunci când utilizați spații de nume lângă filtrele și acțiunile WordPress. Când specificați apeluri de filtru și de acțiune, de obicei faceți acest lucru dând numele apelului înapoi sub formă de șir:

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

Problema este că, dacă această funcție se află într-un spațiu de nume, cârligul anterior nu va funcționa conform așteptărilor; trebuie să spuneți WordPress numele complet al funcției. Cu alte cuvinte, trebuie să includeți spațiul său de nume (dacă are unul).

Adăugați cârligul în fișierul în care definiți spațiul de nume în sine? Nu contează, folosește numele complet:

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

Sunteți într-un alt spațiu de nume, dar ați importat funcția cu use ? Nici nu contează, folosește numele complet:

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

Utilizarea aliasurilor cu spațiile noastre de nume

O altă funcționalitate foarte interesantă a spațiilor de nume este aliasarea. Imaginează-ți următorul scenariu:

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

Dacă vreau să folosesc această funcție într-un alt spațiu de nume, am văzut deja că o pot face cu use . Dar cum aș folosi această funcție dacă modulul în care vreau să o folosesc are deja o funcție numită get_site_id ?

Ei bine, din fericire pentru mine, putem alias importurile noastre în nume noi:

 <?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(); // ... }

Începeți să utilizați spațiile de nume astăzi!

Spațiile de nume sunt un instrument fantastic pentru a evita coliziunile de nume și pentru a ne organiza codul. De fapt, și deși nu am comentat această postare, există standarde precum PSR-4 care permit PHP să încarce automat clase în funcție de structura spațiilor de nume pe care le utilizați și de modul în care organizați codul în directoare și fișiere.

Dacă încă nu utilizați spații de nume în proiectele dvs., vă recomandăm să începeți să faceți acest lucru de acum înainte. Povestește-ne despre experiența ta în comentarii!

Imagine prezentată de Chaitanya Tvs pe Unsplash.