PHP 8.4.1 Released!

Nuove funzionalità

Dichiarazioni di tipi scalari

Le dichiarazioni di tipi scalari sono disponibili in due versioni: coercitivo (predefinito) e rigoroso. I seguenti tipi per i parametri possono ora essere forzati (o coercitivo o rigoroso): stringhe (string), interi (int), numeri con virgola mobile (float), e booleani (bool). Questi aumentano gli altri tipi introdotti in PHP 5: nomi delle classi, interfacce, array e callable.

<?php
// Modalità coercitiva
function sumOfInts(int ...$ints)
{
return
array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));

Il precedente esempio visualizzerà:

int(9)

Per abilitare la modalità rigorosa, una singola direttiva declare deve essere posizionata nella parte superiore del file. Questo significa che la severità della tipizzazione per i valori scalari è configurata su una base per-file. Questa direttiva interessa non solo le dichiarazioni di tipi di parametri, ma anche il tipo di ritorno di una funzione (vedere dichiarazioni dei tipi di ritorno, le funzioni interne di PHP, e le funzioni delle estensioni caricate.

La documentazione completa e gli esempi sulle dichiarazioni dei tipi scalari si possono trovare nel riferimento dichiarazione del tipo.

Dichiarazioni del tipo di ritorno

PHP 7 aggiunge il supporto per le dichiarazioni del tipo di ritorno. Analogamente alle dichiarazioni dei tipi degli argomenti, le dichiarazioni del tipo di ritorno specificano il tipo del valore che sarà restituito da una funzione. Per le dichiarazioni del tipo di ritorno sono disponibili gli stessi tipi che sono disponibili per le dichiarazioni del tipo degli argomenti.

<?php

function arraysSum(array ...$arrays): array
{
return
array_map(function(array $array): int {
return
array_sum($array);
},
$arrays);
}

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

Il precedente esempio visualizzerà:

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

La documentazione completa e gli esempi sulle dichiarazioni del tipo di ritorno si possono trovare nel riferimento le dichiarazioni del tipo di ritorno.

Operatore null coalesce

L'operatore null coalesce (??) è stato aggiunto come zucchero sintattico per il caso comune di dover utilizzare una ternaria in congiunzione con isset(). Esso restituisce il suo primo operando se esiste e non è null; altrimenti restituisce il suo secondo operando.

<?php
// Legge il valore di $_GET['user'] e restituisce 'nobody'
// se esso non esiste.
$username = $_GET['user'] ?? 'nobody';
// Questo è equivalente a:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Più Coalesce possono essere incatenati: questo restituirà il primo
// valore definito tra $_GET['user'], $_POST['user'], e
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

L'operatore spaceship

L'operatore spaceship è usato per confrontare due espressioni. Restituisce -1, 0 o 1 quando $a è rispettivamente minore, uguale, o maggiore di $b. I confronti sono eseguiti secondo le consuete regole di confronto dei tipi di PHP.

<?php
// Interi
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Numeri decimali
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// Stringhe
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>

Array costanti che usano define()

Ora possono essere definiti Array costanti con define(). In PHP 5.6, potevano essere definiti solo con const.

<?php
define
('ANIMALS', [
'dog',
'cat',
'bird'
]);

echo
ANIMALS[1]; // visualizza "cat"
?>

Classi anonime

Il supporto per le classi anonime è stato aggiunto via new class. Queste possono essere usate al posto di definizioni di classi complete per oggetti usa e getta:

<?php
interface Logger {
public function
log(string $msg);
}

class
Application {
private
$logger;

public function
getLogger(): Logger {
return
$this->logger;
}

public function
setLogger(Logger $logger) {
$this->logger = $logger;
}
}

$app = new Application;
$app->setLogger(new class implements Logger {
public function
log(string $msg) {
echo
$msg;
}
});

var_dump($app->getLogger());
?>

Il precedente esempio visualizzerà:

object(class@anonymous)#2 (0) {
}

La documentazione completa può essere trovata nel riferimento delle classi anonime.

Sintassi dell'escape del codepoint Unicode

Questo ha come input un codepoint Unicode in una forma esadecimale, e restituisce quel codepoint in UTF-8 in una stringa con doppi apici oppure un heredoc. Qualsiasi codepoint valido è accettato, con gli iniziali 0 opzionali.

echo "\u{aa}";
echo "\u{0000aa}";
echo "\u{9999}";

Il precedente esempio visualizzerà:

ª
ª (stesso di prima ma con gli iniziali 0 opzionali)
香

Closure::call()

Closure::call() è un modo più performante e abbreviato di effettuare un binding temporaneo dello scope di un oggetto ad una closure e di invocarla.

<?php
class A {private $x = 1;}

// Codice prima di PHP 7
$getX = function() {return $this->x;};
$getXCB = $getX->bindTo(new A, 'A'); // closure intermedia
echo $getXCB();

// Codice PHP 7+
$getX = function() {return $this->x;};
echo
$getX->call(new A);

Il precedente esempio visualizzerà:

1
1

unserialize() filtrata

Questa funzionalità cerca di fornire una miglior sicurezza quando si deserializzano oggetti su dati non attendibili. Previene possibili iniezioni di codice, consentendo agli sviluppatori di inserire nella whitelist le classi che possono essere deserializzate.

<?php

// converte tutti gli oggetti in oggetti __PHP_Incomplete_Class
$data = unserialize($foo, ["allowed_classes" => false]);

// converte tutti gli oggetti in oggetti __PHP_Incomplete_Class eccetto quelli di MyClass e MyClass2
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);

// comportamento predefinito (lo stesso che si ha omettendo il secondo argomento) che accetta tutte le classi
$data = unserialize($foo, ["allowed_classes" => true]);

IntlChar

La nuova classe IntlChar cerca di esporre funzionalità ICU addizionali. La classe stessa definisce un numero di metodi statici e costanti che possono essere usati per manipolare i caratteri unicode.

<?php

printf
('%x', IntlChar::CODEPOINT_MAX);
echo
IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));

Il precedente esempio visualizzerà:

10ffff
COMMERCIAL AT
bool(true)

Per poter utilizzare questa classe, l'estensione Intl deve essere installata.

Aspettative

Le aspetattive sono dei miglioramenti retrocompatibili alla vecchia funzione assert(). Permettono asserzioni a costo zero nel codice di produzione, e forniscono la possibilità di lanciare eccezioni personalizzate quando l'asserzione fallisce.

Mentre la vecchia API continua ad essere mantenuta per compatibilità, assert() è ora un costrutto del linguaggio, consentendo al primo parametro di essere un'espressione piuttosto che solo una string da essere valutata o un valore bool da essere testato.

<?php
ini_set
('assert.exception', 1);

class
CustomError extends AssertionError {}

assert(false, new CustomError('Qualche messaggio di errore'));
?>

Il precedente esempio visualizzerà:

Fatal error: Uncaught CustomError: Qualche messaggio di errore

Tutti i dettagli su questa funzione, incluso come configurarla sia in ambienti di sviluppo che di produzione, possono essere trovati nella sezione aspettative del riferimento assert().

Raggruppare le dichiarazioni use

Classi, funzioni e costanti importati dallo stesso namespace possono ora essere raggruppati insieme in una singola istruzione use.

<?php
// Codice prima di PHP 7
use some\namespace\ClassA;
use
some\namespace\ClassB;
use
some\namespace\ClassC as C;

use function
some\namespace\fn_a;
use function
some\namespace\fn_b;
use function
some\namespace\fn_c;

use const
some\namespace\ConstA;
use const
some\namespace\ConstB;
use const
some\namespace\ConstC;

// Codice PHP 7+
use some\namespace\{ClassA, ClassB, ClassC as C};
use function
some\namespace\{fn_a, fn_b, fn_c};
use const
some\namespace\{ConstA, ConstB, ConstC};
?>

Generatore di espressioni di ritorno

Questa caratteristica si basa sulle funzionalità del generatore introdotte in PHP 5.5. Si abilita per un'istruzione return per essere usata all'interno di un generatore per abilitare per una espressione final per essere restituita (il ritorno per referenza non è permesso). Questo valore può essere preso usando il nuovo metodo Generator::getReturn(), che può solo essere usato una volta che il generatore ha finito di effettuare lo yield dei valori.

<?php

$gen
= (function() {
yield
1;
yield
2;

return
3;
})();

foreach (
$gen as $val) {
echo
$val, PHP_EOL;
}

echo
$gen->getReturn(), PHP_EOL;

Il precedente esempio visualizzerà:

1
2
3

Essere in grado di restituire esplicitamente un valore final da un generatore è un'abilità comoda da avere. Questo perchè abilita per un valore final da essere restituito da un generatore (forse da qualche forma di routine di computazione) che può essere specificamente gestito dal codice client eseguendo il generatore. Questo è molto più semplice rispetto a forzare il codice del client a controllare prima che il valore final sia stato yieldato, e in quel caso, gestire il valore specificamente.

Delegazione del generatore

I generatori possono ora delegare ad un altro generatore, oggetti Traversable o array automaticamente, senza la necessita di scrivere boilerplate nel generatore più esterno usando il costrutto yield from.

<?php
function gen()
{
yield
1;
yield
2;
yield from
gen2();
}

function
gen2()
{
yield
3;
yield
4;
}

foreach (
gen() as $val)
{
echo
$val, PHP_EOL;
}
?>

Il precedente esempio visualizzerà:

1
2
3
4

Divisione intera con intdiv()

La nuova funzione intdiv() esegue una divisione intera dei suoi operandi e la restituisce.

<?php
var_dump
(intdiv(10, 3));
?>

Il precedente esempio visualizzerà:

int(3)

Opzioni di sessione

session_start() ora accetta un array di opzioni che sovrascrivono le direttive di configurazione della sessione normalmente impostate nel php.ini.

Queste opzioni sono state inoltre ampliate per supportare session.lazy_write, che è attivo di default e fa in modo che PHP possa solo sovrascrivere qualsiasi file di sessione se i dati di sessione sono cambiati, e read_and_close, che è un'opzione che può solo essere passata a session_start() per indicare che i dati di sessione dovrebbero essere letti e quindi che la sessione deve essere immediatamente chiusa senza cambiamenti.

Per esempio, impostare session.cache_limiter a private e chiudere immediatamente la sessione dopo averla letta:

<?php
session_start
([
'cache_limiter' => 'private',
'read_and_close' => true,
]);
?>

preg_replace_callback_array()

La nuova funzione preg_replace_callback_array() abilita il codice per essere scritto in maniera più pulita quando si usa la funzione preg_replace_callback(). Prima di PHP 7, le callback che avevano bisogno di essere eseguite per espressioni regolari richiedevano che la funzione di callback venisse sporcata con un sacco di ramificazione.

Ora, le callback possono essere registrate ad ogni espressione regolare usando un array associativo, dove la chiave è un'espressione regolare e il valore è una callback.

CSPRNG Functions

Due nuove funzioni sono state aggiunte per generare interi e stringhe crittograficamente sicuri in modo cross-platform: random_bytes() e random_int().

list() può sempre spacchettare oggetti implementando ArrayAccess

Precedentemente, non era garantito che list() operasse correttamente con gli oggetti che implementavano ArrayAccess. Questo è stato risolto.

Altre Caratteristiche

  • È stato aggiunto l'accesso ai membri della classe in fase di clonazione, per esempio (clone $foo)->bar().
add a note

User Contributed Notes 2 notes

up
60
Adrian Wiik
4 years ago
A good rule of thumb for remembering what the spaceship operator expression returns is to replace the spaceship operator with a minus sign (-). If the result is negative, 0 or positive, the expression will return -1, 0 or 1 respectively.

Example:
<?php
echo 5 <=> 8; // 5 - 8 = -3, prints -1
echo 2 <=> 2; // 2 - 2 = 0, prints 0
echo 4 <=> 2; // 4 - 2 = 2, prints 1
up
16
Julian Sawicki
4 years ago
In php 7.0 it's possible to curry functions in a way that's similar to JavaScript.

<?php

// A curried function
function add($a) {
return function(
$b) use ($a) {
return
$a + $b;
};
}

// Invoking curried function in PHP 7
$result = add(10)(15);

var_dump($result); // int 25

?>

Currying in this way is not possible in php 5.6.
To Top