PHP 7.4 is de meest recente (minor) release en is voor algemene beschikbaarheid uitgegeven op 28 november 2019. Hoog tijd om eens goed te kijken naar een aantal van de meest interessante toevoegingen en nieuwe features die PHP sneller en betrouwbaar maken.
Update: PHP 8.1 (officiële release) is nu beschikbaar voor alle Kinsta klanten. PHP 7.4 wordt niet langer ondersteund door Kinsta. Houd er rekening mee dat we PHP versies 7.4, 8.0, 8.1, 8.2, 8.3 en 8.4 ondersteunen.
PHP 7.4 geeft een enorme boost in performance en leesbaarheid van code en wordt beschouwd als een tussenstap naar PHP 8. Voor deze laatste versie zijn de verwachtingen hooggespannen, helemaal wat betreft performance, omdat de opname van JIT al is goedgekeurd.
Hoe dan ook, vandaag bespreken we meest interessante functies en veranderingen die we kunnen verwachten van PHP 7.4. Dit waren de belangrijkste datums voor versie 7.4:
- 6 juni 2019: PHP 7.4 Alpha 1
- 18 juli: PHP 7.4 Beta 1 – Feature freeze
- 28 november 2019: PHP 7.4 GA Release
De volledige lijst met features en toevoegingen kan je vinden op de officiële RFC-pagina vinden.
Wat is nieuw in PHP in PHP 7.4?
In dit artikel bespreken we een aantal veranderingen en features die aan de taal worden toegevoegd wanneer de definitieve versie van PHP 7.4 wordt uitgebracht:
Vergeet array_merge: PHP 7.4 introduceert Spread Operator in Array Expression
Argument unpacking is een syntax die sinds PHP 5.6 gebruikt kan worden om arrays en Traversables uit te pakken in argumentlijsten. Om een array of een Traversable uit te pakken, moet deze worden voorafgegaan door … (3 punten), zoals je in het onderstaande voorbeeld kan zien:
function test(...$args) { var_dump($args); }
test(1, 2, 3);
In PHP 7.4 RFC staat het voorstel om deze feature uit te breiden naar array definitions
$arr = [...$args];
Het eerste voordeel van het gebruik van Spread Operator in array expression heeft te maken met de performance. Dit is wat het RFC-document vermeldt:
Spread operator zou voor betere prestaties zorgen dan
array_merge
. Dat is niet alleen omdat spread operator een taalstructuur is enarray_merge
een functie is, maar ook omdat de optimalisatie van compilatietijd kan worden gebruikt voor constant arrays.
Een belangrijk voordeel van Spread operator is dat deze alle verplaatsbare objecten ondersteunt, terwijl de array_merge
functie alleen arrays ondersteunt.
Hier is een voorbeeld van argument unpacking in array expression:
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);
Als je deze code uitvoert met PHP 7.3 of lager, dan krijg je een PHP Parse-error:
Parse error: syntax error, unexpected '...' (T_ELLIPSIS), expecting ']' in /app/spread-operator.php on line 3
In PHP 7.4 krijg je echter een array terug:
array(5) {
[0]=>
string(6) "banana"
[1]=>
string(6) "orange"
[2]=>
string(5) "apple"
[3]=>
string(4) "pear"
[4]=>
string(10) "watermelon"
}
De RFC meldt verder dat we deze array ook meerdere keren kunnen uitbreiden. We kunnen de Spread Operator-syntax overal binnen de array gebruiken, omdat normale elementen vóór of na de spread operator kunnen worden toegevoegd. Dus de volgende code werkt zoals we kunnen verwachten:
$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];
Het is ook mogelijk om een array, die door een functie is geretourneerd, direct uit te pakken in een nieuwe array:
function buildArray(){
return ['red', 'green', 'blue'];
}
$arr1 = [...buildArray(), 'pink', 'violet', 'yellow'];
In PHP 7.4 krijg je dan de volgende array:
array(6) {
[0]=>
string(3) "red"
[1]=>
string(5) "green"
[2]=>
string(4) "blue"
[3]=>
string(4) "pink"
[4]=>
string(6) "violet"
[5]=>
string(6) "yellow"
}
We kunnen ook de generator syntax gebruiken:
function generator() {
for ($i = 3; $i <= 5; $i++) {
yield $i;
}
}
$arr1 = [0, 1, 2, ...generator()];
Echter, het is niet toegestaan om arrays uit de pakken die zijn doorgegeven door een verwijzing. In het volgende voorbeeld leg ik het uit:
$arr1 = ['red', 'green', 'blue'];
$arr2 = [...&$arr1];
Als we nu een array willen uitpakken door te verwijzen, dan genereert PHP de volgende Parse-error:
Parse error: syntax error, unexpected '&' in /app/spread-operator.php on line 3
Als de elementen van de eerste array door verwijzing zijn opgeslagen, worden ze ook door verwijzing in de tweede array opgeslagen. Hier is een voorbeeld:
$arr0 = 'red';
$arr1 = [&$arr0, 'green', 'blue'];
$arr2 = ['white', ...$arr1, 'black'];
Dit is wat we krijgen met PHP 7.4:
array(5) {
[0]=>
string(5) "white"
[1]=>
&string(3) "red"
[2]=>
string(5) "green"
[3]=>
string(4) "blue"
[4]=>
string(5) "black"
}
Het voorstel om Spread operator toe te voegen was goedgekeurd met 43 stemmen voor en 1 stem tegen.
Arrow Functions 2.0 (Short Closures)
In PHP worden anonieme functies vaak beschouwd als moeilijk te begrijpen en lastig in te voeren en te onderhouden. Deze RFC stelt voor om de kortere syntax van de arrow functies (of short closures) te introduceren. Hiermee zou je je PHP-code flink kunnen opschonen.
In het volgende voorbeeld leg ik het uit:
function cube($n){
return ($n * $n * $n);
}
$a = [1, 2, 3, 4, 5];
$b = array_map('cube', $a);
print_r($b);
PHP 7.4 maakt het gebruik van een meer beknopte syntax mogelijk en de bovenstaande functie kan als volgt worden herschreven:
$a = [1, 2, 3, 4, 5];
$b = array_map(fn($n) => $n * $n * $n, $a);
print_r($b);
Momenteel kunnen anonieme functies (closures) de variabelen die zijn gedefinieerd in de parent scope inheritten. Dit doen ze met behulp van de use taalconstructie, zoals je hieronder kan zien:
$factor = 10;
$calc = function($num) use($factor){
return $num * $factor;
};
Echter, met PHP 7.4 worden de variabelen die zijn gedefinieerd in de parent scope, impliciet vastgelegd op waarde (implicit by-value scope binding). We kunnen dus de hele functie die je boven zag, als volgt schrijven:
$factor = 10;
$calc = fn($num) => $num * $factor;
De variabele die is gedefinieerd in de parent scope kan gebruikt worden in de arrow functie, alsof we gebruik maken van use($var)
en het is niet mogelijk om een variabele van de parent scope te wijzigen.
De nieuwe syntax is een grote verbetering van de taal, omdat de code beter leesbaar en te onderhouden is. We kunnen ook parameter en return types gebruiken, standaard waarden, argumentlijsten met variabele lengtes (variadic functions), we kunnen pass en return door verwijzing, etc. Ten slotte kunnen short closures ook gebruikt worden in class methodes en maken ze net als normale closures gebruik van de