PHP · PHP 8.6 · STAND 01.11.2026

PHP 8.6: Neuerungen, Änderungen und was jetzt zu prüfen ist

PHP 8.6 soll am 19. November 2026 erscheinen. Zu den Neuerungen gehören Partial Function Application, eine Polling-API, die Klasse Time\Duration und Standardwerte für readonly Properties. Wichtiger für bestehende Anwendungen sind die strengeren Session-Defaults und eine lange Liste von Deprecations.

PHP 8.6 · RELEASE-PLAN
● Release Candidate
21.10.2026
RC4 erschienen
05.11.2026
RC5 geplant
19.11.2026
GA geplant
Partial Function Application● Neu
Polling-API (Io\Poll)● Neu
Time\Duration● Neu
Session-Defaults● Strenger
Deprecations● Viele

Quelle: Release-Plan und RFCs auf wiki.php.net. Stand 1. November 2026.

✓ Gegen RFCs und Release-Plan geprüft
✓ Stand 1. November 2026
✓ Mit Hinweisen für Hosting
✓ Praxisbefehle für den Umstieg
PHP 8.6 Neuerungen: Codefenster mit Partial Function Application, Pipe-Operator und clamp()

STAND

Release-Termin und Entwicklungsstand

Der Release-Plan sieht PHP 8.6.0 für den 19. November 2026 vor. Release Candidate 1 wurde übersprungen, RC2 erschien am 24. September, RC3 am 8. Oktober und RC4 am 21. Oktober. Für den 5. November ist RC5 eingeplant. Plan und einzelne Details der Version können sich bis zum Release noch ändern.

Release Candidates sind für Tests gedacht und gehören nicht auf Produktivsysteme. Anwendungen, Bibliotheken und Erweiterungen lassen sich schon jetzt testen. Freigeben sollte man PHP 8.6 erst nach dem finalen Release und einer eigenen Kompatibilitätsprüfung. Zend erwartet aktive Unterstützung bis Ende 2028 und Sicherheitsunterstützung bis Ende 2030, verbindlich sind die Termine erst mit dem Release.

NEUERUNGEN

Die wichtigsten Neuerungen in PHP 8.6

Partial Function Application

Mit Partial Function Application (PFA) lassen sich Funktionen teilweise vorbelegen. Der Platzhalter ? markiert ein Argument, das später übergeben wird, ... steht für alle restlichen. PHP erzeugt daraus eine Closure. Jedes ? wird dabei zu einem Pflichtparameter der Closure, auch wenn der Parameter der Originalfunktion optional war.

⚙

Eigene und eingebaute Funktionen

PHP
$makeSlug = str_replace(' ', '-', ?);

echo $makeSlug('Hello World');
// Hello-World

function multiply(int $a, int $b): int
{
    return $a * $b;
}

$double = multiply(2, ?);
echo $double(5);
// 10

Bei str_replace() sind die ersten beiden Argumente festgelegt, der Platzhalter steht für das Subjekt.

→

Zusammen mit dem Pipe-Operator

PHP
$output = 'Hello World'
    |> str_replace(' ', '-', ?)
    |> strtolower(...);

echo $output;
// hello-world

Der Pipe-Operator erwartet eine Funktion mit genau einem Argument. PFA liefert sie, ohne dass dafür eine eigene Closure wie fn($v) => str_replace(' ', '-', $v) nötig ist.

PFA ergänzt das bisherige Funktionsmodell und ist vor allem bei Callbacks, Array-Funktionen und Verarbeitungsketten praktisch.

Readonly Properties mit Standardwerten

Instanz-Properties mit readonly dürfen in PHP 8.6 einen Standardwert haben. Bisher war das ein Fehler beim Kompilieren. Das RFC wurde mit 24 zu 0 Stimmen angenommen und ist umgesetzt. Es betrifft normale deklarierte Properties und Properties in readonly-Klassen. Standardwerte an promoted Constructor-Parametern bleiben ganz normale Parameter-Defaults und sind nicht Teil der Änderung.

PHP
final class ApiConfig
{
    public readonly string $host = 'localhost';
    public readonly int $port = 443;
}

Der Standardwert gilt als Initialisierung. Die Property ist also schon gesetzt, bevor der Konstruktor läuft, und jede spätere Zuweisung wirft einen Fehler, auch im Konstruktor.

PHP
final class ApiConfig
{
    public readonly int $port = 443;

    public function __construct()
    {
        $this->port = 8443; // Fehler: bereits initialisiert
    }
}

Nutzen hat das vor allem bei unveränderlichen Konfigurationsobjekten und bei Klassen, die Interfaces mit { get; }-Properties erfüllen.

Polling-API für I/O

Für I/O-Multiplexing gab es bisher im Wesentlichen stream_select(). Die neue Polling-API im Namespace Io\Poll bietet eine einheitliche Schnittstelle über die Mechanismen des Betriebssystems: epoll unter Linux, kqueue unter BSD und macOS, Event Ports unter Solaris und illumos, WSAPoll unter Windows und poll als Fallback auf anderen POSIX-Systemen. Das Backend wird standardmäßig automatisch gewählt. Das RFC wurde mit 33 zu 1 Stimmen angenommen.

PHP
use Io\Poll\Context;
use Io\Poll\Event;

$context = new Context();

$stream = stream_socket_server('tcp://0.0.0.0:8080', $errno, $errstr);
stream_set_blocking($stream, false);

// StreamPollHandle liegt im globalen Namespace
$handle = new StreamPollHandle($stream);

$context->add($handle, [Event::Read], ['type' => 'server']);

while (true) {
    $watchers = $context->wait(1); // Timeout in Sekunden

    // Ereignisse verarbeiten
}

add() gibt ein Watcher-Objekt zurück, wait() liefert die Watcher mit ausgelösten Ereignissen. Welche Timeout-Typen wait() in 8.6 akzeptiert, ist nach den RFC-Texten nicht eindeutig: Das Polling-RFC nennt Sekunden und Mikrosekunden als Integer, das Duration-RFC spricht von einer Duration. Wer die API einsetzt, prüft die Signatur im Manual oder in einer Release Candidate.

Für ReactPHP, Amp und Revolt kann die API eine gemeinsame Grundlage sein, statt dass jede Bibliothek die Betriebssystem-Backends selbst anbindet. Asynchron wird PHP dadurch nicht: Die API ist laut RFC minimal gehalten und bringt weder eine Event-Loop noch eine Async-Laufzeit mit. Timer, Signale, Prozessverwaltung und die Ereignisverarbeitung bleiben Sache der Anwendung oder der Bibliothek. Erweiterungen um Timer-, Signal- und Prozess-Handles liegen als eigenes RFC vor, das für PHP 8.7 vorgesehen ist. Der Hauptgrund für die API liegt in PHP selbst: PHP-FPM, Signalbehandlung in ZTS und weitere interne Komponenten sollen von einer einheitlichen Polling-Infrastruktur profitieren.

Time\Duration

Time\Duration ist eine final readonly Klasse für Zeitspannen mit Nanosekunden-Genauigkeit. Es gibt Factory-Methoden wie fromSeconds(), fromMilliseconds(), fromMinutes() und fromIso8601DurationString(), außerdem add(), sub(), multiplyBy(), divideBy(), negate() und absolute(). Zeitspannen lassen sich mit < und > vergleichen. Das RFC wurde mit 35 zu 1 Stimmen angenommen.

PHP
use Time\Duration;

$base = Duration::fromMilliseconds(100);

// Duration ist unveränderlich, add() und multiplyBy() geben neue Objekte zurück
$total = $base->add(Duration::fromSeconds(2));

$attempt = 5;
$delay = $base->multiplyBy(2 ** $attempt);

if ($delay < Duration::fromSeconds(10)) {
    // Backoff liegt unter dem Limit
}

sleep() und usleep() akzeptieren Duration nicht. Das RFC schlägt keine Änderung bestehender Funktionen vor, die Beispiele dort sind ausdrücklich hypothetisch. Anders als DateTimeImmutable beschreibt Duration eine Zeitspanne und keinen Zeitpunkt oder ein Kalenderintervall.

Reflection: isReadable() und isWritable()

ReflectionProperty bekommt isReadable() und isWritable(). Im RFC-Code heißt die Methode isWritable, nur der URL-Slug des RFC enthält „iswriteable“. Beide Methoden nehmen einen Scope (null für den globalen Scope oder einen Klassennamen) und optional ein Objekt. Das RFC wurde mit 27 zu 0 Stimmen angenommen.

PHP
final class Book
{
    public private(set) string $title;
}

$property = new ReflectionProperty(Book::class, 'title');

var_dump($property->isReadable(scope: null)); // true
var_dump($property->isWritable(scope: null)); // false, von außen nicht schreibbar

Nötig wurden die Methoden, weil readonly (PHP 8.1) und asymmetrische Sichtbarkeit (PHP 8.4) die Annahme gebrochen haben, dass isPublic() auch etwas über Schreibbarkeit aussagt. Ohne Objekt wertet PHP nur die statischen Eigenschaften aus. Mit Objekt berücksichtigt es, ob eine readonly Property schon initialisiert ist. Gebraucht werden die Methoden vor allem in ORMs, Serializern, DI-Containern und Frameworks. In normalen Anwendungen fällt die Änderung kaum auf.

DocComments an Funktionsparametern

Dokumentationskommentare dürfen direkt an einzelnen Parametern stehen, vor dem Parameter oder dahinter und vor dem folgenden Komma. ReflectionParameter::getDocComment() liest sie aus. Das RFC wurde mit 23 zu 0 Stimmen angenommen.

PHP
function store(
    /** @param Book[] */
    array $books,
): void {
    // ...
}

$parameters = (new ReflectionFunction('store'))->getParameters();
$comment = $parameters[0]->getDocComment();

Statische Analyse, IDEs und Codegeneratoren können Typinformationen so gezielt einem Parameter zuordnen, statt sie aus einem gemeinsamen Funktionskommentar herauszulesen.

Kleinere Neuerungen

⇅

enum SortDirection

Eine globale Enum mit den Fällen Ascending und Descending als einheitlicher Typ für Sortierrichtungen. Eingebaute Funktionen wie array_multisort() oder scandir() akzeptieren sie noch nicht, Bibliotheken müssen sie selbst auswerten. Das RFC wurde mit 22 zu 2 Stimmen angenommen.

↔

clamp()

PHP
clamp(101, 0, 100);
// 100

clamp(-1, 0, 100);
// 0

Begrenzt einen Wert auf einen Bereich, auch für Strings und DateTime-Objekte. Ist min größer als max, wirft die Funktion einen ValueError. Eine Eingabevalidierung ersetzt sie nicht.

🔎

Enums mit __debugInfo()

Enums dürfen __debugInfo() implementieren und damit steuern, wie var_dump() sie ausgibt. Das hilft bei der Fehlersuche in Domain-Modellen. Zu dieser Änderung liegen nur Übersichtsartikel vor, ein einzelnes RFC wurde nicht geprüft.

Weitere Änderungen

Mehrere Übersichten (Zend, DEV Community) nennen darüber hinaus diese Punkte. Sie sind nicht einzeln gegen RFCs geprüft.

  • Die Funktionen mb_ereg*() und mb_split() sind deprecated und sollen in PHP 9.0 entfallen, weil Oniguruma nicht mehr gepflegt wird. Als Alternative nennt Zend PCRE mit dem Modifier /u.
  • php://filter-Ketten sind standardmäßig auf 16 Filter begrenzt. Das Limit lässt sich anheben.
  • Rückgabewerte aus __construct() und __destruct() lösen eine Deprecation aus und sollen in PHP 9.0 zum Fehler werden.
  • mysqli_quote_string() kommt als Gegenstück zu PDO::quote().
  • TLS-Sessions können über mehrere Requests auf derselben Verbindung wiederverwendet werden.
  • #[\Override] lässt sich auf Klassenkonstanten anwenden.

SICHERHEIT

Session-Defaults werden strenger

Für bestehende Anwendungen sind die geänderten Session-Defaults die praktisch wichtigste Änderung. Das RFC „Secure Session Configuration Defaults“ wurde angenommen: Jede der drei Einstellungen bekam eine eigene Abstimmung, alle mit mindestens 26 Ja-Stimmen und ohne Gegenstimme.

EinstellungBisherPHP 8.6
session.use_strict_mode01
session.cookie_httponly01
session.cookie_samesiteleerLax

Das RFC ändert die eingebauten Defaults im Quellcode. Ob auch php.ini-development und php.ini-production angepasst werden, nennt es nicht, und eine Übersicht (Laravel News) spricht von „neuen Installationen“. Wer sich auf ein Verhalten verlassen will, setzt die drei Werte deshalb explizit.

session.use_strict_mode

PHP weist ungültige oder nicht akzeptierte Session-IDs zurück, was gegen Session-Fixation hilft. Anwendungen, die Session-IDs bewusst zwischen Subdomains übergeben, können mit dem dateibasierten Handler auf Probleme stoßen: Existiert die Session-Datei auf der empfangenden Seite noch nicht, wird die ID abgelehnt. Die Session sollte auf der Ursprungsseite geschrieben und mit session_write_close() geschlossen werden, bevor die ID weitergegeben wird. Handler, deren validateId() true liefert, sind nicht betroffen. Eigene Handler brauchen korrekte create_sid() und validateId().

session.cookie_httponly

JavaScript kann das Session-Cookie nicht mehr über document.cookie lesen. Anwendungen, die die Session-ID im Browser auslesen und etwa in eigene Header schreiben, müssen angepasst werden. Für Werte, die im Browser gebraucht werden, ist ein separates CSRF- oder Anwendungstoken der richtige Weg.

session.cookie_samesite=Lax

Das Cookie wird bei normalen same-site-Anfragen und bei Top-Level-Navigationen mit sicheren HTTP-Methoden gesendet, bei Cross-Site-POST-Anfragen nicht. Das RFC nennt SP-initiiertes SAML Single Sign-on und ältere Cross-Origin-Formulare als betroffen, dazu kommen externe Login-Prozesse. Wer Cross-Site-POST mit Session-Cookie braucht, muss die Cookie-Einstellungen gezielt setzen, in manchen Fällen mit SameSite=None; Secure, oder auf einen tokenbasierten Ablauf umstellen.

Die Änderung macht bisher implizite Annahmen sichtbar. SSO- und Login-Abläufe sollten deshalb vor dem Upgrade getestet werden.

DEPRECATIONS

Was Entwickler prüfen sollten

Eine Deprecation heißt: Das Verhalten funktioniert noch, PHP gibt aber eine Warnung aus, und es kann in einer späteren Version entfallen. Das RFC „Deprecations for PHP 8.6“ umfasst 35 einzelne Punkte. Nicht alle wurden angenommen: list() und in/out/inout als Bezeichner sind abgelehnt und stehen deshalb nicht in der Liste. Zu einem Teil der angenommenen Punkte stand das Abstimmungsergebnis bei der Prüfung nicht zur Verfügung. Die Liste gibt den RFC-Stand und die Übersichten wieder.

return in finally

Ein return im finally-Block ist deprecated (39 zu 3 Stimmen). Sein Wert überschreibt den Rückgabewert aus try, was überraschend ist und Fehler verdecken kann.

PHP
function getConfig(): array
{
    try {
        return loadConfig();
    } finally {
        return []; // überschreibt den Rückgabewert aus try
    }
}

Die übrigen Deprecations im Überblick

BereichWas deprecated wirdEmpfehlung
Bezeichnerlet und is als Namen für Klassen, Funktionen und Konstanten (Abstimmungsergebnis für is unbekannt); namespace als Klassenkonstante; Funktion namens readonly (39 zu 1); _ als Konstante oder Compile-Time-AliasUmbenennen
Objekte statt Arraysarray_walk(), array_walk_recursive(), deflate_init(), inflate_init(), mb_convert_variables(), http_build_query() sowie die Stream-Filter zlib.* und bzip2.* mit ObjektenEchte Arrays übergeben
Funktions-Aliaseis_double(), is_integer(), is_long(), doubleval()is_float(), is_int(), floatval()
Funktionendefine() mit $case_insensitive; is_a() und is_subclass_of() mit String bei allow_string: false; strcoll(); SORT_LOCALE_STRING; metaphone(); spl_classes(); spl_object_hash()spl_object_id() statt spl_object_hash(), für spl_classes() Reflection
ReflectionReflectionProperty::setValue() und setRawValue() mit Objekt einer falschen Klasse; ReflectionMethod::invoke() und invokeArgs() mit Objekt bei statischen MethodenPassendes Objekt, bei statischen Methoden null
SPLMehrere ArrayIterator-Methoden (getFlags(), setFlags(), asort(), ksort(), uasort(), uksort(), natsort(), natcasesort(), serialize(), unserialize()); die CSV-Methoden von SplFileObjectAuf ArrayObject oder Funktionen ausweichen
mysqli und Sessionsmysqli::stmt_init(); mysqli_get_charset() und mysqli::get_charset(); Session-Handler ohne create_sid() und validateId()$mysqli->prepare(), Handler vervollständigen
KonstruktorenRückgabewerte aus __construct() und __destruct() (laut Zend Fehler ab PHP 9.0)Rückgabewert entfernen
PHP
// Statische Methode über Reflection: null statt Objekt übergeben
$method = new ReflectionMethod(Book::class, 'create');
$method->invoke(null);

// Objekt-ID statt spl_object_hash()
$id = spl_object_id($object);

// Prepared Statement direkt erzeugen
$statement = $mysqli->prepare($sql);

Die meisten Umstellungen sind mechanisch. Frameworks, CMS-Plugins und ältere Anwendungen betrifft es am ehesten, bei den SPL-, Reflection- und Session-Handler-Punkten lohnt ein gezielter Blick.

HOSTING

Was PHP 8.6 für Hosting-Umgebungen bedeutet

🖥

PHP-FPM und paralleler Betrieb

PHP 8.6 braucht eine eigene Runtime mit separaten FPM-Pools, eigenen Sockets oder Ports, passendem CLI-Binary sowie eigenen Konfigurations- und Erweiterungsverzeichnissen. Im Shared Hosting sollte die Version pro Website wählbar sein. Eine globale Umstellung bestehender Websites ist unnötig riskant.

🧩

Native Erweiterungen

Imagick, Redis, Memcached, APCu, ionCube Loader, SourceGuardian und eigene PECL-Erweiterungen müssen für 8.6 verfügbar sein. Erweiterungen mit C-Anteilen werden gegen die passende PHP-Version neu gebaut, bei proprietären Modulen ist die Freigabe des Herstellers abzuwarten. Ein erfolgreicher Core-Build sagt nichts darüber, ob alle Erweiterungen laufen.

⚡

OPcache und Performance

OPcache gehört in die Testplanung: Speicherbedarf, Cache-Invalidierung, Verhalten nach Updates und FPM-Neustarts sowie Unterschiede zwischen CLI und FPM. Ob eine Anwendung schneller wird, zeigen nur realistische Benchmarks.

🔒

Session-Defaults dokumentieren

Kunden sollten wissen, warum sich SSO- oder externe Login-Abläufe nach dem Wechsel anders verhalten können. Einstellungen sind sauber zwischen globaler Konfiguration, FPM-Pools und Website-Konfiguration abzugrenzen.

Beim Rollout lohnt es sich, FPM-Fehler, Worker-Neustarts, Speicherverbrauch, Request-Laufzeiten, Fehler beim Laden von Erweiterungen, Session-Probleme und Deprecation-Meldungen zu überwachen.

Zur Sicherheitslage der aktuellen PHP-Versionen gibt es bei uns zwei Beiträge zu den PHP2Shell-Schwachstellen und den betroffenen Versionen.

KOMPATIBILITÄT

Welche Anwendungen laufen mit PHP 8.6?

Hier gibt es drei Stufen: Eine Anwendung läuft technisch unter PHP 8.6, der Hersteller testet 8.6 regelmäßig, oder der Hersteller gibt 8.6 offiziell frei. Nur die dritte ist eine Kompatibilitätsfreigabe. Bei WordPress, Laravel, Symfony, Nextcloud und anderen großen Projekten gilt das für die konkrete Version, Plugins, Themes, Bundles und Composer-Abhängigkeiten eingeschlossen.

📦

Composer als erste Prüfung

Bash
composer validate
composer check-platform-reqs
composer why-not php 8.6

Die Befehle zeigen, welche Abhängigkeiten PHP 8.6 nicht zulassen. Ein erfolgreicher Check beweist nicht, dass der Code fehlerfrei läuft, dafür braucht es automatisierte Tests.

🔎

Deprecations früh finden

Bash
grep -RInE \
'is_double|is_integer|is_long|doubleval|spl_object_hash|spl_classes' \
./src ./app

PHP 8.6 gehört in eine separate Testumgebung oder in die CI-Matrix. Die Meldungen sollte man auswerten und nicht unterdrücken. Auch die CSV-Methoden, Reflection-Aufrufe und Session-Handler gezielt prüfen.

VORGEHEN

So gelingt der Umstieg

Sinnvoll ist ein Vorgehen in mehreren Schritten.

1

Testumgebung

PHP 8.6 in einer Testumgebung installieren und die Anwendung damit starten.

2

Abhängigkeiten

Composer-Pakete, native Erweiterungen und proprietäre Module kontrollieren.

3

Deprecations

Neue Warnungen auswerten und die betroffenen Stellen im Code korrigieren.

4

Sessions und SSO

Sessions, Cookies, SSO und externe Anmeldung gezielt testen, die drei Session-Werte explizit setzen.

5

Tests und Performance

Unit-, Integrations- und Funktionstests mit 8.6 laufen lassen und Laufzeit sowie Speicherverbrauch mit realistischen Benchmarks vergleichen.

6

Rollout nach GA

Produktiv erst nach dem finalen Release und einem kontrollierten Rollout.

BEI RDDZ

Wie wir mit PHP 8.6 umgehen

Unser Hosting bietet aktuell PHP ab Version 8.3 an. PHP 8.6 bieten wir erst nach dem finalen Release und eigenen Tests an. Wer vorher wissen möchte, ob die eigene Anwendung betroffen ist, kann sich bei uns melden.

FAZIT

Jetzt testen, danach freigeben

Partial Function Application, Time\Duration, die Polling-API und die Reflection-Erweiterungen betreffen vor allem Frameworks, Bibliotheken und komplexere Anwendungen. Für Hosting-Umgebungen und bestehende Anwendungen zählen die geänderten Session-Defaults und die Deprecations mehr.

Produktiv freigeben sollte man PHP 8.6 nach dem Release am 19. November und einer eigenen Kompatibilitätsprüfung. Bis dahin lohnt sich ein Testlauf mit den Release Candidates.

PHP-Update für Ihre Website planen?

Kompatibilität prüfen, Tests aufsetzen, sauber umstellen: Sprechen Sie uns an, wir begleiten Hosting und Betrieb.