Introducere în PHP 7: Ce este nou și ce a dispărut

Publicat: 2022-03-11

Unul dintre cele mai interesante evenimente din 2015 din lumea PHP a fost lansarea PHP 7, la 10 ani de la lansarea ultimei versiuni majore, PHP 5. Cu un pas major înainte, PHP 7 introduce o mulțime de noi funcții și upgrade-uri de performanță. .

Cu toate acestea, elimină și funcționalitatea veche, depreciată, care introduce unele întreruperi de compatibilitate, ceea ce face mai dificilă migrarea aplicațiilor mai vechi la noua versiune. Acest ghid ar trebui să servească drept un tur rapid la ce să vă așteptați dacă intenționați să mutați aplicațiile existente sau să creați altele noi, pe lângă PHP 7.

Dar stai, unde a ajuns PHP 6?

Dacă nu ați lucrat cu PHP în ultimul timp, s-ar putea să vă întrebați ce s-a întâmplat cu PHP 6, de ce săriți de la PHP 5 la PHP 7? Ei bine, pe scurt, PHP 6 a fost un eșec. Caracteristica principală a versiunii 6 a fost suportul nativ pentru caracterele Unicode, deoarece PHP este folosit în principal în dezvoltarea web și web-ul are nevoie de Unicode, așa că trecerea de a aduce Unicode în PHP a avut sens.

Ideea a fost de a aduce suport complet pentru Unicode la nucleu în sine. Ar fi adus capacități extinse pentru limbaj, de la abilitatea de a folosi emoji-uri stupide ca nume de variabile și funcții, până la funcționalitatea puternică a șirurilor internaționale. De exemplu, atunci când o altă limbă folosește litere mari și mici diferit de engleză sau când un nume în caractere chinezești trebuie convertit în engleză.

Din păcate, acest plan ambițios s-a dovedit a fi o problemă mai mare decât se anticipa. O mare parte din baza de cod a trebuit să fie portată pentru a suporta Unicode atât pentru extensii de bază, cât și pentru extensii importante, ceea ce s-a dovedit obositor și dificil. Acest lucru a încetinit dezvoltarea altor funcții din limbaj, frustrând mulți dezvoltatori PHP în acest proces. Au apărut obstacole suplimentare, ceea ce a dus la un interes mai mic pentru dezvoltarea unui suport nativ Unicode, ceea ce a dus în cele din urmă la abandonarea proiectului.

Deoarece resurse, cum ar fi cărți și articole, au fost scrise pentru PHP 6 și suportul său Unicode, noua versiune va fi redenumită PHP 7 pentru a evita confuzia.

Oricum, destulă locuire în trecutul trist, să vedem ce aduce PHP 7 la petrecere.

Bătălia de performanță, PHP 7 vs. PHP 5

Cu aproape toate actualizările, sunt de așteptat îmbunătățiri minore de performanță. Cu toate acestea, de data aceasta PHP aduce o îmbunătățire semnificativă față de versiunile anterioare, făcând performanța absolută una dintre cele mai atractive caracteristici ale PHP 7. Acest lucru vine ca parte a proiectului „PHPNG”, care abordează elementele interne ale Zend Engine în sine.

Prin refactorizarea structurilor interne de date și adăugarea unui pas intermediar la compilarea codului sub forma unui arbore de sintaxă abstractă (AST), rezultatul este o performanță superioară și o alocare mai eficientă a memoriei. Cifrele în sine par foarte promițătoare; Benchmark-urile efectuate pe aplicațiile din lumea reală arată că PHP 7 este de două ori mai rapid decât PHP 5.6 în medie și are ca rezultat un consum de memorie cu 50% mai mic în timpul solicitărilor, făcând PHP 7 un puternic rival pentru compilatorul HHVM JIT de la Facebook. Aruncă o privire la acest infografic de la Zend care prezintă performanța pentru unele CMS și framework-uri comune.

Imagine: Ilustrație de performanță PHP 7 vs. PHP 5.

Scăderea consumului de memorie permite, de asemenea, mașinilor mai mici să gestioneze mai bine cererile, împreună cu posibilitatea de a construi micro-servicii în jurul PHP. Schimbările interne, în special implementarea AST, deschid, de asemenea, posibilități pentru optimizări viitoare care ar putea împinge performanța și mai departe. O nouă implementare internă a unui compilator JIT este luată în considerare pentru versiunile viitoare.

PHP 7 zahar sintactic

PHP 7 vine cu noi caracteristici de sintaxă. Deși nu extind capacitățile limbajului în sine, ele oferă o modalitate mai bună sau mai ușoară de a face codul mai plăcut de scris și mai plăcut pentru ochi.

Declarații de import de grup

Acum, putem grupa declarațiile de import pentru clase care provin din același spațiu de nume într-o singură linie de use . Acest lucru ar trebui să ajute la alinierea declarațiilor într-un mod semnificativ sau pur și simplu să salveze câțiva octeți în fișierele dvs.

 use Framework\Module\Foo; use Framework\Module\Bar; use Framework\Module\Baz;

Cu PHP 7 putem folosi:

 use Framework\Module\{Foo, Bar, Baz};

Sau, dacă preferați un stil cu mai multe linii:

 use Framework\Module{ Foo, Bar, Baz };

Operator de coalescere nul

Aceasta rezolvă o problemă obișnuită în programarea PHP, în care dorim să atribuim o valoare unei variabile dintr-o altă variabilă, dacă aceasta din urmă este de fapt setată, sau altfel îi oferim o valoare diferită. Este folosit în mod obișnuit atunci când lucrăm cu intrare furnizată de utilizator.

Pre-PHP 7:

 if (isset($foo)) { $bar = $foo; } else { $bar = 'default'; // we would give $bar the value 'default' if $foo is NULL }

După PHP 7:

 $bar = $foo ?? 'default';

Aceasta poate fi, de asemenea, înlănțuită cu un număr de variabile:

 $bar = $foo ?? $baz ?? 'default';

Operator de navă spațială

Operatorul de navă spațială <=> permite o comparație în trei direcții între două valori, nu doar indicând dacă acestea sunt egale, ci și care dintre ele este mai mare, pe inegalitate, returnând 1,0 sau -1.

Aici putem lua diferite acțiuni în funcție de modul în care diferă valorile:

 switch ($bar <=> $foo) { case 0: echo '$bar and $foo are equal'; case -1: echo '$foo is bigger'; case 1: echo '$bar is bigger'; }

Valorile comparate pot fi numere întregi, flotanți, șiruri de caractere sau chiar matrice. Verificați documentația pentru a vă face o idee despre modul în care diferitele valori sunt comparate între ele. [https://wiki.php.net/rfc/combined-comparison-operator]

Caracteristici noi în PHP 7

Dar, desigur, PHP 7 aduce și funcționalități noi și interesante.

Tipuri de parametri scalari și indicații pentru tipul de returnare

PHP 7 extinde declarațiile de tip anterioare ale parametrilor în metode (clase, interfețe și tablouri) prin adăugarea celor patru tipuri scalare; Întregi ( int ), floats ( float ), boolean ( bool ) și șiruri ( string ) ca tipuri posibile de parametri.

În plus, putem specifica opțional ce metode și funcții de tip returnează. Tipurile acceptate sunt bool , int , float , string , array , callable , numele clasei sau al interfeței , self și parent ( pentru metodele clasei )

 class Calculator { // We declare that the parameters provided are of type integer public function addTwoInts(int $x, int $y): int { return $x + $y; // We also explicitly say that this method will return an integer } }

Declarațiile de tip permit construirea de aplicații mai robuste și evită transmiterea și returnarea valorilor greșite din funcții. Alte beneficii includ analizoare de cod static și IDE-uri, care oferă o perspectivă mai bună asupra bazei de cod dacă lipsesc DocBlocks.

Deoarece PHP este un limbaj tip slab, anumite valori pentru parametrii și tipurile de returnare vor fi turnate în funcție de context. Dacă trecem valoarea „3” într-o funcție care are un parametru declarat de tip int , interpretul o va accepta ca număr întreg și nu va arunca nicio eroare. Dacă nu doriți acest lucru, puteți activa strict mode adăugând o directivă declare .

declare(strict_types=1);

Acest lucru este setat pe bază de fișier, deoarece o opțiune globală ar împărți depozitele de cod în cele care sunt construite cu strictețe globală și cele care nu sunt, rezultând un comportament neașteptat atunci când combinăm codul din ambele.

Excepții ale motorului

Cu adăugarea de excepții ale motorului, erorile fatale care ar fi dus la terminarea scriptului pot fi detectate și gestionate cu ușurință.

Erorile, cum ar fi apelarea unei metode inexistente, nu vor termina scriptul, în schimb ele aruncă o excepție care poate fi gestionată de un bloc try catch, care îmbunătățește gestionarea erorilor pentru aplicațiile dvs. Acest lucru este important pentru anumite tipuri de aplicații, servere și demoni, deoarece erorile fatale ar necesita repornirea acestora. Testele din PHPUnit ar trebui, de asemenea, să devină mai utilizabile, deoarece erorile fatale renunță la întreaga suită de teste. Excepțiile, mai degrabă decât erorile, ar fi tratate în funcție de caz de testare.

PHP 7 adaugă un număr de noi clase de excepții bazate pe tipul de erori care ar putea fi întâlnite. Pentru a menține compatibilitatea între versiuni, a fost adăugată o nouă interfață Throwable care poate fi implementată atât din excepțiile de la motor, cât și din excepțiile utilizatorilor. Acest lucru a fost necesar pentru a evita excepțiile motorului pentru a extinde clasa de excepție de bază, rezultând excepții mai vechi de captare a codului care nu existau înainte.

Înainte de PHP 7, acest lucru ar fi terminat scriptul cu o eroare fatală:

 try { thisFunctionDoesNotEvenExist(); } catch (\EngineException $e) { // Clean things up and log error echo $e->getMessage(); }

Clasele anonime

Clasele anonime sunt veri ale funcțiilor anonime pe care le puteți utiliza într-o instanță simplă pe termen scurt. Clasele anonime sunt ușor create și utilizate la fel ca un obiect obișnuit. Iată un exemplu din documente.

Pre-PHP 7

 class MyLogger { public function log($msg) { print_r($msg . "\n"); } } $pusher->setLogger( new MyLogger() );

Cu clasa anonima:

 $pusher->setLogger(new class { public function log($msg) { print_r($msg . "\n"); } });

Clasele anonime sunt utile în testarea unitară, în special în batjocurarea obiectelor și serviciilor de testare. Acest lucru ne ajută să evităm bibliotecile și cadrele batjocoritoare grele prin crearea unui obiect simplu care oferă interfața pe care vrem să o batem joc.

Funcții CSPRNG

Au fost adăugate două funcții noi pentru generarea de șiruri și numere întregi securizate criptografic.

 random_bytes(int $len);

Returnează un șir aleatoriu cu lungimea $len .

 random_int(int $min, int $max);

Returnează un număr între $min și $max .

Sintaxa de evacuare Unicode Codepoint

Spre deosebire de multe alte limbi, înainte de PHP 7, PHP nu avea o modalitate de a scăpa de un punct de cod Unicode în literalele șir, . Această funcționalitate adaugă secvența de escape \u pentru a produce astfel de caractere folosind punctul lor de cod UTF-8. Acest lucru este mai bine decât inserarea directă a caracterelor, permițând o mai bună gestionare a caracterelor invizibile, precum și a caracterelor care au aceeași reprezentare grafică, dar care diferă ca semnificație.

echo "\u{1F602}"; // outputs ‚

Rețineți că acest lucru rupe codul existent cu secvența \u , deoarece schimbă comportamentul.

Generatoarele sunt actualizate

Generatoarele în PHP primesc și câteva caracteristici suplimentare frumoase. Acum, generatoarele au o instrucțiune return care poate fi folosită pentru a-i permite să scoată o valoare finală după iterație. Acest lucru poate fi folosit pentru a verifica dacă generatorul a fost executat fără erori și permite codului care a chemat generatorul să gestioneze diferite scenarii în mod corespunzător.

În plus, generatoarele pot reveni și pot genera expresii de la alți generatori. Acest lucru le permite să împartă operațiunile complexe în unități mai simple și modulare.

 function genA() { yield 2; yield 3; yield 4; } function genB() { yield 1; yield from genA(); // 'genA' gets called here and iterated over yield 5; return 'success'; // This is a final result we can check later } foreach (genB() as $val) { echo "\n $val"; // This will output values 1 to 5 in order } $genB()->getReturn(); // This should return 'success' when there are no errors.

Așteptări

Așteptările sunt o îmbunătățire a funcției assert() menținând în același timp compatibilitatea cu versiunea inversă. Acestea permit aserțiuni cu cost zero în codul de producție și oferă posibilitatea de a arunca excepții personalizate atunci când afirmația eșuează, ceea ce poate fi util în timpul dezvoltării.

assert() devine o construcție de limbaj în PHP 7. Aserțiunile ar trebui să fie folosite în scopuri de depanare numai în mediile de dezvoltare și testare. Pentru a-i configura comportamentul, ni se oferă două noi directive.

  • zend.assertions
    • 1 : generați și executați cod (modul de dezvoltare) (valoare implicită)
    • 0 : generează codul, dar sare în jurul lui în timpul rulării
    • -1 : nu generează cod, ceea ce îl face cu cost zero (mod de producție)
  • assert.exception
    • 1 : aruncați atunci când afirmația eșuează, fie prin aruncarea obiectului furnizat ca excepție, fie prin aruncarea unui nou obiect AssertionError dacă nu a fost furnizată excepția
    • 0 : utilizați sau generați un Throwable așa cum este descris mai sus, dar generați doar un avertisment bazat pe acel obiect, mai degrabă decât să îl aruncați (compatibil cu comportamentul PHP 5)

Pregătirea pentru a trece de la PHP 5 la PHP 7

Introducerea unei versiuni majore oferă posibilitatea de a schimba/actualiza funcționalitățile mai vechi sau chiar de a le elimina dacă sunt considerate prea vechi sau au fost depreciate de ceva timp. Astfel de modificări pot introduce întreruperi în compatibilitate în aplicațiile mai vechi.

O altă problemă care apare din astfel de salturi de versiune este că bibliotecile și cadrele importante de care depindeți este posibil să nu fi fost încă actualizate pentru a suporta cea mai recentă versiune. Echipa PHP a încercat să facă noile modificări cât mai compatibile cu înapoi și să permită ca migrarea către noua versiune să fie cât mai nedureroasă posibil. Aplicațiile mai noi și mai actualizate ar trebui să fie mai ușor să treacă la noua versiune, în timp ce aplicațiile mai vechi ar putea fi nevoite să decidă dacă beneficiile depășesc costul, eventual alegând să nu se actualizeze.

Cele mai multe pauze sunt minore și pot fi atenuate cu ușurință, în timp ce altele pot necesita mai mult efort și timp. Practic, dacă ați avut avertismente de depreciere în aplicația dvs. înainte de a instala PHP 7, probabil că veți primi erori care vor rupe aplicația până la remediere. Ai fost avertizat, nu?

SAPI-uri și extensii vechi

Cel mai important, SAPI-urile vechi și depreciate au fost eliminate ca extensia mysql (dar nu ar trebui să utilizați asta în primul rând, nu-i așa?). Pentru o listă completă a extensiilor și a caracteristicilor eliminate, puteți verifica aceste RFC-uri aici și aici.

În plus, alte SAPI-uri sunt portate la PHP 7.

O mulțime de vechi SAPI-uri și extensii au fost eliminate din PHP 7. Bănuim că acestea nu vor fi ratate.

Sintaxă variabilă uniformă

Această actualizare a adus unele modificări în favoarea consistenței pentru construcțiile variabile-variabile. Acest lucru permite expresii mai avansate cu variabile, dar introduce modificări de comportament în alte cazuri, așa cum se arată mai jos.

 // old meaning // new meaning $$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz'] $foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz'] $foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']() Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()

Acest lucru ar rupe comportamentul aplicațiilor care accesează astfel de valori. Pe de altă parte, puteți face niște chestii îngrijite ca acestea:.

 // Nested () foo()(); // Calls the return of foo() $foo->bar()(); // IIFE syntax like JavaScript (function() { // Function body })(); // Nested :: $foo::$bar::$baz

Etichetele de stil vechi au fost eliminate

Etichetele de deschidere/închidere <% ... %> , <%= ... %> , <script language="php"> ... </script> sunt eliminate și nu mai sunt valabile. Înlocuirea lor cu cele valide ar trebui să fie ușoară, dar ce faci oricum folosindu-le, Weirdo?

Nume nevalide pentru clase, interfețe și trăsături

Rezultate din adăugiri, cum ar fi tipurile de parametri și de returnare, clasele, interfețele și trăsăturile nu mai pot avea următoarele nume:

  • bool
  • int
  • pluti
  • şir
  • nul
  • Adevărat
  • fals

Acestea cauzează întreruperi aplicațiilor și bibliotecilor existente care le folosesc, dar ar trebui să fie ușor de remediat. De asemenea, deși nu provoacă nicio eroare și sunt valide, următoarele nu ar trebui folosite deoarece sunt rezervate pentru utilizare ulterioară:

  • resursă
  • obiect
  • amestecat
  • numeric

Abținerea de a le folosi ar trebui să vă scutească de munca de a le schimba în viitor.

Pentru o listă completă a modificărilor care ar rupe compatibilitatea, consultați acest document.

Puteți folosi, de asemenea, php7cc, care vă verifică codul și poate detecta eventualele probleme care pot apărea dacă treceți la PHP 7. Dar, desigur, nu există o modalitate mai bună decât să instalați PHP 7 și să vedeți singur.

Probleme potențiale de compatibilitate cu PHP 7

Compatibilitate cu infrastructura PHP 7

O mulțime de servicii de găzduire au început să adauge suport pentru PHP 7. Aceasta este o veste bună pentru furnizorii de găzduire partajată, deoarece câștigurile de performanță le vor permite să crească numărul de site-uri web ale clienților pe hardware-ul lor, reducându-și cheltuielile de operare și sporindu-și marjele. În ceea ce privește clienții înșiși, aceștia nu ar trebui să se aștepte la un impuls prea mare în aceste condiții, dar, pentru a fi corect, găzduirea partajată nu este oricum o alegere orientată spre performanță.

Pe de altă parte, serviciile care oferă servere private virtuale sau servere dedicate vor culege toate beneficiile acestei creșteri de performanță. Unele servicii PaaS precum Heroku au suportat PHP 7 de la început, dar alte servicii, precum AWS Beanstalk și OpenShift de la Oracle, rămân în urmă. Verificați site-ul web al furnizorului dvs. PaaS pentru a vedea dacă PHP 7 este deja acceptat sau dacă asistența va veni în viitorul apropiat.

Desigur, furnizorii IaaS vă permit să preluați controlul asupra hardware-ului și să instalați PHP 7 (sau să compilați dacă vă place mai mult). Pachetele PHP 7 sunt deja disponibile pentru mediile majore IaaS.

Compatibilitate software PHP 7

Pe lângă compatibilitatea cu infrastructura, trebuie să fiți atenți și la potențialele probleme de compatibilitate software. Sistemele populare de gestionare a conținutului, cum ar fi WordPress, Joomla și Drupal, au adăugat suport pentru PHP 7 cu cele mai recente versiuni. Cadrele majore precum Symfony și Laravel se bucură, de asemenea, de suport complet.

Cu toate acestea, este timpul pentru un cuvânt de precauție. Acest suport nu se extinde la codul terță parte sub formă de suplimente, pluginuri, pachete sau orice le numește CMS-ul sau cadrul dvs. Ei pot suferi de probleme de compatibilitate și este responsabilitatea dumneavoastră să vă asigurați că totul este pregătit pentru PHP 7.

Pentru depozitele active, întreținute, aceasta nu ar trebui să fie o problemă. Cu toate acestea, arhivele mai vechi și neîntreținute, fără suport PHP 7, ar putea face întreaga aplicație inutilizabilă.

Viitorul PHP

Lansarea PHP 7 a eliminat codul vechi și învechit și a deschis calea pentru noi funcții și îmbunătățiri de performanță în viitor. În plus, PHP este de așteptat să obțină optimizări suplimentare de performanță în curând. În ciuda unor întreruperi de compatibilitate cu versiunile anterioare, majoritatea problemelor sunt ușor de rezolvat.

Bibliotecile și cadrele își migrează acum codul la PHP 7, făcând astfel disponibile cele mai recente versiuni. Vă încurajez să îl încercați și să vedeți singuri rezultatele. Poate că aplicația dvs. este deja compatibilă și așteaptă să utilizeze și să beneficieze de PHP 7.

Înrudit: Lista celor mai frecvente 10 greșeli pe care le fac dezvoltatorii PHP