Cosa c'è di nuovo in PHP 8: tutto quello che devi sapere!
Pubblicato: 2021-01-06Ci metteremo in contatto con PHP8 il 26 novembre 2020 e, di certo, c'è molto da scrivere sulle funzionalità in arrivo in questa apprezzata versione.
Poiché si tratta di una versione principale, ci saranno modifiche sostanziali e nuove funzionalità, oltre a rendere importante essere consapevoli di ciò che tutto sta cambiando. Sarà conveniente pensare a come PHP8 influirà sulle tue app e quali azioni saranno necessarie per essere sicuri di poter aggiornare comodamente senza incidenti.
Abbiamo esaminato alcune delle modifiche più importanti per capire cosa otterremo nella prossima versione di PHP e cosa vale la pena criticare.
iniziamo con la panoramica!
Panoramica di PHP 8
Come accennato in precedenza, PHP 8 introduce un pacchetto di nuove funzionalità, miglioramenti, funzioni e deprecazioni al linguaggio. Tra tutte, la caratteristica più discussa è il compilatore JIT. Tuttavia, le funzionalità di miglioramento delle prestazioni come JIT meritano le luci della ribalta, ma ci si aspetta che i miglioramenti sintattici abbiano più di un vero successo per i professionisti di PHP, diremmo, "almeno a breve termine".
Una storia di cambiamento
Alcune modifiche PHP vengono proposte, discusse, implementate e ulteriormente approvate in breve tempo. Sono popolari, non controversi e hanno un metodo naturale per implementarli.
E dopo vengono quelli che vengono provati, falliscono e ritornano più volte prima che li accettiamo finalmente. Alcune volte, l'implementazione richiede molto tempo per essere risolta, e talvolta l'idea stessa è solo a metà, e talvolta la comunità stessa non si è ancora riscaldata all'idea: "non è ancora il momento".
I crediti rientrano esattamente nella categoria del tipo. Sono stati proposti per la prima volta nell'anno 2016 per PHP 7.1. Tuttavia, hanno incontrato una resistenza ostinata e hanno perso il voto di accettazione con un ampio margine. Ora, avanti veloce di quattro anni, e una proposta abbastanza simile, anche se di portata leggermente ridotta, è arrivata con un solo dissidente. Evidentemente è un'idea il cui momento è sicuramente arrivato!
Quali sono i problemi con il vecchio codice?
Poiché PHP 8 è un'enorme nuova versione, dovremmo aspettarci che il vecchio codice non sia più compatibile. Tuttavia, la maggior parte delle modifiche che potrebbero proporre complicazioni erano già state trasmesse nelle versioni 7.2 , 7.3 e 7.4 . Parliamo ora delle ultime modifiche. Loro sono:
Eredità di citazioni magiche
- Il vero tipo
- FILTER_SANITIZE_MAGIC_QUOTES filtro
- Disassociare $this da chiusure non statiche
- array_key_exists() con oggetti
- mb_strrpos() con codifica come 3° argomento
- Metodi Reflection export()
- convert_cyr_string()
- implode() mix di ordine dei parametri
- funzione restore_include_path()
- funzione hebrevc()
- funzione formato_denaro()
- allow_url_include direttiva ini
- ezmlm_hash()
Nuove funzioni in PHP 8
str_contain
Se una stringa ne contiene un'altra, ci sono molti modi per scoprirlo.
In genere, utilizzerai strpos(). Come sai, strpos() prende un pagliaio accanto all'ago che desideri cercare. Restituisce un numero intero che mostra la prima posizione in cui si vede l'ago.
Ora, poiché sta restituendo la posizione di una stringa in un'altra, semplicemente non puoi verificare se strpos() l'ha scoperta o meno; se restituisce "0" (le posizioni sono indicizzate a zero e iniziano con 0 anziché 1), il condizionale lo tratterà come un valore falso e indicherà che non è stato trovato.
Che cosa significa?
Dovrai scrivere il condizionale –“strpos($pagliaio, $ago) !== false.” False indica che non è stato possibile trovare la posizione della stringa. Questo è un metodo non trasparente ed esoterico per cercare una stringa in una stringa! Beh, non così confuso.
Per evitare ciò, PHP 8 porta str_contains(). Il compito di str_contains() è restituire un semplice booleano che mostra se l'ago è presente o meno nel pagliaio. È molto più facile da scrivere, oltre a ciò, capisci come qualcuno che mantiene il codice, vero?
if (str_contains( 'Foo Bar Baz' , 'Foo' )) { // FOUND }
PHP 8: Funzionalità e modifiche del motore
Ci sono alcune nuove funzionalità del motore e modifiche notate in PHP 8. La caratteristica principale, senza dubbio, è il nuovo compilatore JIT.
Compilatore JIT
- Applicazione LSP
- Errori irreversibili su firme di metodi incompatibili
- Risorsa "Classi"
- XML-RPC è ora in PECL
- Comportamento di affermazione
- La riflessione cambia
Per il bene dello scopo principale di questo blog, ci concentreremo sul compilatore JIT, sulle "classi" di risorse e, infine, sulle modifiche dell'API di riflessione.
Compilatore just-in-time ( RFC )
A causa dei miglioramenti di velocità apportati prima del rilascio di PHP7, è avvenuta la nascita del compilatore Just-In-Time (o JIT). È stato introdotto in PHP8 perché non ci sono quasi più miglioramenti nella velocità che possono essere apportati senza utilizzare un JIT. L'idea è che migliorerà le prestazioni di PHP.
Il codice PHP viene tradotto in bytecode quando viene eseguito e tali bytecode vengono ulteriormente utilizzati per eseguire i passaggi del programma.
PHP analizzerà il codice che hai eseguito, ecco cosa significa JIT. Inoltre, può prendere decisioni in tempo reale diverse dai miglioramenti delle prestazioni sul codice durante l'esecuzione. Sarà altamente utilizzabile in applicazioni ad alta intensità di CPU e non solo se utilizzato in scenari basati sul Web.
Ciò riflette le applicazioni PHP lato server che sicuramente possono essere più prevalenti con il sistema JIT integrato in PHP.
Devi prima attivare JIT se vuoi usarlo. Sul nostro sistema di test (Ubuntu 20.04), abbiamo già installato il modulo PHP opcache, che abbiamo installato con il pacchetto principale PHP8. Abbiamo configurato nel file posto in /etc/php/8.0/cli/conf.d/10-opcache.ini.
Ora sei pronto per attivare JIT, giusto?
- Abilita l'opcache
È possibile assegnare memoria all'impostazione opcache.jit_buffer_size . Il tuo file apparirà in questo modo sul mio sistema.
- zend_extension=opcache.so
- opcache.enable_cli=1
- ; configurazione per il modulo php opcache
- opacache.jit_buffer_size=256M
Inoltre usa la funzione opcache_get_status() per assicurarti che sia attiva. Sposta lo sguardo sulla parte "jit" di questo array e ottieni informazioni sullo stato attuale di JIT.
var_dump(opcache_get_status()['jit']);
Se JIT è stato attivato perfettamente, questo dovrebbe essere stampato come mostrato laggiù.
- matrice(7) {
- [“abilitato”]=>
- bool (vero)
- [“acceso”]=>
- bool (vero)
- [“gentile”]=>
- int(5)
- [“livello_opt”]=>
- int(4)
- [“opt_flags”]=>
- int(6)
- [“dimensione_buffer”]=>
- int(268435440)
- [“senza buffer”]=>
- int(268432880)
- }
Quindi è stato più veloce? In una parola, esclameremo un caloroso "sì".
Abbiamo notato che alcune persone eseguono benchmark con l'aiuto di un set di mandelbrot, quindi abbiamo deciso di utilizzare una libreria che abbiamo creato qualche tempo fa che disegna diversi tipi di frattali in PHP. Tutto ciò che abbiamo fatto è stato generare tre frattali e tenere traccia del tempo impiegato utilizzando la funzione microtome(). Di seguito abbiamo mostrato i risultati per PHP 7.4.8.
- Burningship – 84.20269203186
- Mandlebrot – 21.552599906921
- Tricorno – 32.685042858124
Quando abbiamo eseguito lo stesso codice su PHP8, è stato piuttosto più veloce. I numeri parleranno da soli. .
- Burningship – 15.272277116776
- Mandlebrot -3.7528541088104
- Tricorno -4.4957919120789
Questo enorme aumento di velocità è piuttosto interessante. Il codice che abbiamo usato qui crea frattali di dimensioni enormi, ma ricordiamo durante la creazione del codice che la maggior parte del nostro tempo è stato speso in attesa della generazione dei frattali.
Questa aggiunta è interessante per noi poiché in alcune occasioni abbiamo spinto PHP ai suoi limiti (al di fuori della generazione di frattali). Possiamo notare che questo è di grande beneficio per il futuro di PHP e consentirà di scegliere la lingua per situazioni al di fuori della normale lingua del sito web.
Non abbiamo esaminato l'incremento di velocità per app come WordPress o Drupal, ma da quello che abbiamo letto, c'è sicuramente poca differenza in questo tipo di applicazioni. In futuro, eseguiremo benchmark su queste piattaforme per capire che tipo di differenza segna la JIT.
Tipi di unione ( RFC )
Da PHP7, è stato possibile stabilire che tipo di valori di ritorno e tipi di argomenti e sono stati possibili. Ciò consentirà a PHP di generare un errore nel caso in cui il tipo di argomento che stai passando sia un ordinamento non identico al tipo previsto. È fondamentale garantire che le funzioni ricevano e producano i tipi di valore perfetti in un linguaggio tipizzato in modo approssimativo come PHP.
In PHP8 è ora possibile stabilire vari tipi di argomenti e valori di ritorno, divisi da un carattere pipe.
Di seguito abbiamo mostrato una funzione in grado di accettare un valore float o intero.
function addNumbers(int|float $number1, int|float $number2) : int|float { return $number1 + $number2; }
In precedenza, una funzione identica a questa richiedeva di essere generata senza alcun suggerimento sul tipo perché PHP poteva mostrare silenziosamente il tipo nel caso in cui l'argomento passato non fosse corretto. Significava che nel caso in cui avessimo impostato il tipo di argomento come intero, PHP avrebbe mostrato qualsiasi valore float in un intero. Può certamente portare ad alcuni bug difficili da rilevare nel caso in cui non si stia effettuando il test di unità.

Lo chiamiamo semplicemente come qualsiasi altro per utilizzare la funzione sopra
echo addNumbers(1, 1); // prints 2 echo addNumbers(1.1, 1.1); // prints 2.2
Nel caso in cui proviamo a passare una stringa alla funzione identica:
echo addNumbers('one', 'two');
Riceveremo un errore irreversibile PHP che esclama che dobbiamo passare un float o un "int" nella funzione.
Non è possibile utilizzare il tipo void come tipo union perché stabilisce che la funzione non restituirà nulla. In parole semplici, non puoi esclamare che una funzione restituirà un vuoto o un intero; riceverai un errore fatale PHP.
Sebbene sia una normale modifica, possiamo vedere che questa funzione è stata utilizzata un po 'in quanto in precedenza era stato possibile stabilire solo vari tipi di valore nei commenti, il che ha portato i commenti del blocco doc a diventare più dettagliati del codice.
L'operatore Nullsafe (RFC)
Oltre all'operatore di coalescenza nullo, la capacità di rilevare valori restituiti null è possibile direttamente dai metodi. Se non eri a conoscenza, l'operatore di coalescenza nullo ti consente di ottenere un valore e non devi testare nel caso in cui il valore sia presente oltre a restituire un valore diverso nel caso in cui il primo valore sia nullo.
Quindi, possiamo farlo per ottenere un valore da - "$_GET superglobale". e nel caso in cui quel valore non sia presente, allora "0".
1. $page = $_GET['page'] ?? 0;
2. eco $pagina;
Il funzionamento dell'operatore null safe è lo stesso, ma consente di creare una comoda scorciatoia e verificare un ritorno null da un modo prima di provare a utilizzare quel valore.
Abbiamo notato che questo sarà in definitiva utile in Drupal, dove tendiamo a scrivere gran parte del codice di controllo per garantire che i "ritorni dai metodi" o le "proprietà degli oggetti" contengano elementi prima di utilizzarli. Questo è obbligatorio a causa dello stato contestuale degli oggetti in Drupal a causa del contenuto che contengono. Questa modifica semplificherà sicuramente alcuni dei controlli.
Argomenti denominati ( RFC )
Gli argomenti con nome consentono di stabilire un diverso ordine di argomenti e funzioni di chiamata. Prendi la seguente funzione normale che ha due parametri. Riempie un array per la lunghezza data.
function fillArray(array $arrayToFill, int $number) : array { for ($i = 0 $i < $number; ++$i) { $arrayToFill[$i] =1; } return $arrayToFill; }
Possiamo passare gli argomenti nella disposizione in cui sono definiti possiamo chiamare questa tecnica nel modo normale.
$newArray = fillArray([], 2);
A partire da PHP8 ora puoi nominare i parametri mentre li passi alla funzione. Ti consente anche di inviare i parametri nell'ordine che desideriamo.
$newArray = fillArray(number: 2, arrayToFill: []);
Un esempio normale, ma può anche rendere il codice più leggibile.
Questa tecnica funziona con tutte le funzioni in PHP, non solo quelle definite dall'utente. Nel linguaggio PHP, le funzioni array e string hanno ordini di parametri non identici. Quindi, è un'aggiunta davvero gradita.
Attributi V2 ( RFC1 RFC2 RFC3 )
Gli attributi forniscono un meccanismo per collegare i metadati a classi, funzioni, proprietà di classe, parametri di funzione e costanti PHP. Non possono essere direttamente accessibili tramite codice e devi estrarli con l'aiuto delle classi di riflessione integrate in PHP.
La classe ReflectionClass è in PHP da PHP5; tuttavia, il metodo getAttribute() è nuovo per PHP8. Questo metodo restituisce un intervallo di oggetti ReflectionAttribute che includeranno informazioni sugli attributi.
Questa aggiunta ha subito alcune modifiche (come possiamo notare dalle molteplici RFC sopra). Nel caso in cui si istanzia la classe, è quindi possibile utilizzare ReflectionClass e stampare le informazioni sugli attributi contenute a livello di classe. C'è un bel po' di attributi in PHP8, quindi ti consigliamo di leggere le RFC e familiarizzare con ciò che sono effettivamente e come integrarle nel tuo codice.
Espressione di corrispondenza ( RFC )
In PHP 8, possiamo confrontare la nuova espressione di corrispondenza con un'istruzione switch abbreviata.
Sembra un po' come una dichiarazione di funzione che restituirà un valore sulla base del valore passato.
L'istruzione switch in PHP è sorprendente quando si desidera verificare la condizione sull'espressione identica senza includere più istruzioni if
del tutto.
Qui portiamo un confronto di base se-altro su un'espressione identica.
<?php if ($i == 'apple') { echo 'i is apple'; } elseif ($i == 'cake') { echo 'i is cake'; } else { echo 'i is pizza'; }
Ed ecco come apparirebbe l'equivalente istruzione switch
del nostro esempio precedente
<?php switch ($i) { case 'apple': echo 'i is apple'; break; case 'cake': echo 'i is cake'; break; default: echo 'i is pizza'; }
Risorsa "Classi"
Le "classi" di risorse rientrano nell'elenco delle principali modifiche in PHP 8 e fungono da sostituzioni non istanziabili per determinati tipi di risorse. Vedi sotto per sapere che le sostituzioni disponibili includono:
- CurlHandle — curl_init() ora restituisce CurlHandle, mettendo in relazione una risorsa curl.
- Socket / AddressInfo — Fornito dall'estensione socket; la quantità delle funzioni socket_*() restituisce un Socket, mentre la funzione socket_address_info_lookup() restituisce un'istanza AddressInfo.
- GdImage — Rappresenta una risorsa GD, come ripristinata dalle numerose funzioni imagecreatefrom*().
Inoltre, è fondamentale notare che le risorse non vengono distrutte da funzioni come curl_close(). Piuttosto, devi unset() l'istanza per annullarne il riferimento poiché ora è un'istanza di classe.
Ottieni la possibilità di specificare le classi come suggerimenti di digitazione nelle tue funzioni e metodi.
In precedenza, dovevamo restituire valori non tipizzati o lasciare argomenti di risorsa e documentarli tramite annotazioni, ma ora puoi avere tipi espliciti e questo non solo rende il tuo codice più leggibile ma anche più sicuro per i tipi.
Qual è il compromesso qui?
Ora dovrai aggiornare il tuo codice se vuoi distruggere le risorse con l'aiuto di unset() al posto delle precedenti funzioni utilizzate per demolire le risorse. Questo può essere normalmente ottenuto attraverso la ricerca e la sostituzione.
Modifiche all'API Reflection
Un altro piccolo cambiamento, ma un cambiamento fondamentale in PHP 8 è relativo all'API Reflection. Durante l'utilizzo del sistema di attributi, è possibile recuperare comodamente tali attributi tramite l'API Reflection su qualsiasi classe di riflessione.
Con l'aggiunta di tipi misti e union, le tecniche di ReflectionParameter getClass(), isCallable() e isArray() sono ora obsolete.
Lo scenario è così perché l'uso di getType() è molto meglio e ottieni l'elenco completo dei tipi che soddisfa un parametro specifico.
Miglioramenti alla sintassi di PHP 8
Come stiamo notando, JIT sta rubando i titoli dei giornali; i miglioramenti sintattici di PHP 8 offrono enormi vantaggi in termini di qualità della vita agli sviluppatori PHP.
Indipendentemente dall'eliminazione della piastra comune tra gli argomenti del costruttore promosso o dalla migliore gestione delle eccezioni e degli errori, c'è molto di cui gli sviluppatori si sentono entusiasti.
- pseudotipo “misto”.
- Tipi di unione
- Promozione della proprietà del Costruttore di classe
- Generare eccezioni dalle espressioni
- Attributi
- ::ubiquità di classe
- Cattura solo per tipo
- Espressioni di corrispondenza
Ai fini della manutenzione di questo blog, ci stiamo concentrando su tipi di unione, attributi ed espressioni di corrispondenza.
Tipi di unione
I tipi di unione mostrano che un valore è uno tra due o più ordinamenti specificati. È fatto con una barra verticale posizionata tra ogni singolo tipo consentito. Per molti sviluppatori che sono profondi nelle annotazioni PHP per restituire valori o specificare i tuoi parametri, molto probabilmente lo hai già fatto.
I tipi di unione possono comportare molta complessità e difficoltà di comprensione per coloro che accettano molti tipi diversi o restituiscono molti tipi diversi.
Tuttavia, questo sarà molto utile in diverse occasioni. Ad esempio, nel caso in cui tu possa accettare o un oggetto che implementa la nuova interfaccia Stringable ("string|Stringable"), o una stringa, o se puoi accettare un oggetto che implementa l'interfaccia Traversable ("array|Traversable") o un array .
Espressioni di corrispondenza
Le espressioni di corrispondenza interrompono le congetture relative a capire se la mancata rottura all'interno di un determinato caso di commutazione è intenzionale o meno. Semplifica inoltre il normale schema di assegnazione di un valore sulla base di una corrispondenza.
Quando viene utilizzato, il valore che passiamo a match() verrà confrontato direttamente con qualsiasi espressione sia presente sul lato sinistro. Indipendentemente dal fatto che sia un'espressione o un valore, il valore che passi a match() deve corrispondere per poter essere scelto.
Quando viene confrontata, viene stimata l'espressione presente a destra e il relativo valore restituito, mentre le espressioni possono essere solo funzioni Lambda o richiamabili e non sono consentite chiusure su più righe.
Attributi
PHP 8 integra anche gli attributi a livello di lingua. Sebbene gli attributi siano presenti da più di 15 anni tramite annotazioni docblock, integrarli nel linguaggio offre prestazioni migliori e, sicuramente, più potenza e maggiore coerenza. Probabilmente vedremo attributi molto utilizzati nello sviluppo di strumenti e applicazioni rapide.
Conclusione
Certamente, ci sono alcune modifiche in PHP8. Tuttavia, sembra che la maggior parte del codice deprecato eliminato sia per funzionalità precedenti che non abbiamo visto essere utilizzate negli ultimi tempi.
Siamo piuttosto interessati a notare quale impatto avrà il motore JIT sulle basi di codice che utilizziamo e anche sulla più ampia comunità PHP, dicendo che consigliamo vivamente di scansionare la base di codice per rilevare eventuali incompatibilità con PHP8 ed eseguire unit test per garantire che il tuo PHP le applicazioni funzionano perfettamente prima di dire "sì" all'aggiornamento.