News
Le novità di php8

PHP 8 le novità

Frank Vessia
09 ott 2020
Tempo di lettura: 5 minuti, 2 secondi

Uno sguardo alle novità del PHP 8 (come il tanto atteso JIT) che a breve debutterà dopo quasi un anno di test


Ancora un paio di mesi al rilascio del PHP 8, una major release molto attesa sopratutto in vista di alcune novità che fanno sperare ad un salto di qualità e miglioramento delle performances, come il JIT.

In questo articolo ti propongo alcune delle novità degne di nota.

JIT

Partiamo proprio dalla feature più importante, ovvero "Just in Time". Il php è un linguaggio interpretato, il che significa che il codice è tradotto nel linguaggio macchina in tempo reale durante l'esecuzione (viene prima tradotto in Opcode e poi letto dalla macchina virtuale ovvero Zend VM che alla fine lo esegue) cosa che altri linguaggi non fanno poichè sono compilati prima di essere eseguiti, come il C o il Java.

JIT quindi non fa altro che compilare parti del codice che verranno utilizzate come fossero dei blocchi di cache in modo da aumentare le prestazioni (almeno a livello teorico). Quando il PHP incontra del codice che è riutilizzato all'interno dell'applicazione web, segna questo codice come "warm" oppure "hot" e lo manda a JIT il quale lo compila in linguaggio macchina e lo esegue senza passarlo a Zend VM, velocizzando il tutto.

Sembra tutto molto bello ma purtroppo c'è un aspetto molto importante da tener conto, JIT molto probabilmente (anzi sicuramente) non velocizzerà la tua applicazione web perchè non è per questo che è stato creato. Mi spiego meglio, tutto questo processo di compilazione non fa altro che convertire il php nel linguaggio macchina che viene seguito diretamente dalla CPU ma nessuna applicazione web fa uso della CPU così tanto da doversi aspettare dei miglioramenti, la maggior parte delle applicazioni web sono costituite da interazioni input/output come le query al database, il caricamento di file, le chiamate http ecc..quindi nessun utilizzo di CPU = nessun beneficio.

Allora percosa è stato creato JIT? La risposta più plausibile è che si sta cercando di portare PHP in nuovi territori fin'ora occupati da altri linguaggi come il C++, come quello delle applicazioni 3D dove si fa un grande uso della CPU e dove i benefici di JIT si fanno sentire.

A questo link puoi vedere un video che mostra il vantaggio di JIT proprio in ambito 3D.

Named arguments

In PHP 8 sarà possibile passare parametri di funzioni in base al nome e non all'ordine in cui vegono passati. Vediamo un esempio:

setOperator ( 
    string $name, 
    string $value = "", 
    int $start = 0,  
    string $group = "", 
)

Con il vecchio codice PHP, avrei dovuto chiamare questo metodo in questo modo:

setOperator(
    'test operator',
    ''
    time() + 60 * 60 * 4,
);

In PHP 8 posso chiamarlo così:

setOperator(
    name: 'test operator',
    start: time() + 60 * 60 * 4,
);

Il primo vantaggio è quello di non dover specificare valori nulli poichè l'ordinamento dei parametri non conta più e la sintassi diventa più leggibile poichè in qualunque punto del codice ci troviamo, ora sappiamo ogni parametro cosa rappresenta.

É possibile anche passare degli array in questo modo:

$data = [
    'name' => 'test operator',
    'value' => 12,
    'start' => time() + 60 *60 *4,
]

setOperator($data);

Espressione Match

Match è la versione 2.0 di switch, una sintassi più compatta e moderna. Vediamo un esempio, questo è un classico switch:

switch($pageStatus){
    case '200':
        $response = 'published';
    break;
    case '400':
        $response = 'unpublished';
    break;
    case '500':
    case '800':
        $response = 'incomplete';
    break;
    default:
        $response = 'not defined';
    break;    
}

e questa è la versione equivalente usando il match:

$response = match($pageStatus){
    200 => 'published',
    400 => 'unpublished',
    500, 800 => 'incomplete',
    default => 'not defined',
};

La sintassi è molto più compatta e ricorda un array, ma ci sono alcune considerazioni da fare:

  • non è richiesto il break;
  • è possibile combinare casi differenti con una virgola;
  • ritorna un valore quindi devi assegnare il valore solo una volta;
  • effettua solo verifiche implicite con operatore ===;
  • non sono consentiti valori non validi, quindi se non inserisci un caso di defautl riceverai un errore, per esempio:
$pageStatus = 300;

$response = match($pageStatus){
    200 => 'published',
    400 => 'unpublished',
    500, 800 => 'incomplete',
};

//errore: UnhandledMatchError

Array con indici negativi

Finalmente sarà possibile avere una progressione negli indici anche quando il primo valore è negativo, mentre prima un array di questo tipo:

$n = array_fill(-3, 5, true);
var_dump($n);

generava questo risultato:

array(5) {
    [-3]=>
    bool(true)
    [0]=>
    bool(true)
    [1]=>
    bool(true)
    [2]=>
    bool(true)
    [3]=>
    bool(true)
}

in php8 il risultato sarà:

array(5) {
    [-3]=>
    bool(true)
    [-2]=>
    bool(true)
    [-1]=>
    bool(true)
    [0]=>
    bool(true)
    [1]=>
    bool(true)
}

str_constrain, str_starts_with() e str_ends_with()

Finalmente sarà possibile cercare una stringa con una sintassi più compatta e comprensibile e cercare una stringa che inizia o termina con.
str_constrain va a sostituire strstr e strpos, vediamo un esempio pratico, usando strpost avevamo questo codice:

$string = "This is a strpos() test";
$find = "This is";
$pos = strpos($string, $find);
if ($pos !== false) {
    print "Found\n";
} else {
    print "Not Found!\n";
}

questo codice effettua anche la verifica sul tipo di elemento da ricercare per evitare problematiche ulteriori, con la nuova str_constrain avremo invece semplicemente:

$string = "This is a strpos() test";
$find = "This is";
if (str_contains($string, $find)) {
    print "Found\n";
} else {
    print "Not Found!\n";
}

questo codice è molto più compatto ed intuitivo ed evita eventuali problematiche nell'uso del giusto operatore di confronto.

str_starts_with() e str_ends_with() invece sono abbastanza autoesplicative, verificano se una data stringa inizia o finisce con un’altra stringa:

str_starts_with (string $mystring, string $find) : bool
str_ends_with (string $mystring, string $find) : bool

Ci utilizza un framework probabilmente fa uso di funzioni create appositamente per sopperire a questa mancanza nativa del php che da ora sarà nativa, per esempio tutti gli operatori di ProcessWire all'interno di un selector

Altre RFC

Al momento ci sono ancora diverse RFC (request to comment) in discussione e in fase di bozza per cui la lista potrebbe aumentare.

Conclusioni


Bisogna prepararsi, il php8 è alle porte e bisogna fare parecchi test per assicurarsi che le applicazioni attuali funzionino correttamente o che siano modificate per beneficiare delle nuove caratteristiche, bisogna tenere sotto controllo le varie timeline di upgrade dei framework (se ne usi uno tipo Laravel o ProcessWire) e seguirne lo sviluppo poichè pian piano tutti passerrano a questa nuova release.