Introduzione a PHP 7: cosa c'è di nuovo e cosa non c'è più

Pubblicato: 2022-03-11

Uno degli eventi più emozionanti del 2015 nel mondo PHP è stato il rilascio di PHP 7, a 10 anni dal rilascio dell'ultima versione principale, PHP 5. Con un importante passo avanti, PHP 7 introduce molte nuove funzionalità e miglioramenti delle prestazioni .

Tuttavia, rimuove anche la vecchia funzionalità deprecata, che introduce alcune interruzioni di compatibilità, rendendo più difficile la migrazione delle applicazioni precedenti alla nuova versione. Questa guida dovrebbe servire come un rapido tour di cosa aspettarti se prevedi di spostare le tue applicazioni esistenti o di crearne di nuove oltre a PHP 7.

Ma aspetta, dove è finito PHP 6?

Se ultimamente non hai lavorato con PHP, potresti chiederti cosa è successo a PHP 6, perché saltare da PHP 5 a PHP 7? Bene, per farla breve, PHP 6 è stato un fallimento. La caratteristica principale della versione 6 era il supporto nativo per i caratteri Unicode poiché PHP è utilizzato principalmente nello sviluppo web e il web ha bisogno di Unicode, quindi il passaggio a portare Unicode in PHP aveva senso.

L'idea era di portare il supporto completo per Unicode nel core stesso. Avrebbe portato funzionalità estese al linguaggio, dalla possibilità di utilizzare emoji stupidi come nomi di variabili e funzioni, a potenti funzionalità di stringhe internazionali. Ad esempio, quando un'altra lingua utilizza lettere maiuscole e minuscole in modo diverso dall'inglese o quando un nome in caratteri cinesi deve essere convertito in inglese.

Sfortunatamente, questo piano ambizioso si è rivelato un problema più grande del previsto. Gran parte della base di codice doveva essere trasferita per supportare Unicode sia per le estensioni principali che per quelle importanti, il che si è rivelato noioso e complicato. Ciò ha rallentato lo sviluppo di altre funzionalità del linguaggio, frustrando molti sviluppatori PHP nel processo. Sono emersi ulteriori ostacoli, che hanno portato a un minore interesse nello sviluppo di un supporto Unicode nativo, portando infine all'abbandono del progetto.

Poiché risorse, come libri e articoli, erano state scritte per PHP 6 e il suo supporto Unicode, la nuova versione sarebbe stata rinominata PHP 7 per evitare confusione.

Comunque, basta soffermarsi sul triste passato, vediamo cosa porta PHP 7 alla festa.

Battaglia delle prestazioni, PHP 7 contro PHP 5

Con praticamente tutti gli aggiornamenti, sono previsti miglioramenti minori delle prestazioni. Tuttavia, questa volta PHP apporta un miglioramento significativo rispetto alle versioni precedenti, rendendo le prestazioni pure una delle caratteristiche più interessanti di PHP 7. Questo fa parte del progetto "PHPNG", che affronta gli interni dello stesso Zend Engine.

Con il refactoring delle strutture dati interne e l'aggiunta di un passaggio intermedio alla compilazione del codice sotto forma di Abstract Syntax Tree (AST), il risultato sono prestazioni superiori e un'allocazione della memoria più efficiente. I numeri stessi sembrano molto promettenti; i benchmark effettuati sulle app del mondo reale mostrano che PHP 7 è in media due volte più veloce di PHP 5.6 e comporta un consumo di memoria inferiore del 50% durante le richieste, rendendo PHP 7 un forte rivale per il compilatore HHVM JIT di Facebook. Dai un'occhiata a questa infografica di Zend che illustra le prestazioni di alcuni CMS e Framework comuni.

Immagine: illustrazione delle prestazioni di PHP 7 rispetto a PHP 5.

La diminuzione del consumo di memoria consente anche alle macchine più piccole di gestire meglio le richieste insieme all'opportunità di creare microservizi attorno a PHP. Le modifiche interne, in particolare l'implementazione dell'AST, aprono anche possibilità per ottimizzazioni future che potrebbero spingere ulteriormente le prestazioni. Per le versioni future è allo studio una nuova implementazione interna di un compilatore JIT.

Zucchero sintattico PHP 7

PHP 7 viene fornito con nuove funzionalità di sintassi. Pur non estendendo le capacità del linguaggio stesso, forniscono un modo migliore o più semplice per rendere il codice più piacevole da scrivere e piacevole alla vista.

Dichiarazioni di importazione di gruppo

Ora possiamo raggruppare le dichiarazioni di importazione per le classi originate dallo stesso spazio dei nomi in una riga a use singolo. Questo dovrebbe aiutare ad allineare le dichiarazioni in modo significativo o semplicemente a salvare alcuni byte nei tuoi file.

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

Con PHP 7 possiamo usare:

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

Oppure, se preferisci uno stile multilinea:

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

Operatore di coalescenza nullo

Questo risolve un problema comune nella programmazione PHP, dove vogliamo assegnare un valore a una variabile da un'altra variabile, se quest'ultima è effettivamente impostata, o altrimenti fornire un valore diverso per essa. È comunemente usato quando lavoriamo con l'input fornito dall'utente.

Pre-PHP 7:

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

Dopo PHP 7:

 $bar = $foo ?? 'default';

Questo può anche essere concatenato con un numero di variabili:

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

Operatore dell'astronave

L'operatore astronave <=> consente un confronto a tre vie tra due valori, indicando non solo se sono uguali, ma anche quale è più grande, sulla disuguaglianza restituendo 1,0 o -1.

Qui possiamo intraprendere diverse azioni a seconda di come differiscono i valori:

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

I valori confrontati possono essere interi, float, stringhe o anche array. Consulta la documentazione per avere un'idea di come i diversi valori vengono confrontati tra loro. [https://wiki.php.net/rfc/combined-comparison-operator]

Nuove funzionalità in PHP 7

Ma ovviamente PHP 7 porta con sé anche nuove ed entusiasmanti funzionalità.

Tipi di parametri scalari e suggerimenti sui tipi restituiti

PHP 7 estende le precedenti dichiarazioni di tipo dei parametri nei metodi (classi, interfacce e array) aggiungendo i quattro tipi scalari; Interi ( int ), float ( float ), booleani ( bool ) e stringhe ( string ) come possibili tipi di parametri.

Inoltre, possiamo specificare facoltativamente quale tipo di metodi e funzioni restituiscono. I tipi supportati sono bool , int , float , string , array , callable , name of Class o Interface , self e parent (per i metodi di classe)

 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 } }

Le dichiarazioni di tipo consentono la creazione di applicazioni più robuste ed evitano di passare e restituire valori errati dalle funzioni. Altri vantaggi includono analizzatori di codice statico e IDE, che forniscono informazioni migliori sulla base di codice se mancano DocBlock.

Poiché PHP è un linguaggio debolmente tipizzato, alcuni valori per i tipi di parametri e restituiti verranno trasmessi in base al contesto. Se passiamo il valore "3" in una funzione che ha un parametro dichiarato di tipo int , l'interprete lo accetterà come intero e non genererà alcun errore. Se non lo desideri, puoi abilitare strict mode aggiungendo una direttiva declare .

declare(strict_types=1);

Questo è impostato in base al file, poiché un'opzione globale dividerebbe i repository di codice in quelli che sono costruiti con rigore globale e quelli che non lo sono, risultando in un comportamento imprevisto quando combiniamo il codice di entrambi.

Eccezioni motore

Con l'aggiunta delle eccezioni del motore, gli errori irreversibili che avrebbero portato alla chiusura dello script possono essere rilevati e gestiti facilmente.

Errori come la chiamata di un metodo inesistente non terminano lo script, ma generano un'eccezione che può essere gestita da un blocco try catch, che migliora la gestione degli errori per le tue applicazioni. Questo è importante per alcuni tipi di app, server e demoni perché gli errori irreversibili richiederebbero altrimenti il ​​riavvio. I test in PHPUnit dovrebbero anche diventare più utilizzabili poiché gli errori fatali eliminano l'intera suite di test. Le eccezioni, anziché gli errori, verrebbero gestite in base al caso di test.

PHP 7 aggiunge una serie di nuove classi di eccezioni in base al tipo di errori che potrebbero verificarsi. Per mantenere la compatibilità tra le versioni, è stata aggiunta una nuova interfaccia Throwable che può essere implementata sia dalle eccezioni del motore che dalle eccezioni dell'utente. Ciò era necessario per evitare eccezioni del motore per estendere la classe di eccezioni di base, risultando in vecchie eccezioni di cattura del codice che prima non c'erano.

Prima di PHP 7 questo avrebbe terminato lo script con un errore fatale:

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

Classi anonime

Le classi anonime sono cugine di funzioni anonime che potresti utilizzare in una semplice istanza a breve termine. Le classi anonime possono essere facilmente create e utilizzate proprio come un normale oggetto. Ecco un esempio dai documenti.

Pre-PHP 7

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

Con classe anonima:

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

Le classi anonime sono utili negli unit test, in particolare per simulare oggetti e servizi di test. Questo ci aiuta a evitare pesanti librerie e framework di derisione creando un semplice oggetto che fornisce l'interfaccia che vogliamo deridere.

Funzioni CSPRNG

Sono state aggiunte due nuove funzioni per la generazione di stringhe e numeri interi crittograficamente sicuri.

 random_bytes(int $len);

Restituisce una stringa casuale con lunghezza $len .

 random_int(int $min, int $max);

Restituisce un numero compreso tra $min e $max .

Sintassi di escape Unicode Codepoint

A differenza di molti altri linguaggi, prima di PHP 7, PHP non aveva un modo per sfuggire a un codepoint Unicode in stringhe letterali, . Questa funzionalità aggiunge la sequenza di escape \u per produrre tali caratteri usando il loro codepoint UTF-8. Questo è meglio che inserire direttamente i caratteri, consentendo una migliore gestione dei caratteri invisibili e dei caratteri che hanno la stessa rappresentazione grafica ma differiscono nel significato.

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

Nota che questo interrompe il codice esistente con la sequenza \u perché cambia il comportamento.

I generatori vengono aggiornati

I generatori in PHP ottengono anche alcune belle funzionalità aggiuntive. Ora, i generatori hanno un'istruzione return che può essere utilizzata per consentirgli di produrre un valore finale dopo l'iterazione. Questo può essere utilizzato per verificare che il generatore sia stato eseguito senza errori e consente al codice che ha chiamato il generatore di gestire i vari scenari in modo appropriato.

Inoltre, i generatori possono restituire e produrre espressioni da altri generatori. Ciò consente loro di dividere operazioni complesse in unità più semplici e modulari.

 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.

Aspettative

Le aspettative sono un miglioramento della funzione assert() pur mantenendo la compatibilità con le versioni precedenti. Consentono asserzioni a costo zero nel codice di produzione e offrono la possibilità di generare eccezioni personalizzate quando l'asserzione ha esito negativo, il che può essere utile durante lo sviluppo.

assert() diventa un costrutto del linguaggio in PHP 7. Le asserzioni dovrebbero essere usate a scopo di debug solo negli ambienti di sviluppo e test. Per configurarne il comportamento, ci vengono fornite due nuove direttive.

  • zend.assertions
    • 1 : genera ed esegue codice (modalità sviluppo) (valore predefinito)
    • 0 : genera il codice ma lo aggira in fase di esecuzione
    • -1 : non genera codice rendendolo a costo zero (modalità di produzione)
  • assert.exception
    • 1 : lancia quando l'asserzione fallisce, generando l'oggetto fornito come eccezione o generando un nuovo oggetto AssertionError se l'eccezione non è stata fornita
    • 0 : usa o genera un Throwable come descritto sopra, ma genera solo un avviso basato su quell'oggetto anziché lanciarlo (compatibile con il comportamento di PHP 5)

Prepararsi a passare da PHP 5 a PHP 7

L'introduzione di una versione principale offre l'opportunità di modificare/aggiornare funzionalità precedenti o addirittura rimuoverle se sono ritenute troppo vecchie o sono state deprecate da tempo. Tali modifiche possono introdurre interruzioni nella compatibilità nelle applicazioni precedenti.

Un altro problema che sorge da tali salti di versione è che importanti librerie e framework da cui dipendi potrebbero non essere stati ancora aggiornati per supportare l'ultima versione. Il team di PHP ha cercato di rendere le nuove modifiche il più possibile compatibili con le versioni precedenti e di consentire la migrazione alla nuova versione il più indolore possibile. Le app più recenti e aggiornate dovrebbero trovare più facile passare alla nuova versione, mentre le app meno recenti potrebbero dover decidere se i vantaggi superano il costo, eventualmente scegliendo di non aggiornare.

La maggior parte delle interruzioni sono minori e possono essere mitigate facilmente, mentre altre potrebbero richiedere più tempo e fatica. Fondamentalmente, se avevi avvisi di deprecazione nella tua applicazione prima di installare PHP 7, probabilmente otterrai errori che interromperanno l'applicazione fino a quando non verranno corretti. Sei stato avvisato, vero?

Vecchi SAPI ed estensioni

Soprattutto, le SAPI vecchie e deprecate sono state rimosse come l'estensione mysql (ma non dovresti usarla in primo luogo, giusto?). Per un elenco completo delle estensioni e delle funzionalità rimosse puoi controllare queste RFC qui e qui.

Inoltre, altri SAPI vengono trasferiti su PHP 7.

Un sacco di vecchie SAPI ed estensioni sono state eliminate da PHP 7. Immaginiamo che non mancheranno.

Sintassi variabile uniforme

Questo aggiornamento ha apportato alcune modifiche a favore della coerenza per le costruzioni variabile-variabile. Ciò consente espressioni più avanzate con variabili ma introduce modifiche nel comportamento in altri casi, come mostrato di seguito.

 // 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']()

Ciò interromperebbe il comportamento delle applicazioni che accedono a valori come questo. D'altra parte, puoi fare alcune cose belle come questa:.

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

Tag vecchio stile rimossi

I tag di apertura/chiusura <% ... %> , <%= ... %> , <script language="php"> ... </script> vengono rimossi e non sono più validi. Sostituirli con quelli validi dovrebbe essere facile, ma cosa ci fai comunque usandoli, Strano?

Nomi non validi per classi, interfacce e tratti

Risultato di aggiunte come parametri e tipi restituiti classi, interfacce e tratti non possono più avere i seguenti nomi:

  • bollo
  • int
  • galleggiante
  • corda
  • nullo
  • vero
  • falso

Questi causano interruzioni alle applicazioni e alle librerie esistenti che li utilizzano, ma dovrebbero essere facili da risolvere. Inoltre, sebbene non causino alcun errore e siano validi, non devono essere utilizzati i seguenti in quanto riservati per un uso futuro:

  • risorsa
  • oggetto
  • misto
  • numerico

Astenersi dall'usarli dovrebbe risparmiarti il ​​​​lavoro di cambiarli in futuro.

Per un elenco completo delle modifiche che interromperebbero la compatibilità, consulta questo documento.

Puoi anche usare php7cc, che controlla il tuo codice e può rilevare eventuali problemi che potrebbero emergere se passi a PHP 7. Ma ovviamente, non c'è modo migliore che installare PHP 7 e vedere di persona.

Potenziali problemi di compatibilità con PHP 7

Compatibilità con l'infrastruttura PHP 7

Molti servizi di hosting hanno iniziato ad aggiungere il supporto per PHP 7. Questa è una buona notizia per i provider di hosting condiviso, poiché i miglioramenti delle prestazioni consentiranno loro di aumentare il numero di siti Web client sul proprio hardware, riducendo le spese operative e aumentando i margini. Per quanto riguarda i clienti stessi, non dovrebbero aspettarsi una spinta eccessiva in queste condizioni, ma ad essere onesti, l'hosting condiviso non è comunque una scelta orientata alle prestazioni.

D'altra parte, i servizi che offrono server privati ​​virtuali o server dedicati raccoglieranno tutti i vantaggi di questo aumento delle prestazioni. Alcuni servizi PaaS come Heroku hanno supportato PHP 7 all'inizio, ma altri servizi, come AWS Beanstalk e Oracle OpenShift, sono in ritardo. Controlla il sito Web del tuo provider PaaS per vedere se PHP 7 è già supportato o se il supporto arriverà nel prossimo futuro.

Naturalmente, i provider IaaS ti consentono di assumere il controllo dell'hardware e installare PHP 7 (o compilare se è più di tuo gradimento). I pacchetti PHP 7 sono già disponibili per i principali ambienti IaaS.

Compatibilità software PHP 7

Oltre alla compatibilità dell'infrastruttura, devi anche prestare attenzione ai potenziali problemi di compatibilità del software. I popolari sistemi di gestione dei contenuti come WordPress, Joomla e Drupal hanno aggiunto il supporto per PHP 7 con le loro ultime versioni. Anche i principali framework come Symfony e Laravel godono di pieno supporto.

Tuttavia, è tempo di una parola di cautela. Questo supporto non si estende al codice di terze parti sotto forma di componenti aggiuntivi, plug-in, pacchetti o come li chiama il tuo CMS o framework. Potrebbero soffrire di problemi di compatibilità ed è tua responsabilità assicurarti che tutto sia pronto per PHP 7.

Per i repository attivi e mantenuti, questo non dovrebbe essere un problema. Tuttavia, i repository meno recenti e non mantenuti privi del supporto per PHP 7 potrebbero rendere inutilizzabile l'intera app.

Il futuro di PHP

Il rilascio di PHP 7 ha rimosso il codice vecchio e obsoleto e ha aperto la strada a nuove funzionalità e miglioramenti delle prestazioni in futuro. Inoltre, si prevede che PHP ottenga presto ulteriori ottimizzazioni delle prestazioni. Nonostante alcune interruzioni di compatibilità con le versioni precedenti, la maggior parte dei problemi è facile da risolvere.

Librerie e framework stanno ora migrando il loro codice a PHP 7 rendendo così disponibili le ultime versioni. Ti incoraggio a provarlo e vedere i risultati di persona. Forse la tua applicazione è già compatibile e in attesa di utilizzare e beneficiare di PHP 7.

Correlati: l'elenco dei 10 errori più comuni commessi dagli sviluppatori PHP