PHP 8.6 komt op 19 november: dit is er nieuw en dit moet je testen
PHP 8.6 verschijnt op 19 november. Partial function application, clamp(), veiligere sessie-instellingen en een paar wijzigingen die je eerst moet testen.
Over twee weken is PHP 8.6 er. De release staat gepland voor donderdag 19 november 2026. RC4 kwam uit op 21 oktober en RC5 staat voor 5 november op de planning. De features liggen sinds de feature freeze van 22 september vast, dus je kunt nu al zien wat er verandert.
Ik zet hieronder op een rij wat er nieuw is, wat stuk kan gaan en hoe je je upgrade voorbereidt.
Wat er nieuw is #
Partial function application #
Dit is de grootste wijziging aan de taal. Zet je bij een functieaanroep een ? of ... neer in plaats van een argument, dan roept PHP de functie niet aan maar krijg je een closure terug. ? staat voor precies één argument, ... voor alle overige argumenten.
$makeSlug = str_replace(' ', '-', ?);
$makeSlug('Hello World'); // Hello-World
$titles = array_map(strtolower(?), $titles);
Tot nu toe schreef je daarvoor een arrow function als fn ($s) => str_replace(' ', '-', $s). De closure die je nu krijgt neemt de parameternamen en types van de oorspronkelijke functie over.
Er zijn twee dingen die afwijken van een arrow function:
- De argumenten die je al invult worden direct geëvalueerd, op het moment dat de partial wordt gemaakt, en niet pas bij de aanroep. Zet je er een functieaanroep in, dan draait die meteen.
- Een vervolg-RFC regelt dat elke
?een verplichte parameter wordt, ook als de originele parameter optioneel was. Optionele parameters houd je alleen via....
Op new werkt het niet: new Foo(1, ?) is een compile error. Een statische factory als Foo::make(1, ?) mag wel.
clamp() #
Eindelijk een ingebouwde manier om een waarde tussen twee grenzen te houden, zonder max($min, min($max, $value)):
clamp(10, min: 0, max: 100); // 10
clamp(101, min: 0, max: 100); // 100
clamp(-1, min: 0, max: 100); // 0
Is $min groter dan $max, of is een van de grenzen NAN, dan krijg je een ValueError.
Readonly properties met een standaardwaarde #
Tot nu toe gaf een default op een readonly property een compile error. In 8.6 mag het:
final class RuleA implements Rule
{
public readonly string $className = SomeParser::class;
}
Let op: zo'n property kun je daarna niet meer in de constructor zetten. Dat geeft Cannot modify readonly property.
Kleinere toevoegingen #
Time\Duration: een readonly klasse voor tijdsduren met nanoseconde-precisie, met optellen, delen en vergelijken. Handig voor retry-logica, bijvoorbeeldDuration::fromMilliseconds(100)->multiplyBy(2 ** $attempt).- Polling API (
Io\Poll): één interface boven epoll, kqueue en WSAPoll, als vervanger vanstream_select()in event loops. - Betere foutafhandeling voor streams: met de context-optie
error_modekun je streams exceptions laten gooien in plaats van warnings. #[\Override]op class constants, zodat je fouten ziet als een constante in de parent wordt hernoemd.- Enums mogen
__debugInfo()hebben, voor leesbaarderevar_dump()-output. - Doc comments op parameters, uit te lezen met
ReflectionParameter::getDocComment(). enum SortDirectionmetAscendingenDescending. Er is nog niets in de core dat hem gebruikt, maar frameworks kunnen hem nu als gedeelde type aannemen.grapheme_strrev()keert een string om zonder emoji en samengestelde tekens kapot te maken.
Wat stuk kan gaan #
Sessies zijn standaard veiliger #
Drie standaardwaarden in ext/session veranderen:
| Instelling | Was | Wordt |
|---|---|---|
session.use_strict_mode |
0 | 1 |
session.cookie_httponly |
0 | 1 |
session.cookie_samesite |
leeg | Lax |
Voor de meeste sites is dit gewoon winst. Problemen kun je verwachten als:
- je JavaScript de sessiecookie leest via
document.cookie; - je een cross-site POST met sessie nodig hebt, zoals SAML-login die vanuit je eigen site start of een oud formulier dat vanaf een ander domein post. Die requests sturen de sessiecookie niet meer mee;
- je zelf een sessie-ID van buitenaf meegeeft, bijvoorbeeld om een sessie tussen subdomeinen over te dragen.
Staan deze waarden expliciet in je php.ini, dan wint die. Laravel beheert zijn eigen sessiecookies en heeft hier dus weinig last van. Dit gaat vooral over code die session_start() direct gebruikt.
Deprecations en kleine gedragswijzigingen #
- Een waarde returnen uit
__construct()of__destruct()geeft een deprecation. Een kalereturn;mag nog wel. In de volgende major wordt het een compile error. trim(),ltrim()enrtrim()halen nu standaard ook form feed (\f) weg.array_filter()gooit eenValueErrorbij een ongeldige$mode.- De mbregex-functies (
mb_ereg*,mb_split()en verwante) zijn deprecated en verdwijnen in PHP 9.0, omdat de onderliggende Oniguruma-bibliotheek niet meer wordt onderhouden. Gebruik je ze, dan is dit een goed moment om naarpreg_*over te stappen.
Hoe je je upgrade voorbereidt #
Wacht op je framework. Laravel 13 ondersteunt officieel PHP 8.3 tot en met 8.5. 8.6 staat nog niet in de supporttabel. Upgrade productie pas als je framework en je belangrijkste packages 8.6 ondersteunen.
Kijk welke packages je tegenhouden. Composer kan je vertellen welke dependencies PHP 8.6 blokkeren:
composer why-not php 8.6.0
Test nu al in een aparte omgeving. Draai je testsuite tegen de RC in een losse container of een extra CI-job, en zet daar deprecations aan (error_reporting=E_ALL). Zoek in je code naar plekken die geraakt worden:
grep -rn "document.cookie" resources/ public/
grep -rn "mb_ereg" app/ src/
Upgrade daarna in kleine stappen: eerst lokaal en in CI, dan acceptatie, dan productie. Houd de vorige PHP-versie als image of pakket beschikbaar, zodat je snel terug kunt.
PHP 8.6 is geen release waar je voor moet rennen. Je hoeft niets te herschrijven, en wat er nieuw is maakt alledaagse code korter. Het enige waar je echt op moet letten zijn de sessie-instellingen als je oudere PHP-code zonder framework draait.
Bronnen #
- PHP 8.6 release schedule (wiki.php.net)
- PHP RFC-overzicht, sectie PHP 8.6
- RFC: Partial Function Application v2
- RFC: Partial Function Application, handling of optional parameters
- RFC: clamp()
- RFC: Readonly Property Defaults
- RFC: Secure Session Configuration Defaults
- RFC: Deprecate returning values from
__construct()and__destruct() - RFC: Oniguruma maintenance end and end of mbregex
- Laravel News: What's New in PHP 8.6
- PHP.Watch: PHP 8.6
- Laravel 13 release notes en supporttabel
Mitchel van Emmerik