Îmbunătățirea codului WordPress cu PHP modern
Publicat: 2022-03-10WordPress s-a născut în urmă cu cincisprezece ani și, deoarece a păstrat din trecut compatibilitatea cu versiunea anterioară, versiunile mai noi ale codului său nu au putut folosi pe deplin cele mai recente capabilități oferite de versiunile mai noi de PHP. În timp ce cea mai recentă versiune de PHP este 7.3.2, WordPress oferă în continuare suport până la PHP 5.2.4.
Dar acele zile se vor termina în curând! WordPress își va actualiza suportul minim pentru versiunea PHP, ajungând la PHP 5.6 în aprilie 2019 și PHP 7 în decembrie 2019 (dacă totul decurge conform planului). Apoi putem începe în sfârșit să folosim capabilitățile de programare imperative ale PHP fără teama de a sparge site-urile clienților noștri. Ura!
Deoarece cei cincisprezece ani de cod funcțional ai WordPress au influențat modul în care dezvoltatorii au construit cu WordPress, site-urile, temele și pluginurile noastre pot fi pline de cod mai puțin decât optim, care poate primi cu plăcere un upgrade.
Acest articol este compus din două părți:
- Cele mai relevante funcții noi
Alte caracteristici au fost adăugate la versiunile PHP 5.3, 5.4, 5.5, 5.6 și 7.0 (observați că nu există PHP 6) și le vom explora pe cele mai relevante. - Construirea unui software mai bun
Vom arunca o privire mai atentă asupra acestor funcții și asupra modului în care acestea ne pot ajuta să construim un software mai bun.
Să începem prin a explora „noile” caracteristici ale PHP.
Clasele, OOP, SOLID și modele de design
Clasele și obiectele au fost adăugate la PHP 5, așa că WordPress folosește deja aceste caracteristici, totuși, nu foarte extins sau cuprinzător: Paradigma de codare în WordPress este în mare parte programare funcțională (efectuarea de calcule prin apelarea funcțiilor lipsite de starea aplicației) în loc de obiect. -programare orientată (OOP) (efectuarea de calcule prin manipularea stării obiectelor). Prin urmare, descriu, de asemenea, clase și obiecte și cum să le folosesc prin OOP.
OOP este ideal pentru producerea de aplicații modulare: Clasele permit crearea de componente, fiecare dintre acestea putând implementa o anumită funcționalitate și interacționa cu alte componente și pot oferi personalizare prin proprietățile și moștenirea încapsulate, permițând un grad ridicat de reutilizare a codului. În consecință, aplicația este mai ieftin de testat și întreținut, deoarece caracteristicile individuale pot fi izolate de aplicație și gestionate pe cont propriu; există și o creștere a productivității, deoarece dezvoltatorul poate folosi componente deja dezvoltate și poate evita reinventarea roții pentru fiecare aplicație.
O clasă are proprietăți și funcții, cărora li se poate oferi vizibilitate prin utilizarea private
(accesibil numai din clasa definitorie), protected
(accesibil din interiorul clasei definitorii și a strămoșilor ei și a claselor moștenitoare) și public
(accesibil de oriunde). Dintr-o funcție, putem accesa proprietățile clasei adăugând numele lor cu $this->
:
class Person { protected $name; public function __construct($name) { $this->name = $name; } public function getIntroduction() { return sprintf( __('My name is %s'), $this->name ); } }
O clasă este instanțiată într-un obiect prin cuvântul cheie new
, după care îi putem accesa proprietățile și funcțiile prin ->
:
$person = new Person('Pedro'); echo $person->getIntroduction(); // This prints "My name is Pedro"
O clasă care moștenește poate suprascrie funcțiile public
și protected
de la clasele sale strămoși și poate accesa funcțiile strămoși, adăugându-le înaintea parent::
:
class WorkerPerson extends Person { protected $occupation; public function __construct($name, $occupation) { parent::__construct($name); $this->occupation = $occupation; } public function getIntroduction() { return sprintf( __('%s and my occupation is %s'), parent::getIntroduction(), $this->occupation ); } } $worker = new WorkerPerson('Pedro', 'web development'); echo $worker->getIntroduction(); // This prints "My name is Pedro and my occupation is web development"
O metodă poate fi făcută abstract
, ceea ce înseamnă că trebuie implementată de o clasă moștenitoare. O clasă care conține o metodă abstract
trebuie făcută în sine abstract
, ceea ce înseamnă că nu poate fi instanțiată; numai clasa care implementează metoda abstractă poate fi instanțiată:
abstract class Person { abstract public function getName(); public function getIntroduction() { return sprintf( __('My name is %s'), $this->getName() ); } } // Person cannot be instantiated class Manuel extends Person { public function getName() { return 'Manuel'; } } // Manuel can be instantiated $manuel = new Manuel();
Clasele pot defini, de asemenea, metode și proprietăți static
, care trăiesc sub clasa în sine și nu sub o instanțiere a clasei ca obiect. Acestea sunt accesate prin self::
din interiorul clasei și prin numele clasei + ::
din afara acesteia:
class Factory { protected static $instances = []; public static function registerInstance($handle, $instance) { self::$instances[$handle] = $instance; } public static function getInstance($handle) { return self::$instances[$handle]; } } $engine = Factory::getInstance('Engine');
Pentru a profita la maximum de OOP, putem folosi principiile SOLID pentru a stabili o bază solidă, dar ușor de personalizată pentru aplicație, și modele de proiectare pentru a rezolva probleme specifice într-un mod încercat și testat. Modelele de design sunt standardizate și bine documentate, permițând dezvoltatorilor să înțeleagă modul în care diferitele componente ale aplicației se relaționează între ele și oferă o modalitate de a structura aplicația într-un mod ordonat, ceea ce ajută la evitarea utilizării variabilelor globale (cum ar fi global $wpdb
) care poluează mediul global.
Spații de nume
Spațiile de nume au fost adăugate la PHP 5.3, prin urmare lipsesc în prezent cu totul din nucleul WordPress.
Spațiile de nume permit organizarea structurală a bazei de cod pentru a evita conflictele atunci când elemente diferite au același nume - într-o manieră similară directoarelor sistemului de operare care permit să existe fișiere diferite cu același nume, atâta timp cât sunt stocate în directoare diferite. Spațiile de nume fac același truc de încapsulare pentru elementele PHP (cum ar fi clase, trăsături și interfețe), evitând coliziunile atunci când elemente diferite au același nume, plasându-le pe spații de nume diferite.
Spațiile de nume sunt obligatorii atunci când interacționăm cu biblioteci terțe, deoarece nu putem controla cum vor fi denumite articolele acestora, ceea ce duce la potențiale coliziuni atunci când folosim nume standard precum „Fișier”, „Logger” sau „Încărcare” pentru articolele noastre. Mai mult, chiar și în cadrul unui singur proiect, spațiile de nume împiedică numele claselor să devină extrem de lungi pentru a evita confruntările cu alte clase, ceea ce ar putea duce la nume precum „MyProject_Controller_FileUpload”.
Spațiile de nume sunt definite folosind cuvântul cheie namespace
(plasat pe linia imediat după deschiderea <?php
) și se pot întinde pe mai multe niveluri sau subnamespaces (similar cu mai multe subdirectoare în care plasați un fișier), care sunt separate folosind un \
:
<?php namespace CoolSoft\ImageResizer\Controllers; class ImageUpload { }
Pentru a accesa clasa de mai sus, trebuie să-i calificăm complet numele, inclusiv spațiul de nume (și începând cu \
):
$imageUpload = new \CoolSoft\ImageResizer\Controllers\ImageUpload();
Sau putem importa și clasa în contextul curent, după care putem face referire direct la clasa după numele ei:
use CoolSoft\ImageResizer\Controllers\ImageUpload; $imageUpload = new ImageUpload();
Prin denumirea spațiilor de nume urmând convențiile stabilite, putem obține beneficii suplimentare. De exemplu, urmând Recomandarea standardelor PHP PSR-4, aplicația poate folosi mecanismul de încărcare automată al Composer pentru încărcarea fișierelor, scăzând astfel complexitatea și adăugând interoperabilitate fără fricțiuni între dependențe. Această convenție stabilește să includă numele vânzătorului (de exemplu, numele companiei) ca subspațiu de nume de sus, urmat opțional de numele pachetului și abia apoi urmat de o structură internă în care fiecare subspațiu de nume corespunde unui director cu același nume. Rezultatul mapează de la 1 la 1 locația fizică a fișierului în unitate cu spațiul de nume al elementului definit în fișier.
Trăsături
Trăsăturile au fost adăugate la PHP 5.4, prin urmare lipsesc în prezent cu totul din nucleul WordPress.
PHP acceptă moștenirea unică, deci o subclasă este derivată dintr-o singură clasă părinte, și nu din mai multe. Prin urmare, clasele care nu se extind unele de altele nu pot reutiliza codul prin moștenirea clasei. Trăsăturile este un mecanism care permite compunerea orizontală a comportamentului, făcând posibilă reutilizarea codului între clasele care trăiesc în diferite ierarhii de clasă.
O trăsătură este similară cu o clasă, cu toate acestea, nu poate fi instanțiată singură. În schimb, codul definit în interiorul unei trăsături poate fi considerat ca fiind „copiat și lipit” în clasa de compunere în timpul compilării.
O trăsătură este definită folosind cuvântul cheie trait
, după care poate fi importată în orice clasă prin cuvântul cheie use
. În exemplul de mai jos, două clase complet neînrudite Person
și Shop
pot reutiliza același cod printr-o trăsătură Addressable
:
trait Addressable { protected $address; public function getAddress() { return $this->address; } public function setAddress($address) { $this->address = $address; } } class Person { use Addressable; } class Shop { use Addressable; } $person = new Person('Juan Carlos'); $person->setAddress('Obelisco, Buenos Aires');
O clasă poate, de asemenea, să compună mai multe trăsături:
trait Exportable { public class exportToCSV($filename) { // Iterate all properties and export them to a CSV file } } class Person { use Addressable, Exportable; }
Trăsăturile pot fi, de asemenea, compuse din alte trăsături, definesc metode abstracte și oferă un mecanism de rezolvare a conflictelor atunci când două sau mai multe trăsături compuse au același nume de funcție, printre alte caracteristici.
Interfețe
Interfețele au fost adăugate la PHP 5, așa că WordPress folosește deja această funcție, totuși, extrem de parțial: nucleul include mai puțin de zece interfețe în total!
Interfețele permit crearea de cod care specifică metodele care trebuie implementate, dar fără a fi nevoie să definească modul în care aceste metode sunt implementate efectiv. Sunt utile pentru definirea contractelor între componente, ceea ce duce la o mai bună modularitate și mentenabilitate a aplicației: O clasă care implementează o interfață poate fi o cutie neagră de cod și, atâta timp cât semnăturile funcțiilor din interfață nu se modifică, codul poate fi actualizat după bunul plac, fără a produce modificări rupturi, ceea ce poate ajuta la prevenirea acumulării datoriilor tehnice. În plus, ele pot ajuta la reducerea blocării furnizorilor, permițând schimbarea implementării unei interfețe cu cea a unui alt furnizor. În consecință, este imperativ să codificați aplicația împotriva interfețelor în loc de implementări (și definirea care sunt implementările reale prin injecția de dependență).
Interfețele sunt definite folosind cuvântul cheie interface
și trebuie să enumere doar semnătura metodelor sale (adică fără a avea conținutul definit), care trebuie să aibă vizibilitate public
(în mod implicit, adăugarea unui cuvânt cheie fără vizibilitate îl face și public):
interface FileStorage { function save($filename, $contents); function readContents($filename); }
O clasă definește că implementează interfața prin cuvântul cheie implements
:
class LocalDriveFileStorage implements FileStorage { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } }
O clasă poate implementa mai mult de o interfață, separându-le cu ,
:
interface AWSService { function getRegion(); } class S3FileStorage implements FileStorage, AWSService { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } function getRegion() { return 'us-east-1'; } }
Deoarece o interfață declară intenția a ceea ce ar trebui să facă o componentă, este extrem de important să denumim interfețele în mod corespunzător.
Închideri
Închiderile au fost adăugate la PHP 5.3, prin urmare lipsesc în prezent cu totul din nucleul WordPress.
Închiderile este un mecanism de implementare a funcțiilor anonime, care ajută la eliminarea spațiului de nume global de funcțiile de unică folosință (sau rar utilizate). Tehnic vorbind, închiderile sunt cazuri de Closure
de clasă , cu toate acestea, în practică, cel mai probabil putem fi fericiți să nu conștientizăm acest fapt fără nici un rău.
Înainte de închidere, de fiecare dată când trecem o funcție ca argument unei alte funcții, a trebuit să definim funcția în avans și să îi transmitem numele ca argument:
function duplicate($price) { return $price*2; } $touristPrices = array_map('duplicate', $localPrices);
Cu închideri, o funcție anonimă (adică fără nume) poate fi deja transmisă direct ca parametru:
$touristPrices = array_map(function($price) { return $price*2; }, $localPrices);
Închiderile pot importa variabile în contextul său prin cuvântul cheie use
:
$factor = 2; $touristPrices = array_map(function($price) use($factor) { return $price*$factor; }, $localPrices);
Generatoare
Generatoarele au fost adăugate la PHP 5.5, prin urmare lipsesc în prezent cu totul din nucleul WordPress.
Generatoarele oferă o modalitate ușoară de a implementa iteratoare simple. Un generator permite să scrie cod care utilizează foreach
pentru a itera peste un set de date fără a fi nevoie să construiți o matrice în memorie. O funcție de generator este aceeași cu o funcție normală, cu excepția faptului că, în loc să se întoarcă o dată, poate yield
de câte ori este nevoie pentru a furniza valorile care trebuie iterate.
function xrange($start, $limit, $step = 1) { for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } foreach (xrange(1, 9, 2) as $number) { echo "$number "; } // This prints: 1 3 5 7 9
Declarații de tip argument și returnare
Diferite declarații de tip de argument au fost introduse în diferite versiuni de PHP: WordPress este deja capabil să declare interfețe și matrice (ceea ce nu: abia am găsit o instanță a unei funcții care declară o matrice ca parametru în nucleu și nicio interfață) și va în curând vor putea declara apelabile (adăugat în PHP 5.4) și tipurile scalare: bool, float, int și șir (adăugat în PHP 7.0). Declarațiile de tip returnare au fost adăugate la PHP 7.0.
Declarațiile de tip de argument permit funcțiilor să declare ce tip specific trebuie să fie un argument. Validarea este executată în timpul apelului, aruncând o excepție dacă tipul argumentului nu este cel declarat. Declarațiile de tip returnat sunt același concept, cu toate acestea, ele specifică tipul de valoare care va fi returnată de la funcție. Declarațiile de tip sunt utile pentru a face mai ușor de înțeles intenția funcției și pentru a evita erorile de rulare de la primirea sau returnarea unui tip neașteptat.
Tipul de argument este declarat înainte de numele variabilei argument, iar tipul de returnare este declarat după argumente, precedat de :
:
function foo(boolean $bar): int { }
Declarațiile de tip argument scalar au două opțiuni: coercitive și stricte. În modul coercitiv, dacă tipul greșit este trecut ca parametru, acesta va fi convertit în tipul potrivit. De exemplu, o funcție căreia i se dă un număr întreg pentru un parametru care așteaptă un șir va primi o variabilă de tip șir. În modul strict, va fi acceptată doar o variabilă de tipul exact de declarație.
Modul coercitiv este implicit. Pentru a activa modul strict, trebuie să adăugăm o instrucțiune declare
folosită cu declarația strict_types
:

declare(strict_types=1); function foo(boolean $bar) { }
Sintaxă și operatori noi
WordPress poate identifica deja liste de argumente cu lungime variabilă prin funcția func_num_args
. Pornind de la PHP 5.6, putem folosi simbolul ...
pentru a indica faptul că funcția acceptă un număr variabil de argumente, iar aceste argumente vor fi trecute în variabila dată ca o matrice:
function sum(...$numbers) { $sum = 0; foreach ($numbers as $number) { $sum += $number; } return $sum; }
Începând de la PHP 5.6, constantele pot implica expresii scalare care implică literale numerice și șir în loc de doar valori statice și, de asemenea, matrice:
const SUM = 37 + 2; // A scalar expression const LETTERS = ['a', 'b', 'c']; // An array
Pornind de la PHP 7.0, matricele pot fi definite și folosind define
:
define('LETTERS', ['a', 'b', 'c']);
PHP 7.0 a adăugat câțiva operatori noi: operatorul de coalescere Null ( ??
) și operatorul Navă spațială ( <=>
).
Operatorul de coalescere Null ??
este zahăr sintactic pentru cazul obișnuit al necesității de a folosi un ternar împreună cu isset(). Returnează primul său operand dacă există și nu este NULL; în caz contrar, returnează al doilea operand.
$username = $_GET['user'] ?? 'nobody'; // This is equivalent to: // $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
Operatorul de navă spațială <=>
este folosit pentru compararea a două expresii, returnând -1, 0 sau 1 când primul operand este, respectiv, mai mic, egal sau mai mare decât al doilea operand.
echo 1 <=> 2; // returns -1 echo 1 <=> 1; // returns 0 echo 2 <=> 1; // returns 1
Acestea sunt cele mai importante caracteristici noi adăugate la PHP, cuprinzând versiunile 5.3 până la 7.0. Lista noilor funcții suplimentare, care nu sunt enumerate în acest articol, poate fi obținută răsfoind documentația PHP privind migrarea de la versiune la versiune.
În continuare, analizăm cum putem profita la maximum de toate aceste noi funcții și de tendințele recente în dezvoltarea web, pentru a produce un software mai bun.
Recomandări privind standardele PHP
Recomandările privind standardele PHP au fost create de un grup de dezvoltatori PHP din cadre și biblioteci populare, încercând să stabilească convenții, astfel încât diferite proiecte să poată fi integrate mai perfect și diferite echipe să poată lucra mai bine între ele. Recomandările nu sunt statice: recomandările existente pot fi depreciate și pot fi create altele mai noi pentru a le înlocui, iar altele noi sunt lansate în mod continuu.
Recomandările actuale sunt următoarele:
grup | Recomandare | Descriere |
---|---|---|
Stiluri de codare Formatarea standardizată reduce frecarea cognitivă la citirea codului de la alți autori | PSR-1 | Standard de codare de bază |
PSR-2 | Ghid de stil de codare | |
Încărcare automată Încărcările automate îndepărtează complexitatea includerii fișierelor prin maparea spațiilor de nume la căile sistemului de fișiere | PSR-4 | Încărcare automată îmbunătățită |
Interfețe Interfețele simplifică partajarea codului între proiecte urmând contractele așteptate | PSR-3 | Interfață de înregistrare |
PSR-6 | Interfață de stocare în cache | |
PSR-11 | Interfață container | |
PSR-13 | Link-uri hipermedia | |
PSR-16 | Cache simplu | |
HTTP Standarde și interfețe interoperabile pentru a avea o abordare agnostică a gestionării cererilor și răspunsurilor HTTP, atât pe partea client, cât și pe server | PSR-7 | Interfețe pentru mesaje HTTP |
PSR-15 | Handler-uri HTTP | |
PSR-17 | Fabrici HTTP | |
PSR-18 | Client HTTP |
Gândiți și codificați în componente
Componentele fac posibilă utilizarea celor mai bune caracteristici dintr-un cadru fără a fi blocat în cadrul în sine. De exemplu, Symfony a fost lansat ca un set de componente PHP reutilizabile care pot fi instalate independent de cadrul Symfony; Laravel, un alt framework PHP, folosește mai multe componente Symfony și a lansat propriul set de componente reutilizabile care pot fi utilizate de orice proiect PHP.
Toate aceste componente sunt publicate în Packagist, un depozit de pachete PHP publice și pot fi adăugate cu ușurință la orice proiect PHP prin Composer, un manager de dependențe extrem de popular pentru PHP.
WordPress ar trebui să facă parte dintr-un astfel de ciclu de dezvoltare virtuos. Din păcate, nucleul WordPress în sine nu este construit folosind componente (dovadă de absența aproape totală a interfețelor) și, în plus, nici măcar nu are fișierul composer.json necesar pentru a permite instalarea WordPress prin Composer. Acest lucru se datorează faptului că comunitatea WordPress nu a fost de acord dacă WordPress este dependența unui site (caz în care instalarea lui prin Composer ar fi justificată) sau dacă este site-ul în sine (caz în care Composer poate să nu fie instrumentul potrivit pentru job) .
În opinia mea, dacă ne așteptăm ca WordPress să rămână relevant în următorii cincisprezece ani (cel puțin WordPress ca CMS backend), atunci WordPress trebuie să fie recunoscut ca dependență a unui site și să fie disponibil pentru instalare prin Composer . Motivul este foarte simplu: cu o singură comandă în terminal, Composer permite să declare și să instaleze dependențele unui proiect din miile de pachete publicate în Packagist, făcând posibilă crearea de aplicații PHP extrem de puternice în cel mai scurt timp, iar dezvoltatorii iubesc lucrând în acest fel. Dacă WordPress nu se adaptează la acest model, poate pierde sprijinul din partea comunității de dezvoltare și poate cădea în uitare, la fel de mult cu cât FTP a căzut din favoare după introducerea implementărilor bazate pe Git.
Aș susține că lansarea lui Gutenberg demonstrează deja că WordPress este o dependență de site și nu site-ul în sine: Gutenberg tratează WordPress ca pe un CMS fără cap și poate funcționa și cu alte sisteme backend, așa cum exemplifica Drupal Gutenberg. Prin urmare, Gutenberg precizează că CMS-ul care alimentează un site poate fi schimbat, prin urmare ar trebui tratat ca o dependență. Mai mult decât atât, Gutenberg însuși este destinat să se bazeze pe componente JavaScript lansate prin npm (după cum a explicat de către committerul de bază Adam Silverstein), așa că dacă clientul WordPress este de așteptat să își gestioneze pachetele JavaScript prin managerul de pachete npm, atunci de ce să nu extindeți această logică la backend-ul pentru a gestiona dependențele PHP prin Composer?
Acum vestea bună: nu este nevoie să așteptați ca această problemă să fie rezolvată, deoarece este deja posibil să tratați WordPress ca dependență a unui site și să îl instalați prin Composer. John P. Bloch a reflectat nucleul WordPress în Git, a adăugat un fișier composer.json și l-a lansat în Packagist, iar Bedrock de la Roots oferă un pachet pentru instalarea WordPress cu o structură de foldere personalizată, cu suport pentru instrumente moderne de dezvoltare și o securitate îmbunătățită. Și temele și pluginurile sunt de asemenea acoperite; Atâta timp cât au fost listate în directoarele cu teme și pluginuri WordPress, sunt disponibile sub WordPress Packagist.
În consecință, este o opțiune sensibilă să creați cod WordPress nu gândind în termeni de teme și pluginuri, ci gândind în termeni de componente, făcându-le disponibile prin Packagist pentru a fi utilizate de orice proiect PHP și, în plus, împachetate și lansate ca teme și pluginuri pentru utilizarea specifică a WordPress. Dacă componenta trebuie să interacționeze cu API-urile WordPress, atunci aceste API-uri pot fi extrase în spatele unei interfețe care, dacă este nevoie, poate fi implementată și pentru alte CMS-uri.
Adăugarea unui motor de șabloane pentru a îmbunătăți stratul de vizualizare
Dacă respectăm recomandarea de gândire și codificare în componente și tratăm WordPress ca pe o dependență a unui site, alta decât site-ul în sine, atunci proiectele noastre se pot elibera de granițele impuse de WordPress și pot importa idei și instrumente preluate din alte cadre.
Redarea conținutului HTML pe partea serverului este un exemplu, care se face prin șabloane PHP simple. Acest strat de vizualizare poate fi îmbunătățit prin motoarele de șabloane Twig (de la Symfony) și Blade (de la Laravel), care oferă o sintaxă foarte concisă și caracteristici puternice care îi oferă un avantaj față de șabloanele PHP simple. În special, blocurile dinamice ale lui Gutenberg pot beneficia cu ușurință de pe urma acestor motoare de șabloane, deoarece procesul lor de a reda HTML-ul blocului pe partea serverului este decuplat de arhitectura ierarhiei șabloane a WordPress.
Arhitectul Aplicația pentru uz general
Codarea în funcție de interfețe și gândirea în termeni de componente ne permite să construim o aplicație pentru uz general și să o personalizăm pentru utilizarea specifică pe care trebuie să o oferim, în loc să codificăm doar pentru utilizarea specifică pentru fiecare proiect pe care îl avem. Chiar dacă această abordare este mai costisitoare pe termen scurt (implică muncă suplimentară), se plătește pe termen lung atunci când proiectele suplimentare pot fi livrate cu eforturi mai mici de la doar personalizarea unei aplicații de uz general.
Pentru ca această abordare să fie eficientă, trebuie luate în considerare următoarele considerente:
Evitați dependențele fixe (pe cât posibil)
jQuery și Bootstrap (sau Foundation, sau <–insert your favorite library here–> ) ar fi putut fi considerate indispensabile în urmă cu câțiva ani, cu toate acestea, ele au pierdut constant teren față de vanilla JS și noile funcții native CSS. Prin urmare, un proiect de uz general codificat acum cinci ani, care depindea de aceste biblioteci, poate să nu mai fie potrivit în zilele noastre. Prin urmare, ca regulă generală, cu cât este mai mică cantitatea de dependențe fixe de biblioteci terțe, cu atât se va dovedi mai actualizată pe termen lung.
Îmbunătățirea progresivă a funcționalităților
WordPress este un sistem CMS complet care include gestionarea utilizatorilor, prin urmare suportul pentru gestionarea utilizatorilor este inclus din pachet. Cu toate acestea, nu orice site WordPress necesită gestionarea utilizatorilor. Prin urmare, aplicația noastră ar trebui să țină cont de acest lucru și să funcționeze optim în fiecare scenariu: sprijină gestionarea utilizatorilor ori de câte ori este necesar, dar nu încărcați activele corespunzătoare ori de câte ori nu este. Această abordare poate funcționa și treptat: Să spunem că un client necesită să implementeze un formular Contactați-ne, dar nu are buget, așa că îl codificăm folosind un plugin gratuit cu funcții limitate, iar un alt client are bugetul pentru a cumpăra licența de la o ofertă de plugin comercial. caracteristici mai bune. Apoi, ne putem codifica funcționalitatea implicită la o funcționalitate foarte de bază și putem folosi din ce în ce mai mult funcțiile din oricare dintre pluginurile cele mai capabile disponibile în sistem.
Revizuirea continuă a codului și a documentației
Prin revizuirea periodică a codului nostru scris anterior și a documentației sale, putem valida dacă este fie actualizat cu privire la noile convenții și tehnologii și, dacă nu este, să luăm măsuri pentru a-l actualiza înainte ca datoria tehnică să devină prea costisitoare pentru a fi depășită. și trebuie să-l codificăm din nou de la zero.
Lectură recomandată : Fiți atenți: funcțiile PHP și WordPress care vă pot face site-ul nesigur
Încercați să minimizați problemele, dar fiți pregătiți când acestea se întâmplă
Niciun software nu este niciodată 100% perfect: erorile sunt mereu acolo, pur și simplu nu le-am găsit încă. Ca atare, trebuie să ne asigurăm că, odată ce problemele apar, acestea sunt ușor de remediat.
Simplifică
Software-ul complex nu poate fi menținut pe termen lung: nu doar pentru că alți membri ai echipei ar putea să nu îl înțeleagă, ci și pentru că persoana care l-a codificat ar putea să nu-și înțeleagă propriul cod complex peste câțiva ani. Deci, producerea de software simplu trebuie să fie o prioritate, mai mult cu cât doar software-ul simplu poate fi corect și rapid.
Eșecul la timpul de compilare este mai bun decât la timpul de execuție
Dacă o bucată de cod poate fi validată împotriva erorilor fie în timpul compilării, fie în timpul rulării, atunci ar trebui să prioritizăm soluția de compilare, astfel încât eroarea să poată apărea și să fie tratată în etapa de dezvoltare și înainte ca aplicația să ajungă la producție. De exemplu, atât const
, cât și define
sunt utilizate pentru definirea constantelor, totuși, în timp ce const
este validat în timpul compilării, define
este validat în timpul execuției. Deci, ori de câte ori este posibil, folosirea const
este de preferată decât define
.
Urmând această recomandare, conectarea funcțiilor WordPress conținute în clase poate fi îmbunătățită prin trecerea clasei reale ca parametru în loc de un șir cu numele clasei. În exemplul de mai jos, dacă clasa Foo
este redenumită, în timp ce al doilea cârlig va produce o eroare de compilare, primul cârlig va eșua în timpul execuției, prin urmare al doilea cârlig este mai bun:
class Foo { public static function bar() { } } add_action('init', ['Foo', 'bar']); // Not so good add_action('init', [Foo::class, 'bar']); // Much better
Din același motiv ca mai sus, ar trebui să evităm utilizarea variabilelor globale (cum ar fi global $wpdb
): acestea nu numai că poluează contextul global și nu sunt ușor de urmărit de unde provin, dar și, dacă sunt redenumite, eroarea va să fie produs în timpul rulării. Ca soluție, putem folosi un Container de injecție de dependență pentru a obține o instanță a obiectului necesar.
Tratarea erorilor/excepțiilor
Putem crea o arhitectură a obiectelor Exception
, astfel încât aplicația să poată reacționa corespunzător în funcție de fiecare problemă particulară, fie să se recupereze de la aceasta ori de câte ori este posibil, fie să afișeze un mesaj de eroare util utilizatorului oricând nu și, în general, să înregistreze eroarea pentru admin pentru a rezolva problema. Și protejați-vă întotdeauna utilizatorii de ecranul alb al morții: Toate Error
și Exception
neprinse pot fi interceptate prin funcția set_exception_handler
pentru a imprima pe ecran un mesaj de eroare care nu este înfricoșător.
Adoptă instrumente de construcție
Instrumentele de construcție pot economisi mult timp prin automatizarea sarcinilor care sunt foarte obositoare de executat manual. WordPress nu oferă integrare cu niciun instrument specific de construcție, așa că sarcina de a le încorpora în proiect va reveni în întregime dezvoltatorului.
Există diferite instrumente pentru realizarea unor scopuri diferite. De exemplu, există instrumente de compilare pentru a executa sarcini pentru comprimarea și redimensionarea imaginilor, minimizarea fișierelor JS și CSS și copierea fișierelor într-un director pentru producerea unei versiuni, cum ar fi Webpack, Grunt și Gulp; alte instrumente ajută la crearea schelei unui proiect, ceea ce este util pentru producerea structurii de foldere pentru temele sau pluginurile noastre, cum ar fi Yeoman. Într-adevăr, având atâtea instrumente în jur, răsfoirea articolelor care compară diferitele instrumente disponibile va ajuta la găsirea celui mai potrivit pentru nevoile noastre.
În unele cazuri, totuși, nu există instrumente de compilare care să poată realiza exact ceea ce are nevoie proiectul nostru, așa că este posibil să fie nevoie să ne codificăm propriul instrument de construcție ca o extensie a proiectului în sine. De exemplu, am făcut acest lucru pentru a genera fișierul service-worker.js pentru a adăuga suport pentru Service Workers în WordPress.
Concluzie
Datorită accentului puternic pus pe păstrarea compatibilității cu versiunea anterioară, extinsă chiar și până la PHP 5.2.4, WordPress nu a putut beneficia de cele mai recente funcții adăugate la PHP, iar acest fapt a făcut ca WordPress să devină o platformă nu foarte interesantă de codare. pentru printre mulți dezvoltatori.
Din fericire, aceste zile sumbre s-ar putea termina în curând, iar WordPress poate deveni o platformă strălucitoare și incitantă pentru codificare: cerința PHP 7.0+ începând din decembrie 2019 va face disponibile o mulțime de funcții PHP, permițând dezvoltatorilor să producă mai puternice și mai puternice. software mai performant. În acest articol, am analizat cele mai importante funcții PHP recent disponibile și cum să profităm la maximum de ele.
Lansarea recentă a lui Gutenberg ar putea fi un semn al vremurilor bune care vor veni: chiar dacă Gutenberg în sine nu a fost pe deplin acceptat de comunitate, cel puțin demonstrează dorința de a încorpora cele mai noi tehnologii (cum ar fi React și Webpack) în nucleu. . Această întorsătură a evenimentelor mă face să mă întreb: dacă frontend-ul poate avea o astfel de schimbare, de ce să nu o extind și la backend? Odată ce WordPress necesită cel puțin PHP 7.0, upgrade-ul la instrumente și metodologii moderne se poate accelera: cu cât npm a devenit managerul de pachete JavaScript preferat, de ce să nu îl facem pe Composer să devină managerul oficial de dependență PHP? Dacă blocurile sunt noua unitate pentru șantierele de construcție în front-end, de ce să nu folosiți componente PHP ca unitate pentru încorporarea funcționalităților în backend? Și, în sfârșit, dacă Gutenberg tratează WordPress ca pe un CMS backend interschimbabil, de ce să nu recunoaștem deja că WordPress este o dependență de site și nu site-ul în sine? Vă voi lăsa aceste întrebări deschise la care să reflectați și să reflectați.