{"id":3757,"date":"2024-01-24T15:36:36","date_gmt":"2024-01-24T14:36:36","guid":{"rendered":"https:\/\/www.dotenv.it\/non-categorizzato\/php-8-novita-e-performance-nella-versione-migliorativa"},"modified":"2024-06-12T16:19:24","modified_gmt":"2024-06-12T14:19:24","slug":"php-8-novita-e-performance","status":"publish","type":"post","link":"https:\/\/www.dotenv.it\/en\/blog\/php-8-novita-e-performance","title":{"rendered":"PHP 8: Novit\u00e0 e Performance nella Versione Migliorativa"},"content":{"rendered":"<p>Dopo\u00a0una fase di testing\u00a0relativamente veloce pare proprio che ci siamo: il 26 Novembre 2020, <b>la nuova\u00a0major version PHP 8<\/b>,\u00a0il linguaggio di programmazione\u00a0pi\u00f9 noto per lo sviluppo di server, sar\u00e0 disponibile per tutti.<\/p>\n<p>Scopriamo insieme, nel prossimo articolo, <b>le principali novit\u00e0 e performance della nuova versione <\/b>di questo linguaggio.<\/p>\n<h2>Il passaggio da PHP 7 a PHP 8<\/h2>\n<p>Creato dallo sviluppatore <a href=\"https:\/\/it.wikipedia.org\/wiki\/Rasmus_Lerdorf\" target=\"_self\" rel=\"noopener\"><b>Rasmus Lerdorf<\/b><\/a> venticinque anni fa per la creazione di pagine web dinamiche, PHP \u00e8 il linguaggio di programmazione\u00a0pi\u00f9 noto per lo sviluppo di server, che nel tempo si \u00e8 evoluto in un<b> linguaggio completo e professionale<\/b>, grazie anche al supporto della community e di professionisti che ruota intorno ad esso.<\/p>\n<p>Il termine\u00a0<b>major version\u00a0<\/b>\u00e8 importante: cos\u00ec come PHP 7 ha introdotto modifiche che hanno rotto le compatibilit\u00e0 con PHP 5.6, dobbiamo aspettarci anche in questo caso un salto tecnologico importante che introdurr\u00e0 molte\u00a0<i>breaking changes<\/i>.<\/p>\n<p>Esattamente come nel passaggio da PHP 5.6 a PHP 7, <b>la vera differenza la far\u00e0 la qualit\u00e0 del codice e la capacit\u00e0 del singolo developer di aggiornarsi<\/b>; utilizzare framework come <i>Symfony<\/i>,\u00a0<i>Laravel<\/i>,\u00a0<i>Yii<\/i>\u00a0pu\u00f2 essere d\u2019aiuto per gestire passaggi di versione cos\u00ec importanti, obbligando lo sviluppatore a scrivere codice il pi\u00f9 possibile astratto e di alto livello.<\/p>\n<h2><b>La principale novit\u00e0 di PHP 8: JIT<\/b><\/h2>\n<p>Principale novit\u00e0 di questa versione \u00e8 il <b>supporto per la compilazione\u00a0JIT<\/b>\u00a0(Just-in-Time), il cui compito \u00e8 quello di <b>migliorare la performance<\/b>, interpretando e compilando le parti del codice riga per riga durante il runtime, ovvero l\u2019esecuzione. In termini pratici quindi il <b>JIT \u00e8 una modalit\u00e0 di compilazione durante il funzionamento stesso di una applicazione<\/b> e per questo parliamo di \u201ctraduzione dinamica\u201d, perch\u00e9 avviene durante l\u2019esecuzione anzich\u00e9 prima.<\/p>\n<h2><b>Le fasi di esecuzione di PHP 8 con OPcache<\/b><\/h2>\n<p>La procedura di esecuzione di PHP 8 si compone di quattro fasi:<\/p>\n<ul>\n<li><b>Lexing\/Tokenizing<\/b><span class=\"ProseMirror__styled\">\u00a0<\/span>per la costruzione di un set di token.<\/li>\n<li><b>Parsing<\/b><b><span class=\"ProseMirror__styled\">\u00a0<\/span><\/b>tramite l\u2019uso di token, per costruire l\u2019AST, ovvero la rappresentazione gerarchica del codice sorgente.<\/li>\n<li><b>Compilation<\/b>: l\u2019interprete traduce i nodi AST in Zend opcode di basso livello, che determinano il tipo di\u00a0istruzione eseguita dalla Zend VM.<\/li>\n<li><b>Interpretation<\/b>: gli opcode vengono interpretati ed eseguiti sulla Zend VM.<\/li>\n<\/ul>\n<p>L\u2019abilitazione di <b>OPcache <\/b>permette di <b>velocizzare le operazioni e di ottimizzare le prestazioni macchina <\/b>avendo dei contenuti immediati senza attendere. In altre parole, con OPcache l\u2019interprete PHP attraversa le quattro fasi della procedura solo la prima volta in cui viene eseguito lo script, rendendo immediatamente disponibili i bytecode della rappresentazione intermedia di basso livello per eseguirli poi sulla Zend VM.<\/p>\n<h2><b>Le caratteristiche principali di PHP 8<\/b><\/h2>\n<p>La versione PHP 8 si \u00e8 infatti allineata alla robustezza dei sistemi legacy pi\u00f9 blasonati, mantenendo per\u00f2 le caratteristiche esclusive che lo rendono un metodo sicuro:<\/p>\n<ul>\n<li><b>Strutturato:<\/b> la nuova release \u00e8 caratterizzata dalla tipizzazione, comportando maggiori controllo e stabilit\u00e0 sulla piattaforma.<\/li>\n<li><b>Performante: <\/b>sicuro per la prestazione e il controllo in fase di sviluppo, build e deploy.<\/li>\n<li><b>Standardizzato: <\/b>maggiore coerenza nelle risposte da parte delle funzioni di sistema.<\/li>\n<\/ul>\n<p>In DotEnv il team sviluppo lavora gi\u00e0 con PHP 7.4, rilasciata lo scorso novembre, per poter garantire una sempre migliore performance. Con il rilascio della nuova versione quindi aggiorneremo ulteriormente metodi e procedure, certi dei vantaggi che PHP8 comporter\u00e0, dopo il rilascio della versione Beta1 lo scorso 6 agosto.<\/p>\n<h2>Le nuove funzionalit\u00e0 di PHP 8<\/h2>\n<p><b>Union Types<\/b><\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/union_types_v2\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><\/p>\n<p>Questa era, personalmente, una delle carenze che pi\u00f9 avvertivo nel dichiarare funzioni; il rischio come sempre sar\u00e0 quello di un abuso della funzionalit\u00e0; vediamo con un esempio:<\/p>\n<p><code>public function foo(Foo|Bar $input): int|float;<\/code><\/p>\n<p>Prima di PHP 8, l\u2019unica possibilit\u00e0 per ritornare uno o pi\u00f9 valori era solo il<span class=\"ProseMirror__styled\">\u00a0<\/span><code>null<\/code>, ad esempio con<\/p>\n<p><code>public function foo(?Foo $input): ?int;<\/code><\/p>\n<p>in questo esempio posso ritornare\u00a0<code>null<\/code>\u00a0oppure\u00a0<code>int<\/code>\u00a0e la funzione accetta un\u00a0<code>$input<\/code>\u00a0di tipo\u00a0<code>null<\/code>\u00a0o\u00a0<code>Foo<\/code>. Ma cosa succede se il dato di ritorno \u00e8, per esempio, un int e un float? Non avrei potuto farlo. Questo non vale se si usa il\u00a0<code>void<\/code>: se, quindi, una funzione non ritorna nulla, non mi posso aspettare altri tipi di dato oltre a void (non avrebbe senso dire che il dato di ritorno \u00e8\u00a0<code>int<\/code>\u00a0o\u00a0<code>void<\/code>).<\/p>\n<p><code>public function foo(Foo|null $foo): void;<\/code><\/p>\n<p><code>public function bar(?Bar $bar): void;<\/code><\/p>\n<h2><b>JIT<\/b><\/h2>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/jit\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><\/p>\n<p>Il compilatore Just in Time sulla carta promette importanti miglioramenti in termini di performance anche se tutto dipender\u00e0 dal caso d\u2019uso specifico. In ambito web, esistono dei benchmark che sembrano sfatare questo mito. Vedremo nei prossimi mesi, soprattutto perch\u00e9 la versione stabile potrebbe essere molto pi\u00f9 ottimizzata.<\/p>\n<p><b>L\u2019operatore\u00a0<\/b><b><i>nullsafe<\/i><\/b><\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/nullsafe_operator\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><\/p>\n<p>Alzi la mano chi qualche volta si \u00e8 trovato l\u2019errore\u00a0<code>Fatal error: Call to a member function getFoo() on null<\/code>; questo accade perch\u00e9 magari il codice \u00e8 scritto cos\u00ec<\/p>\n<p><code>$object-&gt;bar-&gt;getFoo();<\/code><\/p>\n<p>ma\u00a0<code>bar<\/code>\u00a0\u00e8 null. L\u2019unica soluzione era quindi quella di usare un operatore ternario (o verificare in due step se\u00a0<code>bar<\/code><span class=\"ProseMirror__styled\">\u00a0<\/span>esiste) ad esempio:<\/p>\n<p><code>$startDate= $booking-&gt;getStartDate();<\/code><\/p>\n<p><code>$dateAsString = $startDate ? $startDate-&gt;asDateTimeString() : null;<\/code><\/p>\n<p>Se quindi in questo caso esiste\u00a0<code>$startDate<\/code>\u00a0chiamo la funzione\u00a0<code>asDateTimeString()<\/code>, altrimenti ritorno null.<\/p>\n<p>In PHP 8 diventa tutto molto pi\u00f9 leggibile e pulito<\/p>\n<p>$da<\/p>\n<p><code>$dateAsString = $booking-&gt;getStartDate()?-&gt;asDateTimeString();<\/code><\/p>\n<p>Quel\u00a0<code>?<\/code>\u00a0sta facendo esattamente la stessa cosa, ma in modo pi\u00f9 veloce e leggibile.<\/p>\n<p><b>Named arguments<\/b><\/p>\n<p>Questa \u00e8 una grossa novit\u00e0 che sicuramente aiuter\u00e0 a rendere pi\u00f9 leggibile il codice.<br \/>\nFino ad oggi gli argomenti passati ad una funzione erano posizionali: se quindi il primo elemento era\u00a0<code>$a<\/code>\u00a0e poi\u00a0<code>$b<\/code>\u00a0i valori da passare dovevano seguire questo ordine.<\/p>\n<p>Prendiamo questa struttura:<\/p>\n<p><code>class CustomerData<\/code><\/p>\n<p><code>{<\/code><\/p>\n<p><code>public function __construct(<\/code><\/p>\n<p><code>public string $name,<\/code><\/p>\n<p><code>public string $email,<\/code><\/p>\n<p><code>public int $age,<\/code><\/p>\n<p><code>) {}<\/code><\/p>\n<p><code>}<\/code><\/p>\n<p>Al momento, una volta invocata, l\u2019ordine da seguire \u00e8 definito dalla firma della funzione; notate la comodit\u00e0 di:<\/p>\n<p><code>$data = new CustomerData(<\/code><\/p>\n<p><code> age: $input['age'],<\/code><\/p>\n<p><code> name: $input['name'],<\/code><\/p>\n<p><code> email: $input['email'],<\/code><\/p>\n<p><code>);<\/code><\/p>\n<p>cos\u00ec facendo non devo ricordarmi la posizione degli elementi ma il loro nome, rendendo tutto molto pi\u00f9 leggibile e lineare. Nell\u2019esempio della struttura vedrete la prossima novit\u00e0 di PHP 8, i\u00a0<i>Constructor property promotion.<\/i><\/p>\n<h3><b>Constructor property promotion<\/b><\/h3>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/constructor_promotion\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><\/p>\n<p>Una cosa comodissima e che vi eviter\u00e0 inutili e ripetitive righe di codice.<br \/>\nSi passa da:<\/p>\n<p><code>class Money<\/code><\/p>\n<p><code>{<\/code><\/p>\n<p><code>public Currency $currency;<\/code><\/p>\n<p><code>public int $amount;<\/code><\/p>\n<p><code>public function __construct(<\/code><\/p>\n<p><code> Currency $currency,<\/code><\/p>\n<p><code>int $amount,<\/code><\/p>\n<p><code>) {<\/code><\/p>\n<p><code>$this-&gt;currency = $currency;<\/code><\/p>\n<p><code>$this-&gt;amount = $amount;<\/code><\/p>\n<p><code>}<\/code><\/p>\n<p><code>}<\/code><\/p>\n<p><code>a<\/code><\/p>\n<p><code>class Money<\/code><\/p>\n<p><code>{<\/code><\/p>\n<p><code>public function __construct(<\/code><\/p>\n<p><code>public Currency $currency,<\/code><\/p>\n<p><code>public int $amount,<\/code><\/p>\n<p><code>) {}<\/code><\/p>\n<p><code>}<\/code><\/p>\n<p>Come potete vedere mi sono evitato la definizione della variabili all\u2019inizio della classe\u00a0<code>Money<\/code>\u00a0cos\u00ec come l\u2019assegnazione nel costruttore.<\/p>\n<h3><b>Match<\/b><\/h3>\n<p>Premesso che non amo particolarmente gli\u00a0<code>switch-case<\/code>\u00a0in quanto li ritengo, tanto quanto gli else, poco leggibili e funzionali,\u00a0<code>match<\/code>\u00a0permette di avere, in forma compatta, quello che faremmo con uno\u00a0<code>switch<\/code>.<\/p>\n<p>Di sicuro avrete visto qualcosa come:<\/p>\n<p><code>switch ($statusCode) {<\/code><\/p>\n<p><code>case 200:<\/code><\/p>\n<p><code>case 300:<\/code><\/p>\n<p><code>$message = null;<\/code><\/p>\n<p><code>break;<\/code><\/p>\n<p><code>case 400:<\/code><\/p>\n<p><code>$message = 'not found';<\/code><\/p>\n<p><code>break;<\/code><\/p>\n<p><code>case 500:<\/code><\/p>\n<p><code>$message = 'server error';<\/code><\/p>\n<p><code>break;<\/code><\/p>\n<p><code>default:<\/code><\/p>\n<p><code>$message = 'unknown status code';<\/code><\/p>\n<p><code>break;<\/code><\/p>\n<p><code>}<\/code><\/p>\n<p>bene, tutto questo si pu\u00f2 accorciare in qualcosa di molto pi\u00f9 semplice e leggibile:<\/p>\n<p><code>$message = match ($statusCode) {<\/code><\/p>\n<p><code>200, 300 =&gt; null,<\/code><\/p>\n<p><code>400 =&gt; 'not found',<\/code><\/p>\n<p><code>500 =&gt; 'server error',<\/code><\/p>\n<p><code>default =&gt; 'unknown status code',<\/code><\/p>\n<p><code>};<\/code><\/p>\n<p>spariscono i\u00a0<i>break<\/i>\u00a0e pi\u00f9 valori possono essere accorpati assieme se il risultato \u00e8 lo stesso. Inoltre ritorna un valore che gi\u00e0 viene associato ad una variabile, senza la necessit\u00e0 di ripetere il\u00a0<code>$message =<\/code>\u00a0ogni volta.<\/p>\n<h3><b>Stringhe<\/b><\/h3>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/str_contains\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><br \/>\n<a href=\"https:\/\/wiki.php.net\/rfc\/add_str_starts_with_and_ends_with_functions\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><\/p>\n<p>Sono disponibili alcune nuove funzioni in PHP 8, ad esempio<span class=\"ProseMirror__styled\">\u00a0<\/span><code>str_contains()<\/code>\u00a0torner\u00e0\u00a0<i>true<\/i>\u00a0o\u00a0<i>false<\/i>\u00a0senza pi\u00f9 dover passare per\u00a0<code>strpos<\/code><\/p>\n<p><code>if (strpos('string with lots of words', 'words') !== false) { }<\/code><\/p>\n<p>diventa<\/p>\n<p><code>if (str_contains('string with lots of words', 'words')) { }<\/code><\/p>\n<p>allo stesso modo abbiamo anche altre due funzioni:<\/p>\n<p><code>str_starts_with('haystack', 'hay');<\/code><\/p>\n<p><code>str_ends_with('haystack', 'stack');<\/code><\/p>\n<h3><b>Trailing comma in parameter lists<\/b><\/h3>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/trailing_comma_in_parameter_list\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><\/p>\n<p>Quante volte, abituati ad esempio agli\u00a0<i>array<\/i><span class=\"ProseMirror__styled\">\u00a0<\/span>vi siete ritrovati ad aggiungere la virgola all\u2019ultimo parametro di una funzione? Ora finalmente \u00e8 possibile farlo:<\/p>\n<p><code>public function(<\/code><\/p>\n<p><code>string $parameterA,<\/code><\/p>\n<p><code>int $parameterB,<\/code><\/p>\n<p><code> Foo $objectfoo,<\/code><\/p>\n<p><code>) {<\/code><\/p>\n<p><code>}<\/code><\/p>\n<h3><b>::class per gli oggetti<\/b><\/h3>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/class_name_literal_on_object\" target=\"_blank\" rel=\"noopener\"><b>Link alla RFC<\/b><\/a><\/p>\n<p>Ultima novit\u00e0, piccola ma decisamente comoda: al posto di usare\u00a0<code>get_class()<\/code>\u00a0sugli oggetti, si potr\u00e0 utilizzare il pi\u00f9 conosciuto\u00a0<code>::class<\/code><\/p>\n<p><code>$foo = new Foo();<\/code><\/p>\n<p><code>var_dump($foo::class);<\/code><\/p>\n<p>notate come, finalmente, possa usare\u00a0<code>::class<\/code>\u00a0su\u00a0<code>$foo<\/code>.<\/p>\n<h2><\/h2>\n<p>PHP 8 porta sicuramente una ventata di novit\u00e0 e freschezza, obbligando il developer a utilizzare sempre pi\u00f9 sintassi simili ad altri linguaggi e abbandonando sempre pi\u00f9 concezioni legacy che hanno, negli anni, rovinato la sua reputazione.<\/p>\n<p>Il salto non sar\u00e0 quindi importante come da PHP 5 a PHP 7 proprio perch\u00e9 un gran lavoro di svecchiamento \u00e8 stato gi\u00e0 fatto.<\/p>\n<p>Ora sta agli sviluppatori scrivere del buon codice e utilizzare questi nuovi <i>tools<\/i>; tutto ci\u00f2 che in PHP 8 \u00e8 stato tolto (diventando quindi una breaking change) lo trovate <a href=\"https:\/\/github.com\/php\/php-src\/blob\/master\/UPGRADING#L20\" target=\"_blank\" rel=\"noopener\"><b>nella guida all\u2019upgrade<\/b><\/a>.<\/p>\n<p>Fonte: <a href=\"http:\/\/stitcher.io\" target=\"_blank\" rel=\"noopener\"><b>stitcher.io<\/b><\/a> e<span class=\"ProseMirror__styled\">\u00a0<\/span><a href=\"https:\/\/twitter.com\/brendt_gd\" target=\"_blank\" rel=\"noopener\"><b>Brent<\/b><\/a><span class=\"ProseMirror__styled\">\u00a0<\/span><\/p>\n<p>In DotEnv le competenze in termini di linguaggi di programmazione non mancano. Gli sviluppatori sono un gruppo eterogeneo che seguono procedure precise per raggiungere precisi obiettivi e rilasciare software performanti ai clienti.<\/p>\n<p><a href=\"https:\/\/www.dotenv.it\/it\/soluzioni-software\" target=\"_self\" rel=\"noopener\"><b>Scopri i processi di Design, Development e Delivery DotEnv.<\/b><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dopo\u00a0una fase di testing\u00a0relativamente veloce pare proprio che ci siamo: il 26 Novembre 2020, PHP 8, la nuova\u00a0major version,\u00a0sar\u00e0 disponibile per tutti <\/p>\n<p>Creato da Rasmus Lerdorf venticinque anni fa per la creazione di pagine web dinamiche, PHP \u00e8 il linguaggio di programmazione\u00a0pi\u00f9 noto per lo sviluppo di server, che nel tempo si \u00e8 evoluto in un linguaggio completo e professionale, grazie anche al supporto della community e di professionisti che ruota intorno ad esso.<\/p>\n<p>Il termine\u00a0major version\u00a0\u00e8 importante: cos\u00ec come PHP 7 ha introdotto modifiche che hanno rotto le compatibilit\u00e0 con PHP 5.6, dobbiamo aspettarci anche in questo caso un salto tecnologico importante che introdurr\u00e0 molte\u00a0breaking changes.<\/p>\n<p>Esattamente come nel passaggio da PHP 5.6 a PHP 7, quindi, la vera differenza la far\u00e0 la qualit\u00e0 del codice e la capacit\u00e0 del singolo developer di aggiornarsi; utilizzare framework come Symfony,\u00a0Laravel,\u00a0Yii\u00a0pu\u00f2 essere d\u2019aiuto per gestire passaggi di versione cos\u00ec importanti, obbligando lo sviluppatore a scrivere codice il pi\u00f9 possibile astratto e di alto livello.<\/p>\n","protected":false},"author":19,"featured_media":3545,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,22],"tags":[],"class_list":["post-3757","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","category-soluzioni-software"],"_links":{"self":[{"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/posts\/3757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/users\/19"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/comments?post=3757"}],"version-history":[{"count":2,"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/posts\/3757\/revisions"}],"predecessor-version":[{"id":4314,"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/posts\/3757\/revisions\/4314"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/media\/3545"}],"wp:attachment":[{"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/media?parent=3757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/categories?post=3757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dotenv.it\/en\/wp-json\/wp\/v2\/tags?post=3757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}