Almeno apparentemente PHP 5.6, ultima major release del noto linguaggio Open Source per lo sviluppo server side, non sembrerebbe presentare novità rilevanti per l'evoluzione del progetto, come per esempio l'abbandono di fatto delle mysql functions avvenuto con la versione 5.5; in realtà si tratta di un aggiornamento che porta con sé un buon numero di features aggiuntive meritevoli di un approfondimento. Nel corso di questa trattazione verranno analizzate le principali novità che caratterizzano tale rilascio.
Stato di avanzamento di PHP 5.6
PHP 5.6 si trova attualmente allo stadio iniziale della fase di betatest, la prima alpha venne rilasciata all'inizio di gennaio e venne seguita da altre due release di cui l'ultima resa disponibile ad inizio marzo. La seconda beta dovrebbe essere rilasciata entro la penultima settimana di aprile. Ad oggi gli ultimi due aggiornamenti dei rami stabili supportati sono PHP 5.4.27 e 5.5.11.
Constant scalar expressions
Il concetto di espressioni scalari (o espressioni di valore) è ricollegato alla possibilità di introdurre cifre ed elaborazioni numeriche, stringhe, costanti o questi stessi elementi combinati tra di loro, all'interno di un contesto nel quale il linguaggio avrebbe precedentemente accettato soltanto valori statici; come per esempio nel caso della dichiarazione di una costante, delle proprietà di una classe o degli argomenti predefiniti per le funzioni che ora potranno essere associati a strutture di tipo logico o ad elementari espressioni aritmetiche.
Un semplice esempio relativo a questa funzionalità potrebbe essere il seguente che riassume praticamente quasi tutti i casi descritti in precedenza:
<?php
const A = 1;
const B = A * 2;
class NuovoRisultato {
const C = B + 1;
const CALCOLO = A / self::C;
const OUTPUT = 'Valore di C pari a '.self::C;
public function addizione($totale = A + self::C) {
return $totale;
}
}
echo (new NuovoRisultato)->addizione()."n";
echo NuovoRisultato::OUTPUT;
?>
Utilizzando le versioni precedenti di PHP, e nel caso specifico l'analisi è stata limitata alle release dalla 5.3 alla 5.5, il risultato dell'esecuzione dello script proposto sarebbe stato la notifica di un errore sul modello della seguente:
Parse error: syntax error, unexpected '*', expecting ',' or ';' in /dir/file.php on line 3
mentre in un ambiente basato su PHP 5.6, l'output previsto dovrebbe essere invece quello proposto di seguito:
4
Valore di C pari a 3
Variadic functions tramite operatore …
Le variadic functions sono in pratica delle funzioni alle quali viene associato un numero arbitrario di argomenti, in PHP 5.6 esse risulteranno implementabili senza dover fare riferimento a costrutti basati su func_get_args()
che restituisce un array comprendente l'elenco degli argomenti di una funzione.
A tal proposito si prendano in considerazione i due esempi seguenti; il primo presenta una funzione, somma()
, che permette di sommare i valori passati ad essa attraverso l'utilizzo di func_get_args()
come argomento di array_sum()
:
function somma()
{
return array_sum(func_get_args());
}
echo somma(1, 10, 100, 1000);
Il secondo esempio presenta la stessa funzione definita dall’utente, ma invece di ricorrere a func_get_args()
sfrutterà l'operatore …
per indicare che somma()
è una variadic function e che tutti gli argomenti dovranno essere inseriti nell'array $addendi
:
function somma(...$addendi)
{
return array_sum($addendi);
}
echo somma(2, 4, 8, 16);
Ciò dovrebbe portare alla possibilità di scrivere codici più leggibili e meno articolati rispetto al passato; come evidenziato dall’esempio seguente, quello descritto non è però l'unico vantaggio derivante dalle variadic functions:
public function sql($sql) {
$prst = $this->pdo->prepare($sql);
$prst->execute(array_slice(func_get_args(), 1));
return $prst;
}
La stessa funzione, utilizzabile nell'implementazione di un'interfaccia, potrà essere riscritta adottando l’operatore …
e senza ricorrere a array_slice()
e func_get_args()
:
public function sql($sql, ...$parametri) {
$prst = $this->pdo->prepare($sql);
$prst->execute($parametri);
return $prst;
}
Nel primo esempio non viene messo a disposizione alcun elemento attraverso il quale interpretare la funzione dichiarata come una variadic function, l'unico parametro raccolto è infatti quello relativo ad una query da mandare in esecuzione, inoltre, func_get_args()
restituisce tutti i parametri che le vengono passati, quindi sarà necessario l'impiego di array_slice()
per la rimozione di $sql
dagli argomenti passati al metodo execute()
.
Nel secondo esempio invece, il costrutto ...$parametri
rivela la natura della funzione quale variadic function, quindi tutti i valori presenti dopo di $sql
(e non quest’ultimo) saranno passati come elementi all'array $parametri
.
Argument unpacking
Quello dell'argument unpacking è un tema ricollegato direttamente a quello delle variadic functions; in pratica, precedentemente alla versione 5.6, l'unica procedura disponibile per la chiamata ad una funzione dotata di un numero arbitrario di parametri era quella che prevedeva di far ricorso a costrutti basati su call_user_func_array()
; quest'ultima in pratica richiama un callback con un array di parametri. Da subito tale soluzione si è rivelata però macchinosa, lenta e non priva di incompatibilità con altri costrutti.
Anche la sintassi dell'argument unpacking si basa sull’utilizzo dell'operatore …
o splat operator, l'esempio seguente mostra una semplice modalità d'impiego per questa nuova feature:
$elementi = [2, 4, 6, 8, 10];
NomeClasse::nomeMetodo(...$elementi);
Un’espressione che in pratica corrisponde a:
NomeClasse::nomeMetodo(2, 4, 6, 8, 10);
Con l'argument unpacking, gli array e gli oggetti dell'interfaccia nativa Traversable possono essere spacchettati all'interno di liste di argomenti tramite l'operatore …
che, a sua volta, potrà essere utilizzato al momento della chiamata di una funzione, come nell'esempio proposto di seguito:
function inserisci($uno, $due, $tre) {
return $uno + $due + $tre;
}
$addendi = [200, 300];
echo inserisci(100, ...$addendi);
Da notare l'impiego dello splat operator per permettere alla funzione inserisci()
di utilizzare anche gli elementi assegnati ad $addendi
per la generazione del valore di ritorno.
Operatore ** per l’elevamento a potenza
PHP 5.6 introduce un nuovo operatore associativo, **
, appositamente dedicato alle operazioni matematiche per l'elevamento a potenza; in pratica, in un’espressione si avrà la base alla sinistra dell'operatore e l'esponente alla sua destra, motivo per il quale l'elaborazione seguente restituirà come output il valore "8":
printf(2 ** 3);
Lo stesso operatore potrà essere utilizzato più volte all'interno della medesima espressione in modo da introdurre più esponenti:
printf(2 ** 2 ** 3); // output "256"
Vi sarà inoltre la possibilità di adottare ** in operazioni di assegnazione di valori grazie all'uso combinato con l'operatore =:
$num = 8;
$num **= 2;
printf($num); // output "64"
L'estensione dell'operatore use
In PHP 5.6 il campo d'azione dell'operatore use
è stato esteso allo scopo di supportare l'importazione di funzioni e costanti, un supporto che andrà quindi ad aggiungersi a quello già disponibile per le classi; lo sviluppatore avrà cioè la possibilità di adottare i costrutti use function
e use const
come nell'esempio proposto di seguito:
namespace HomerMarge {
const BART = "Eat my shorts!";
function lisa() { echo __FUNCTION__."n"; }
}
namespace {
use const HomerMargeBART;
use function HomerMargelisa;
echo BART."n";
lisa();
}
L'output dello script, proposto di seguito, rappresenterà il semplice risultato dell'importazione di quelle che vengono definite namespaced functions e del loro uso combinato con le costanti all'interno di namespaces.
Eat my shorts!
HomerMargelisa
Chiaramente, nulla impedirà di adottare l'operatore use
per l'importazione di comuni namespaces così come di classi, interfacce o traits.
Codifica predefinita per i caratteri
Con quest'ultimo aggiornamento del linguaggio, la direttiva default_charset
diventerà il riferimento predefinito per il set di caratteri nelle funzioni appositamente dedicate alle operazioni di codifica, come per esempio htmlspecialchars()
che converte i cosiddetti "caratteri speciali" in entità HTML. Nel caso specifico, il valore di default per l'impostazione della direttiva citata sarà la codifica dei caratteri Unicode UTF-8; si tenga però conto del fatto che nel caso in cui dovessero essere state settate le impostazioni per la codifica di iconv
e mbstring
, queste risulteranno comunque prioritarie rispetto a default_charset
.
Il debugger phpdbg
PHP presenta ora un debugger interattivo che prende il nome di phpdbg ed è stato implementato come modulo SAPI (Server Application Programming Interface), l'API utilizzata dal linguaggio per l'interazione con i Web server; phpdbg è stato realizzato per garantire il minimo impatto possibile a carico delle prestazioni.
Sarà possibile interfacciarsi al debugger tramite CLI (Command line Interface) utilizzando semplici istruzioni testuali da terminale, phpdbg si integra con il motore Zend e ne inizializza l'ambiente; per i test e le procedure di accesso e ispezione a carico delle applicazioni sono disponibili numerose opzioni grazie alle quali specificare i breakpoint in fase di esecuzione.
Novità per la sicurezza
La versione 5.6 di PHP include alcune nuove features dedicate alla sicurezza intesa in senso lato. Si va infatti dal nuovo metodo ZipArchive::setPassword()
, che permetterà di definire delle password per la protezione degli archivi compressi, alla funzione hash_equals()
, integrata per consentire il confronto tra due stringhe e prevenire attacchi basati sull'analisi del tempo di esecuzione degli algoritmi di crittografici, fino al supporto per l'algoritmo gost-crypto. In riferimento ad hash_equals()
, chiaramente essa dovrà essere impiegata nel caso di test a carico degli hash prodotti tramite crypt()
, questo perché le funzioni alternative password_hash()
e password_verify()
dovrebbero mettere già al riparo da tentativi di timing attack.
Alcuni importanti miglioramenti hanno riguardato il supporto per le comunicazioni sicure via SSL/TLS, da questo punto di vista assumono una certa rilevanza l'abilitazione predefinita della verifica peer (nodo paritario) a cui si aggiungono il supporto per il riconoscimento dell'autenticità dei certificati, le nuove contromisure per limitare i tentativi di attacco basati sulla TLS renegotiation, le opzioni aggiuntive per incrementare l'efficacia dei controlli sul protocollo in un contesto SSL e le impostazioni per le verifiche durante l'uso di stream cifrati.
Da segnalare inoltre che PHP 5.6 consentirà l'upload di file di dimensioni maggiori di 2 Gb.
Accesso allo stream php://input
php://input
è uno stream in sola lettura che consente di leggere dati grezzi dal corpo di una richiesta basata sul metodo POST
, come nell'esempio seguente:
$dati = file_get_contents("php://input");
Esso è stato introdotto e ritenuto preferibile alla variabile predefinita $HTTP_RAW_POST_DATA
per via del fatto di essere indipendente da direttive del file di configurazione PHP.ini; fino a PHP 5.5 uno stream aperto con php://input
poteva essere letto una volta sola, ora, con PHP 5.6 esso potrà essere riaperto tutte le volte che sarà necessario, ne conseguirà un maggiore risparmio nell'impiego di memoria richiesta per la gestione dei dati veicolati tramite POST
.
Quando abilitata, la direttiva always_populate_raw_post_data
darà ora luogo ad una notifica E_DEPRECATED, mentre la superglobale $HTTP_RAW_POST_DATA
dovrebbe essere destinata alla rimozione nelle versioni future del linguaggio.
Conclusioni: PHP 6
Così come i precedenti aggiornamenti presentavano interessanti novità dal punto di vista della riutilizzabilità del codice, anche la versione 5.6 contiene alcune features mirate a semplificare il lavoro necessario per la stesura dei sorgenti nonché dei miglioramenti appositamente dedicati alla sicurezza. Intanto però, è ormai da anni che si aspettano notizie riguardanti PHP 6 e le funzionalità che esso dovrebbe portare con sé (come, ad esempio, il supporto nativo per Unicode), ma da questo punto di vista l'attesa potrebbe essere ancora lunga.