{"id":43352,"date":"2021-09-06T13:51:38","date_gmt":"2021-09-06T11:51:38","guid":{"rendered":"https:\/\/kinsta.com\/?p=101567"},"modified":"2023-07-27T11:42:50","modified_gmt":"2023-07-27T10:42:50","slug":"php-8-1","status":"publish","type":"post","link":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/","title":{"rendered":"Was ist neu in PHP 8.1: Funktionen, \u00c4nderungen, Verbesserungen und mehr"},"content":{"rendered":"<p>Seit dem 25. November 2021 ist <a href=\"https:\/\/wiki.php.net\/todo\/php81\">PHP 8.1 endlich da<\/a>, vollgepackt mit vielen spannenden Funktionen.<\/p>\n<p>In diesem Artikel werden wir detailliert auf die Neuerungen in PHP 8.1 eingehen. Von neuen Features und Leistungsverbesserungen bis hin zu signifikanten \u00c4nderungen und Verwerfungen werden wir sie alle im Detail durchgehen.<\/p>\n<p>Bleib dran!<\/p>\n<div><\/div><kinsta-auto-toc heading=\"Table of Contents\" exclude=\"last\" list-style=\"arrow\" selector=\"h2\" count-number=\"-1\"><\/kinsta-auto-toc>\n<h2>Neue Funktionen in PHP 8.1<\/h2>\n<p>Beginnen wir damit, alle neuen Features in PHP 8.1 zu beschreiben. Es ist eine ziemlich lange Liste.<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"20\" sub-toc=\"true\"><\/kinsta-auto-toc>\n<p><aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>PHP 8.1 ist jetzt bei Kinsta f\u00fcr alle Umgebungen verf\u00fcgbar. Weitere Informationen findest du in unserem <a href=\"https:\/\/kinsta.com\/de\/changelog\/php-8-1\/\">PHP 8.1 Feature Update<\/a><\/p>\n<\/aside>\n.<\/p>\n\n<h3>Reine Schnittmengen-Typen<\/h3>\n<p>PHP 8.1 f\u00fcgt Support f\u00fcr Kreuzungstypen hinzu. Es ist \u00e4hnlich wie die <a href=\"https:\/\/kinsta.com\/de\/blog\/php-8\/#union-types-2-0\">Union-Typen<\/a>, die in PHP 8.0 eingef\u00fchrt wurden, aber ihr Verwendungszweck ist das genaue Gegenteil.<\/p>\n<p>Um es besser zu verstehen, lass uns noch einmal auffrischen, wie Typdeklarationen in PHP funktionieren.<\/p>\n<p>Im Wesentlichen kannst du Typdeklarationen zu Funktionsargumenten, R\u00fcckgabewerten und Klasseneigenschaften hinzuf\u00fcgen. Diese Zuweisung wird Type Hinting genannt und stellt sicher, dass der Wert zur Aufrufzeit vom richtigen Typ ist. Ansonsten wirft es sofort einen <a href=\"https:\/\/www.php.net\/manual\/en\/class.typeerror.php\">TypeError<\/a> aus. Das wiederum hilft dir, Code besser zu debuggen.<\/p>\n<p>Allerdings hat die Deklaration eines einzelnen Typs seine Grenzen. Union-Typen helfen dir, das zu \u00fcberwinden, indem sie dir erlauben, einen Wert mit mehreren Typen zu deklarieren, wobei die Eingabe mindestens einem der deklarierten Typen gen\u00fcgen muss.<\/p>\n<p>Auf der anderen Seite beschreibt <a href=\"https:\/\/wiki.php.net\/rfc\/pure-intersection-types\">der RFC<\/a> Kreuzungstypen als:<\/p>\n<blockquote><p><em>Ein &#8222;Kreuzungstyp&#8220; erfordert, dass ein Wert mehrere Type Constraints erf\u00fcllt, anstatt nur einen.<\/em><\/p>\n<p><em>&#8230;reine Kreuzungstypen werden mit der Syntax T1&#038;T2&#038;&#8230; spezifiziert und k\u00f6nnen an allen Stellen verwendet werden, an denen derzeit Typen akzeptiert werden&#8230;<\/em><\/p><\/blockquote>\n<p>Beachte die Verwendung des <code>&<\/code> (AND) Operators, um Schnittmengen zu deklarieren. Im Gegensatz dazu verwenden wir den <code>|<\/code> (OR) Operator, um Vereinigungstypen zu deklarieren.<\/p>\n<p>Die Verwendung der meisten Standardtypen in einem Kreuzungstyp wird zu einem Typ f\u00fchren, der niemals erf\u00fcllt werden kann (z.B. Integer und String). Daher k\u00f6nnen Kreuzungstypen nur Klassentypen enthalten (d.h. Interfaces und Klassennamen).<\/p>\n<p>Hier ist ein Beispielcode, wie du Kreuzungstypen verwenden kannst:<\/p>\n<pre><code class=\"language-php\"><span id=\"urn:enhancement-e28c9395-25bb-42d7-9f26-a81a76ed8ee8\" class=\"textannotation\">class<\/span> A {\n\u00a0 \u00a0 private Traversable&Countable $countableIterator;\n \n\u00a0 \u00a0 public <span id=\"urn:enhancement-7b3de330-3a09-4d3c-8604-87b24163589c\" class=\"textannotation\">function<\/span> setIterator(Traversable&Countable $countableIterator): <span id=\"urn:enhancement-116b1aae-0b15-4cfa-975b-adae945dff16\" class=\"textannotation\">void<\/span> {\n\u00a0 \u00a0 \u00a0 \u00a0 $this-&gt;countableIterator = $countableIterator;\n\u00a0 \u00a0 }\n \n\u00a0 \u00a0 public <span id=\"urn:enhancement-c35e72a7-e45b-4d84-9e8b-24d1a9b0a5a4\" class=\"textannotation\">function<\/span> getIterator(): Traversable&Countable {\n\u00a0 \u00a0 \u00a0 \u00a0 return $this-&gt;countableIterator;\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n<p>Im obigen Code haben wir eine Variable <strong>countableIterator<\/strong> als eine Kreuzung zweier Typen definiert: <strong>Traversable<\/strong> und <strong>Countable<\/strong>. In diesem Fall sind die beiden deklarierten Typen Interfaces.<\/p>\n<p>Schnittpunkttypen entsprechen auch den Standard PHP Varianzregeln, die bereits f\u00fcr Typ\u00fcberpr\u00fcfung und Vererbung verwendet werden. Aber es gibt zwei zus\u00e4tzliche Regeln, wie Kreuzungstypen mit der Subtypisierung interagieren. Du kannst mehr \u00fcber die <a href=\"https:\/\/wiki.php.net\/rfc\/pure-intersection-types#variance\">Varianzregeln von Intersektionstypen<\/a> in ihrem RFC lesen.<\/p>\n<p>In einigen Programmiersprachen kannst du Union Types und Intersection Types in der gleichen Deklaration kombinieren. Aber PHP 8.1 verbietet es. Daher wird seine Implementierung &#8222;reine&#8220; Kreuzungstypen genannt. Der RFC erw\u00e4hnt jedoch, dass es &#8222;ein zuk\u00fcnftiger Bereich&#8220; ist.<\/p>\n<h3>Enums<\/h3>\n<p>PHP 8.1 f\u00fcgt endlich Support f\u00fcr Enums (auch Aufz\u00e4hlungen oder enumerated types genannt) hinzu. Sie sind ein benutzerdefinierter Datentyp, der aus einer Menge von m\u00f6glichen Werten besteht.<\/p>\n<p>Das h\u00e4ufigste Beispiel f\u00fcr Enums in Programmiersprachen ist der <strong>boolesche<\/strong> Typ, mit <code>true<\/code> und <code>false<\/code> als zwei m\u00f6gliche Werte. Es ist so weit verbreitet, dass es in vielen <a href=\"https:\/\/kinsta.com\/de\/blog\/beste-programmiersprache-lernen-sollte\/\">modernen Programmiersprachen<\/a> eingebaut ist.<\/p>\n<p><span style=\"font-family: Roboto, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;font-size: 1rem\">Gem\u00e4\u00df <a href=\"https:\/\/wiki.php.net\/rfc\/enumerations\">dem RFC<\/a> werden Enums in PHP zun\u00e4chst auf &#8222;unit enumerations&#8220; beschr\u00e4nkt sein:<\/span><\/p>\n<blockquote><p><em>Der Anwendungsbereich dieses RFCs ist auf &#8222;unit enumerations&#8220; beschr\u00e4nkt, d.h. Aufz\u00e4hlungen, die selbst ein Wert sind und nicht nur eine ausgefallene Syntax f\u00fcr eine primitive Konstante, und die keine zus\u00e4tzlichen zugeh\u00f6rigen Informationen enthalten. Diese F\u00e4higkeit bietet einen stark erweiterten Support f\u00fcr die Datenmodellierung, benutzerdefinierte Typdefinitionen und monadenartiges Verhalten. Enums erm\u00f6glichen die Modellierungstechnik des &#8222;ung\u00fcltige Zust\u00e4nde nicht repr\u00e4sentierbar machen&#8220;, was zu robusterem Code mit weniger Bedarf an ausf\u00fchrlichen Tests f\u00fchrt.<\/em><\/p><\/blockquote>\n<p>Um zu diesem Stadium zu gelangen, hat das PHP-Team viele Sprachen untersucht, die bereits Enumerationen unterst\u00fctzen. <a href=\"https:\/\/github.com\/Crell\/enum-comparison\">Ihre Umfrage<\/a> ergab, dass man Aufz\u00e4hlungen in drei allgemeine Gruppen kategorisieren kann: Fancy Constants, Fancy Objects und vollst\u00e4ndige algebraische Datentypen (ADTs). Es ist eine interessante Lekt\u00fcre!<\/p>\n<p>PHP implementiert &#8222;Fancy Objects&#8220; Enums, mit Pl\u00e4nen, es in der Zukunft auf volle ADTs zu erweitern. Es ist konzeptionell und semantisch an die Aufz\u00e4hlungstypen in Swift, Rust und Kotlin angelehnt, auch wenn es nicht direkt an einen dieser Typen angelehnt ist.<\/p>\n<p>Der RFC verwendet die ber\u00fchmte Analogie der Farben in einem Kartenspiel, um zu erkl\u00e4ren, wie es funktionieren wird:<\/p>\n<pre><code class=\"language-php\">enum Suit {\n\u00a0 case Hearts;\n\u00a0 case Diamonds;\n\u00a0 case Clubs;\n\u00a0 case Spades;\n}<\/code><\/pre>\n<p>Hier definiert das <strong>Suit<\/strong> enum vier m\u00f6gliche Werte: <strong>Herz<\/strong>, <strong>Karo<\/strong>, <strong>Kreuz<\/strong> und <strong>Pik<\/strong>. Du kannst direkt auf diese Werte zugreifen, indem du die Syntax verwendest: <code>Suit::Hearts<\/code>, <code>Suit::Diamonds<\/code>, <code>Suit::Clubs<\/code>, und <code>Suit::Spades<\/code>.<\/p>\n<p>Diese Verwendung mag vertraut erscheinen, da Enums auf Klassen und Objekten aufgebaut sind. Sie verhalten sich \u00e4hnlich und haben fast die gleichen Anforderungen. Enums teilen sich die gleichen Namespaces wie Klassen, Interfaces und Traits.<\/p>\n<p>Die oben erw\u00e4hnten Enums werden <strong>Pure<\/strong> <strong>Enums<\/strong> genannt.<\/p>\n<p>Du kannst auch <strong>Backed<\/strong> <strong>Enums<\/strong> definieren, wenn du allen F\u00e4llen einen skalaren Ersatzwert geben willst. Allerdings k\u00f6nnen Backed Enums nur einen Typ haben, entweder <code>int<\/code> oder <code>string<\/code> (niemals beides).<\/p>\n<pre><code class=\"language-php\">enum Suit: string {\n\u00a0 case Hearts = 'H';\n\u00a0 case Diamonds = 'D';\n\u00a0 case Clubs = 'C';\n\u00a0 case Spades = 'S';\n}<\/code><\/pre>\n<p>Au\u00dferdem m\u00fcssen alle verschiedenen F\u00e4lle einer backed enum einen eindeutigen Wert haben. Und du kannst niemals pure und backed enums mischen.<\/p>\n<p>Der RFC geht weiter auf Enum Methoden, statische Methoden, Konstanten, konstante Ausdr\u00fccke und vieles mehr ein. Sie alle zu behandeln, w\u00fcrde den Rahmen dieses Artikels sprengen. Du kannst die Dokumentation zu Rate ziehen, um dich mit all ihren Vorz\u00fcgen vertraut zu machen.<\/p>\n<h3>Der <code>never<\/code> Return Type<\/h3>\n<p>PHP 8.1 f\u00fcgt einen neuen R\u00fcckgabetyp-Hinweis namens <code>never<\/code> hinzu. Es ist super hilfreich f\u00fcr Funktionen, die immer einen <code>Throw<\/code> oder <code>Exit<\/code> ausl\u00f6sen.<\/p>\n<p>Wie im <a href=\"https:\/\/wiki.php.net\/rfc\/noreturn_type\">RFC<\/a> beschrieben, sind URL-Redirect-Funktionen, die sich immer <code>exit<\/code> (explizit oder implizit), ein gutes Beispiel f\u00fcr seine Verwendung:<\/p>\n<pre><code class=\"language-php\"><span id=\"urn:enhancement-87c160e1-abc4-47fa-a6ab-f7c427c61ab1\" class=\"textannotation\">function<\/span> redirect(string $uri): never {\n\u00a0 \u00a0 header('Location: ' . $uri);\n\u00a0 \u00a0 <span id=\"urn:enhancement-43e2a752-817e-43ec-ac47-2073b72edb45\" class=\"textannotation\">exit<\/span>();\n}\n \n<span id=\"urn:enhancement-e27b0d77-510b-4fc9-b389-fbf341c7917f\" class=\"textannotation\">function<\/span> redirectToLoginPage(): never {\n\u00a0 \u00a0 redirect('\/login');\n}<\/code><\/pre>\n<p>Eine <code>never<\/code>-declared function sollte drei Bedingungen erf\u00fcllen:<\/p>\n<ul>\n<li>Es sollte kein explizites <code>Return<\/code>-Statement definiert sein.<\/li>\n<li>Es sollte keine implizite <code>Return<\/code>-Anweisung enthalten (z.B. <strong>if-else<\/strong>-Anweisungen).<\/li>\n<li>Es muss seine Ausf\u00fchrung mit einer <code>Exit<\/code>-Anweisung beenden (explizit oder implizit).<\/li>\n<\/ul>\n<p>Das obige Beispiel der <a href=\"https:\/\/kinsta.com\/de\/docs\/wordpress-hosting\/weiterleitungs-regeln\/\">URL-Umleitung<\/a> zeigt sowohl die explizite als auch die implizite Verwendung des <code>never<\/code> return Typs.<\/p>\n<p>Der <code>never<\/code> return Typ hat viele \u00c4hnlichkeiten mit dem <code>void<\/code> return Typ. Sie stellen beide sicher, dass die Funktion oder Methode keinen Wert zur\u00fcckgibt. Jedoch unterscheidet er sich durch die Einhaltung strengerer Regeln. Zum Beispiel kann eine <code>void<\/code>-declared Funktion immer noch ohne einen expliziten Wert zur\u00fcckkehren, aber du <code>return<\/code> das gleiche nicht mit einer <code>never<\/code>-declared Funktion tun.<\/p>\n<p>Als Faustregel gilt: Verwende <code>void<\/code>, wenn du erwartest, dass PHP nach dem Funktionsaufruf weiter ausgef\u00fchrt wird. Verwende <code>never<\/code>, wenn du das Gegenteil willst.<\/p>\n<p>Au\u00dferdem ist <code>never<\/code> als &#8222;bottom&#8220;-Typ definiert. Daher kann jede Klassenmethode, die als <code>never<\/code> deklariert ist, ihren R\u00fcckgabetyp &#8222;never&#8220; in etwas anderes \u00e4ndern. Allerdings kannst du eine <code>void<\/code>-deklarierte Methode mit einer <code>never<\/code>-deklarierten Methode erweitern.<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>Der urspr\u00fcngliche RFC listet den R\u00fcckgabetyp <code>never<\/code> als <code>noreturn<\/code> auf, ein R\u00fcckgabetyp, der bereits von zwei PHP-Tools zur statischen Analyse, n\u00e4mlich Psalm und PHPStan, unterst\u00fctzt wurde. Da dies von den Autoren von Psalm und PHPStan selbst vorgeschlagen wurde, haben sie die Terminologie beibehalten. Aufgrund der Namenskonventionen f\u00fchrte das PHP-Team jedoch eine Abstimmung \u00fcber <code>noreturn<\/code> vs. <code>never<\/code> durch, aus der <code>never<\/code> als ewiger Sieger hervorging. Ersetze daher bei PHP 8.1+ Versionen immer <code>noreturn<\/code> durch <code>never<\/code>.<\/p>\n<\/aside>\n\n<h3>Fibers<\/h3>\n<p>Historisch gesehen ist PHP-Code fast immer synchroner Code. Die Codeausf\u00fchrung h\u00e4lt an, bis das Ergebnis zur\u00fcckgegeben wird, auch bei I\/O-Operationen. Du kannst dir vorstellen, warum dieser Prozess die Codeausf\u00fchrung langsamer machen kann.<\/p>\n<p>Es gibt mehrere L\u00f6sungen von Drittanbietern, um dieses Hindernis zu \u00fcberwinden und es Entwicklern zu erm\u00f6glichen, PHP-Code asynchron zu schreiben, insbesondere f\u00fcr gleichzeitige I\/O-Operationen. Einige beliebte Beispiele sind <a href=\"https:\/\/amphp.org\/\">amphp<\/a>, <a href=\"https:\/\/reactphp.org\/\">ReactPHP<\/a> und <a href=\"https:\/\/guzzlephp.org\/\">Guzzle<\/a>.<\/p>\n<p>Allerdings gibt es keinen Standardweg, um solche Instanzen in PHP zu behandeln. Au\u00dferdem f\u00fchrt die Behandlung von synchronem und asynchronem Code im selben Aufrufstapel <a href=\"https:\/\/journal.stuffwithstuff.com\/2015\/02\/01\/what-color-is-your-function\/\">zu anderen Problemen<\/a>.<\/p>\n<p>Fibers sind PHPs Art, Parallelit\u00e4t \u00fcber virtuelle Threads (oder <a href=\"https:\/\/en.wikipedia.org\/wiki\/Green_threads\">gr\u00fcne Threads<\/a>) zu behandeln. Es versucht, den Unterschied zwischen synchronem und asynchronem Code zu eliminieren, indem es PHP-Funktionen erlaubt, zu unterbrechen, ohne den gesamten Aufrufstapel zu beeinflussen.<\/p>\n<p>Hier ist, was <a href=\"https:\/\/wiki.php.net\/rfc\/fibers\">der RFC<\/a> <em>verspricht<\/em>:<\/p>\n<ul>\n<li>Hinzuf\u00fcgen des Supports f\u00fcr Fibers in PHP.<\/li>\n<li>Einf\u00fchrung einer neuen Fiber-Klasse und der entsprechenden Reflection-Klasse ReflectionFiber.<\/li>\n<li>Hinzuf\u00fcgen der Ausnahmeklassen FiberError und FiberExit zur Darstellung von Fehlern.<\/li>\n<li>Fibers erm\u00f6glichen transparente nicht-blockierende I\/O-Implementierungen von existierenden Interfaces (PSR-7, Doctrine ORM, etc.). Das liegt daran, dass das Platzhalter (promise) Objekt eliminiert wird. Stattdessen k\u00f6nnen Funktionen den I\/O-Ergebnistyp deklarieren anstelle eines Platzhalterobjekts, das keinen Aufl\u00f6sungstyp angeben kann, da PHP keine Generics unterst\u00fctzt.<\/li>\n<\/ul>\n<p>Du kannst Fibers nutzen, um Full-Stack, unterbrechbare PHP-Funktionen zu entwickeln, die du dann nutzen kannst, um kooperatives Multitasking in PHP zu implementieren. Da Fibers den gesamten <a href=\"https:\/\/kinsta.com\/de\/docs\/wordpress-hosting\/wordpress-ueberwachung\/apm-tool\/#stack-trace\">Ausf\u00fchrungsstapel<\/a> unterbricht, kannst du sicher sein, dass es den Rest deines Codes nicht beeintr\u00e4chtigt.<\/p>\n<figure id=\"attachment_110018\" aria-describedby=\"caption-attachment-110018\" style=\"width: 1100px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/kinsta.com\/wp-content\/uploads\/2021\/08\/PHP-8.1-fiber-flow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-110018 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2021\/08\/PHP-8.1-fiber-flow-e1637845079600.png\" alt=\"Diagramm zur Veranschaulichung des Ablaufs von PHP-Code mit Fibers (Quelle: PHP.net).\" width=\"1100\" height=\"894\"><\/a><figcaption id=\"caption-attachment-110018\" class=\"wp-caption-text\">Diagramm zur Veranschaulichung des Ablaufs von PHP-Code mit Fibers (Quelle: PHP.net).<\/figcaption><\/figure>\n<p>Um die Verwendung von Fibers zu veranschaulichen, verwendet der RFC dieses einfache Beispiel:<\/p>\n<pre><code class=\"language-php\">$fiber = <span id=\"urn:enhancement-05237e3d-1803-4a51-8ea1-feb073020320\" class=\"textannotation\">new<\/span> Fiber(<span id=\"urn:enhancement-a1c66c45-41ce-4ee7-bfe1-e2a8112582fd\" class=\"textannotation\">function<\/span> (): <span id=\"urn:enhancement-ffec0fe2-c260-479a-a781-9c3faf0aaa8b\" class=\"textannotation\">void<\/span> {\n\u00a0 \u00a0 $<span id=\"urn:enhancement-5839951e-4829-430c-95c7-758447a07d81\" class=\"textannotation\">value<\/span> = Fiber::suspend('fiber');\n\u00a0 \u00a0 echo \"<span id=\"urn:enhancement-6c9b048e-2ded-456d-80f0-46b5145b7619\" class=\"textannotation\">Value<\/span> used to resume fiber: \", $<span id=\"urn:enhancement-6b95d3e4-105a-4c48-a0ee-b49dc14a88a8\" class=\"textannotation\">value<\/span>, \"<span id=\"urn:enhancement-cb03e071-0ae5-40a5-a4c5-98dfaa60e4a2\" class=\"textannotation\">\\n<\/span>\";\n});\n \n$<span id=\"urn:enhancement-578caa74-358c-4f9a-8fb7-2611f97ff4fa\" class=\"textannotation\">value<\/span> = $fiber-&gt;start();\n \necho \"<span id=\"urn:enhancement-ceab5b9b-563a-4a79-971b-d1ade2194b4e\" class=\"textannotation\">Value<\/span> from fiber suspending: \", $<span id=\"urn:enhancement-b5e8c4d8-bb9a-455b-8920-2076fd65f2f1\" class=\"textannotation\">value<\/span>, \"<span id=\"urn:enhancement-87e489d1-e067-454c-aa1e-402b86e35ea5\" class=\"textannotation\">\\n<\/span>\";\n \n$fiber-&gt;resume('test');<\/code><\/pre>\n<p>Du erstellst im obigen Code eine &#8222;Faser&#8220; und setzt sie sofort mit dem String <code>fiber<\/code> aus. Die <code>echo<\/code>-Anweisung dient als visueller Hinweis f\u00fcr die Wiederaufnahme der Faser.<\/p>\n<p>Du kannst diesen String-Wert durch den Aufruf von <code>$fiber-&gt;start()<\/code> abrufen.<\/p>\n<p>Dann nimmst du die Faser mit der Zeichenkette &#8222;test&#8220; wieder auf, die vom Aufruf von <code>Fiber::suspend()<\/code> zur\u00fcckgegeben wird. Die vollst\u00e4ndige Codeausf\u00fchrung f\u00fchrt zu einer Ausgabe, die lautet:<\/p>\n<pre><code class=\"language-php\"><span id=\"urn:enhancement-78e6c022-38dc-4e2a-981d-86d160d3309d\" class=\"textannotation\">Value<\/span> from fiber suspending: fiber\n<span id=\"urn:enhancement-dd60797f-7a0a-45ab-8ad4-61068ffe329d\" class=\"textannotation\">Value<\/span> used to resume fiber: test<\/code><\/pre>\n<p>Das ist das einfache Lehrbuchbeispiel f\u00fcr PHP Fibers bei der Arbeit. <a href=\"https:\/\/github.com\/nox7\/async-php-8-io-http\">Hier ist ein weiteres Fibers-Beispiel<\/a> f\u00fcr die Ausf\u00fchrung von sieben asynchronen GET-Anfragen.<\/p>\n<p>Trotz allem werden die meisten PHP-Entwickler nie direkt mit Fibers zu tun haben. Und der RFC legt das auch nahe:<\/p>\n<blockquote><p><em>Fibers sind ein fortgeschrittenes Feature, das die meisten Benutzer nicht direkt nutzen werden. Dieses Feature richtet sich in erster Linie an Bibliotheks- und Framework-Autoren, um eine Ereignisschleife und eine asynchrone Programmier-API bereitzustellen. Fibers erm\u00f6glichen die nahtlose Integration von asynchroner Codeausf\u00fchrung in synchronen Code an jedem beliebigen Punkt, ohne dass der Aufrufstapel der Anwendung ge\u00e4ndert oder Boilerplate-Code hinzugef\u00fcgt werden muss.<\/em><em>\u00a0<\/em><\/p>\n<p><em>Es wird nicht erwartet, dass die Fiber API direkt im Code auf Anwendungsebene verwendet wird. Fibers bieten eine grundlegende, Low-Level-API zur Flusskontrolle, um Abstraktionen auf h\u00f6herer Ebene zu erstellen, die dann im Anwendungscode verwendet werden.<\/em><\/p><\/blockquote>\n<p>In Anbetracht der Performance-Vorteile kann man davon ausgehen, dass PHP-Bibliotheken und -Frameworks die Vorteile dieses neuen Features nutzen werden. Es wird interessant sein zu sehen, wie sie Fibers in ihrem \u00d6kosystem implementieren.<\/p>\n<h3>Neue <code>readonly<\/code> Eigenschaften<\/h3>\n<p>PHP 8.1 f\u00fcgt den Support f\u00fcr <code>readonly<\/code> Properties hinzu. Sie k\u00f6nnen nur einmal aus dem Scope, in dem sie deklariert wurden, initialisiert werden. Einmal initialisiert, kannst du ihren Wert nicht mehr \u00e4ndern. Wenn du das tust, wird eine <strong>Error<\/strong>-Exception ausgel\u00f6st.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/readonly_properties_v2\">Der RFC<\/a> lautet:<\/p>\n<blockquote><p><em>Eine <strong>Readonly<\/strong>-Eigenschaft kann nur einmal initialisiert werden und nur von dem Bereich, in dem sie deklariert wurde. Jede andere Zuweisung oder \u00c4nderung der Eigenschaft f\u00fchrt zu einer Fehler-Ausnahme.<\/em><\/p><\/blockquote>\n<p>Hier ist ein Beispiel, wie du es verwenden kannst:<\/p>\n<pre><code class=\"language-php\"><span id=\"urn:enhancement-e6b92f69-33ed-4b40-85f5-70b7d212e164\" class=\"textannotation\">class<\/span> Test {\n\u00a0 \u00a0 public readonly string $<span id=\"urn:enhancement-4bfd6a56-656d-4f39-a0d7-fda9ecd81af6\" class=\"textannotation\">kinsta<\/span>;\n \n\u00a0 \u00a0 public <span id=\"urn:enhancement-d56b6fad-7b07-410a-9dc2-4ddf3626587e\" class=\"textannotation\">function<\/span> __construct(string $<span id=\"urn:enhancement-377522be-8101-40b8-94a9-4458c21f5350\" class=\"textannotation\">kinsta<\/span>) {\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ Legal initialization.\n\u00a0 \u00a0 \u00a0 \u00a0 $this-&gt;<span id=\"urn:enhancement-f8846cbb-9bf4-4f28-91c0-8209a6f7b211\" class=\"textannotation\">kinsta<\/span> = $<span id=\"urn:enhancement-4ca0a08d-e4dd-4b0f-b854-e9102c98ce1d\" class=\"textannotation\">kinsta<\/span>;\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n<p>Einmal initialisiert, gibt es kein Zur\u00fcck mehr. Dieses Feature in PHP eingebaut zu haben, reduziert den Boilerplate-Code, der oft verwendet wird, um diese Funktionalit\u00e4t zu aktivieren, erheblich.<\/p>\n<p>Die <code>readonly<\/code> Eigenschaft bietet eine starke Unver\u00e4nderlichkeitsgarantie, sowohl innerhalb als auch au\u00dferhalb der Klasse. Es spielt keine Rolle, welcher Code dazwischen l\u00e4uft. Der Aufruf einer <code>readonly<\/code> Eigenschaft wird immer den gleichen Wert zur\u00fcckgeben.<\/p>\n<p>Allerdings kann die Verwendung der <code>readonly<\/code>-Eigenschaft in bestimmten Anwendungsf\u00e4llen nicht ideal sein. Zum Beispiel kannst du sie nur neben einer <a href=\"https:\/\/kinsta.com\/de\/blog\/php-7-4\/#typed-properties\">typisierten Eigenschaft<\/a> verwenden, da Deklarationen ohne Typ implizit <code>null<\/code> sind und nicht <code>readonly<\/code> sein k\u00f6nnen.<\/p>\n<p>Au\u00dferdem macht das Setzen einer <code>readonly<\/code>-Eigenschaft die Objekte nicht unver\u00e4nderlich. Die <code>readonly<\/code>-Eigenschaft wird das gleiche Objekt halten, aber das Objekt selbst kann sich \u00e4ndern.<\/p>\n<p>Ein weiteres kleines Problem mit dieser Eigenschaft ist, dass man sie nicht klonen kann. Es gibt bereits einen <a href=\"https:\/\/stitcher.io\/blog\/cloning-readonly-properties-in-php-81\">Workaround f\u00fcr diesen speziellen Anwendungsfall<\/a>. Schau es dir bei Bedarf an.<\/p>\n<h3>Definiere <code>final<\/code> Klassen-Konstanten<\/h3>\n<p>Seit PHP 8.0 kannst du Klassenkonstanten mit ihren Unterklassen \u00fcberschreiben. Das liegt an der Art und Weise, wie Vererbung in PHP implementiert ist.<\/p>\n<p>Hier ist ein Beispiel, wie du den Wert einer zuvor deklarierten Konstante \u00fcberschreiben kannst:<\/p>\n<pre><code class=\"language-php\"><span id=\"urn:enhancement-72f34951-c6b0-405b-bc21-8e6abd9ccff6\" class=\"textannotation\">class<\/span> Moo\n{\n\u00a0 \u00a0 public <span id=\"urn:enhancement-191d4bae-432e-4c5e-b9fb-98971dbb9f96\" class=\"textannotation\">const<\/span> M = \"moo\";\n}\n \n<span id=\"urn:enhancement-7b3a2878-d57a-4c9e-a9c4-5f02a245e108\" class=\"textannotation\">class<\/span> Meow extends Moo\n{\n\u00a0 \u00a0 public <span id=\"urn:enhancement-631f5b23-50b4-4afc-97e3-752ab132647c\" class=\"textannotation\">const<\/span> M = \"meow\";\n}\u00a0\u00a0<\/code><\/pre>\n<p>Wenn die Bedingungen strenger werden sollen (zumindest bei Konstanten), dann k\u00f6nnen sie das mit dem neuen <code>final<\/code>-Modifikator von PHP 8.1 tun.<\/p>\n<p>Sobald du eine Konstante als <code>final<\/code> deklariert hast, bedeutet es das.<\/p>\n<pre><code class=\"language-php\"><span id=\"urn:enhancement-67d37baf-d55d-4a63-a687-9fd3c2162950\" class=\"textannotation\">class<\/span> Moo\n{\n\u00a0 \u00a0 final public <span id=\"urn:enhancement-e9a1dbac-35ec-4311-af77-20cb51caee8b\" class=\"textannotation\">const<\/span> M = \"moo\";\n}\n \n<span id=\"urn:enhancement-3fc58a89-edd5-430c-a3ad-5ce132c38402\" class=\"textannotation\">class<\/span> Meow extends Moo\n{\n\u00a0 \u00a0 public <span id=\"urn:enhancement-15cbe9d6-8f6c-4ed3-af5e-9c72c16bc376\" class=\"textannotation\">const<\/span> M = \"meow\";\n}\n \n\/\/ Fatal error: Meow::M cannot override final <span id=\"urn:enhancement-5e4659d4-6f4f-4b8b-a2d2-f36d32a4b1e6\" class=\"textannotation\">constant<\/span> Moo::M<\/code><\/pre>\n<p>Du kannst mehr dar\u00fcber in den <a href=\"https:\/\/wiki.php.net\/rfc\/final_class_const\">finalen Klassenkonstanten<\/a> PHP RFC lesen.<\/p>\n<h3>Neue <code>fsync()<\/code> und <code>fdatasync()<\/code> Funktionen<\/h3>\n<p>PHP 8.1 f\u00fcgt zwei neue Dateisystemfunktionen namens <code>fsync()<\/code> und <code>fdatasync()<\/code> hinzu. Sie werden denjenigen bekannt vorkommen, die mit den gleichnamigen <a href=\"https:\/\/linux.die.net\/man\/2\/fsync\">Linux-Funktionen vertraut sind<\/a>. Das liegt daran, dass sie miteinander verwandt sind, nur eben f\u00fcr PHP implementiert.<\/p>\n<p>Tats\u00e4chlich war diese Erg\u00e4nzung schon lange \u00fcberf\u00e4llig. PHP ist eine der wenigen gro\u00dfen Programmiersprachen, die <a href=\"https:\/\/wiki.php.net\/rfc\/fsync_function\">fsync() und fdatasync()<\/a> noch nicht implementiert haben &#8211; zumindest <a href=\"https:\/\/wiki.php.net\/rfc\/fsync_function\">bis PHP 8.1<\/a>.<\/p>\n<p>Die <code>fsync()<\/code>-Funktion \u00e4hnelt der bereits existierenden <code>fflush()<\/code>-Funktion von PHP, aber sie unterscheidet sich in einem Punkt deutlich. W\u00e4hrend <code>fflush()<\/code> die internen Puffer der Anwendung an das Betriebssystem leert, geht <code>fsync()<\/code> einen Schritt weiter und stellt sicher, dass die internen Puffer an den physischen <a href=\"https:\/\/kinsta.com\/de\/blog\/was-ist-ssd\/\">Speicher<\/a> geleert werden. Das stellt sicher, dass die Daten vollst\u00e4ndig und persistent geschrieben werden, so dass du sie auch nach einem Applikations- oder Systemabsturz wieder abrufen kannst.<\/p>\n<p>Hier ist ein Beispiel, wie du es verwenden kannst.<\/p>\n<pre><code class=\"language-php\">$doc = 'kinsta.txt';\n\n$kin = fopen($doc, 'ki');\nfwrite($kin, 'doc info');\nfwrite($kin, \"\\r<span id=\"urn:enhancement-6c91217c-b2cf-48b9-b8f8-48ec8429418f\" class=\"textannotation\">\\n<\/span>\");\nfwrite($kin, 'more info');\n\nfsync($kin);\nfclose($kin);<\/code><\/pre>\n<p>Das Hinzuf\u00fcgen des <code>fsync()<\/code>-Aufrufs am Ende stellt sicher, dass alle Daten, die im PHP- oder OS-internen Puffer gehalten werden, in den Speicher geschrieben werden. Alle anderen Codeausf\u00fchrungen werden bis dahin blockiert.<\/p>\n<p>Die verwandte Funktion ist <code>fdatasync()<\/code>. Benutze es, um Daten zu synchronisieren, aber nicht unbedingt Metadaten. F\u00fcr Daten, deren Metadaten nicht essentiell sind, macht dieser Funktionsaufruf den Schreibprozess einen Tick schneller.<\/p>\n<p>Du solltest jedoch beachten, dass PHP 8.1 <code>fdatasync()<\/code> unter Windows noch nicht vollst\u00e4ndig unterst\u00fctzt. Es fungiert lediglich als Alias von <code>fsync()<\/code>. Unter POSIX ist <code>fdatasync()<\/code> korrekt implementiert.<\/p>\n<h3>Neue <code>array_is_list()<\/code> Funktion<\/h3>\n<p>PHP Arrays k\u00f6nnen sowohl Integer- als auch String-Schl\u00fcssel enthalten. Das bedeutet, dass du sie f\u00fcr verschiedene Dinge verwenden kannst, einschlie\u00dflich Listen, Hash-Tabellen, W\u00f6rterb\u00fccher, Sammlungen, Stacks, Warteschlangen und vieles mehr. Du kannst sogar Arrays innerhalb von Arrays haben und so multidimensionale Arrays erstellen.<\/p>\n<p>Du kannst effizient \u00fcberpr\u00fcfen, ob ein bestimmter Eintrag ein Array ist, aber es ist nicht so einfach zu \u00fcberpr\u00fcfen, ob es irgendwelche fehlenden Array-Offsets, ungeordnete Keys, etc. hat. Kurz gesagt, du kannst nicht schnell \u00fcberpr\u00fcfen, ob ein Array eine Liste ist.<\/p>\n<p>Die <a href=\"https:\/\/wiki.php.net\/rfc\/is_list\">Funktion array_is_list()<\/a> pr\u00fcft, ob die Schl\u00fcssel eines Arrays in sequentieller Reihenfolge, beginnend bei <code>0<\/code>, und ohne L\u00fccken sind. Wenn alle Bedingungen erf\u00fcllt sind, gibt sie <code>true<\/code> zur\u00fcck. Standardm\u00e4\u00dfig gibt sie auch <code>true<\/code> f\u00fcr leere Arrays zur\u00fcck.<\/p>\n<p>Hier sind ein paar Beispiele f\u00fcr die Verwendung der Funktion, wenn sowohl die <code>true<\/code> als auch die <code>false<\/code> Bedingungen erf\u00fcllt sind:<\/p>\n<pre><code class=\"language-php\">\/\/ true array_is_<span id=\"urn:enhancement-60019546-30d7-49bf-bfd6-2395c359df9d\" class=\"textannotation\">list<\/span>() examples\narray_is_<span id=\"urn:enhancement-7f745f9b-68d8-46e2-b05e-ababf89baea6\" class=\"textannotation\">list<\/span>([]); \/\/ true\narray_is_<span id=\"urn:enhancement-1079d005-8e45-45e9-88be-cb144261f8a7\" class=\"textannotation\">list<\/span>([1, 2, 3]); \/\/ true\narray_is_<span id=\"urn:enhancement-1e6901d1-3735-4bcf-a559-f0006fc49cc0\" class=\"textannotation\">list<\/span>(['cats', 2, 3]); \/\/ true\narray_is_<span id=\"urn:enhancement-328ad9ba-2a3f-4688-b90a-e99b988626e6\" class=\"textannotation\">list<\/span>(['cats', 'dogs']); \/\/ true\narray_is_<span id=\"urn:enhancement-53662483-3fdd-49ad-bc91-43cc9b2f240c\" class=\"textannotation\">list<\/span>([0 =&gt; 'cats', 'dogs']); \/\/ true\narray_is_<span id=\"urn:enhancement-3962aa5b-7745-4e5d-b3b7-8a491fec4325\" class=\"textannotation\">list<\/span>([0 =&gt; 'cats', 1 =&gt; 'dogs']); \/\/ true \n\n\/\/ false array_is_<span id=\"urn:enhancement-dc405ddb-b727-48e3-8447-340986904b41\" class=\"textannotation\">list<\/span>() examples \narray_is_<span id=\"urn:enhancement-85a643ea-f33a-482b-ab24-9ba95216e77a\" class=\"textannotation\">list<\/span>([1 =&gt; 'cats', 'dogs']); \/\/ as first key isn't 0\narray_is_<span id=\"urn:enhancement-b8b98236-19e8-4156-b762-b932719c3304\" class=\"textannotation\">list<\/span>([1 =&gt; 'cats', 0 =&gt; 'dogs']); \/\/ <span id=\"urn:enhancement-57e252cd-090d-4f9f-bef8-31ea8b7ff7a1\" class=\"textannotation\">keys<\/span> are out of order\narray_is_<span id=\"urn:enhancement-6986d69c-9837-42d1-83a8-6920731b49e9\" class=\"textannotation\">list<\/span>([0 =&gt; 'cats', 'bark' =&gt; 'dogs']); \/\/ non-integer <span id=\"urn:enhancement-e327ddeb-5e0e-4b46-9c91-b70656b1be50\" class=\"textannotation\">keys<\/span>\narray_is_<span id=\"urn:enhancement-70b466b1-32c0-4323-9d0e-5b09f1be84ce\" class=\"textannotation\">list<\/span>([0 =&gt; 'cats', 2 =&gt; 'dogs']); \/\/ gap in between <span id=\"urn:enhancement-5266ffb3-4d6d-4214-b294-f70b2b1aa638\" class=\"textannotation\">keys<\/span> <\/code><\/pre>\n<p>Eine PHP-Array-Liste mit ungeordneten Schl\u00fcsseln ist eine <a href=\"https:\/\/kinsta.com\/de\/blog\/wordpress-sicherheit\/#2-use-latest-php-version\">potentielle Quelle f\u00fcr Fehler<\/a>. Die Verwendung dieser Funktion, um eine strikte Einhaltung der <strong>Listenanforderungen<\/strong> zu erzwingen, bevor man mit der Codeausf\u00fchrung fortf\u00e4hrt, ist eine gro\u00dfartige Erg\u00e4nzung zu PHP.<\/p>\n<h3>Neue Sodium XChaCha20 Funktionen<\/h3>\n<p>Sodium ist eine moderne, einfach zu benutzende kryptographische Bibliothek f\u00fcr Verschl\u00fcsselung, Entschl\u00fcsselung, <a href=\"https:\/\/kinsta.com\/de\/blog\/passwort-manager\/\">Passwort<\/a>-Hashing, Signaturen und mehr. Das <a href=\"https:\/\/pecl.php.net\/package\/libsodium\">PECL libsodium Paket<\/a> f\u00fcgt einen Wrapper f\u00fcr Sodium hinzu, damit PHP-Entwickler es nutzen k\u00f6nnen.<\/p>\n<p>Auch <a href=\"https:\/\/doc.libsodium.org\/libsodium_users\">f\u00fchrende Tech-Unternehmen<\/a> wie Facebook, Discord, Malwarebytes und Valve nutzen libsodium, um ihre Nutzer mit schnellen und sicheren Verbindungen zu sch\u00fctzen.<\/p>\n<p>libsodium unterst\u00fctzt den <a href=\"https:\/\/www.cryptopp.com\/wiki\/XChaCha20\">XChaCha20 Verschl\u00fcsselungsalgorithmus<\/a>, um Daten zu ver- und entschl\u00fcsseln, insbesondere f\u00fcr die Stream-Verschl\u00fcsselung. Ebenso unterst\u00fctzt die PECL libsodium Erweiterung bereits XChaCha20, allerdings nur mit Poly1305 message-authentication code.<\/p>\n<p>Viele PHP-Anwendungen nutzen XChaCha20 direkt f\u00fcr die Stream-Verschl\u00fcsselung. Um die Dinge einfacher zu machen, gibt es ab PHP 8.1 drei neue Funktionen, um Daten mit XChaCha20 zu ver- oder entschl\u00fcsseln, ohne dass eine Authentifizierung involviert ist. Dieser Modus wird &#8222;detached mode&#8220; genannt.<\/p>\n<p>Die neu eingef\u00fchrten XChaCha20-Funktionen sind:<\/p>\n<ul>\n<li><code>sodium_crypto_stream_xchacha20_keygen<\/code>: Gibt einen sicheren Zufallsschl\u00fcssel f\u00fcr die Verwendung mit sodium_crypto_stream_xchacha20 zur\u00fcck.<\/li>\n<li><code>sodium_crypto_stream_xchacha20<\/code>: Expandiert den Schl\u00fcssel und die Nonce in einen Keystream aus pseudozuf\u00e4lligen Bytes.<\/li>\n<li><code>sodium_crypto_stream_xchacha20_xor<\/code>: Verschl\u00fcsselt eine Nachricht mit einer Nonce und einem geheimen Schl\u00fcssel (keine Authentifizierung).<\/li>\n<\/ul>\n<p>Zus\u00e4tzlich gibt es zwei neue PHP-Konstanten, die im globalen Namespace definiert sind:<\/p>\n<ul>\n<li><code>SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES<\/code> (zugewiesen <strong>32<\/strong>)<\/li>\n<li><code>SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES<\/code> (zugewiesen <strong>24<\/strong>)<\/li>\n<\/ul>\n<p>Benutze es aber mit Vorsicht. Da es ohne Authentifizierung funktioniert, ist die Entschl\u00fcsselung anf\u00e4llig f\u00fcr g\u00e4ngige Ciphertext-Angriffe.<\/p>\n<p>Du kannst mehr \u00fcber die Verwendung und die Anforderungen auf der <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6868\">GitHub Seite<\/a> lesen.<\/p>\n<h3>Neue IntlDatePatternGenerator Klasse<\/h3>\n<p>Die zugrundeliegende ICU-Bibliothek von PHP unterst\u00fctzt die Erstellung von lokalisierten <a href=\"https:\/\/kinsta.com\/de\/blog\/wordpress-kalender-plugin\/\">Datums- und Zeitformaten<\/a>, ist aber nicht vollst\u00e4ndig anpassbar.<\/p>\n<p>Wenn du z.B. bis PHP 8.0 lokal-spezifische Daten- und Zeitformate erstellen m\u00f6chtest, kannst du die <a href=\"https:\/\/www.php.net\/manual\/en\/class.intldateformatter.php\">vordefinierte Konstante IntlDateFormatter<\/a> verwenden, um dies auf 6 Arten zu tun:<\/p>\n<ul>\n<li><strong><code>IntlDateFormatter::LONG<\/code>:<\/strong> Lang, wie <strong>10. November 2017<\/strong> oder <strong>11:22:33 Uhr<\/strong><\/li>\n<li><strong><code>IntlDateFormatter::MEDIUM<\/code>:<\/strong> Etwas k\u00fcrzer, wie z.B. <strong>Nov 10, 2017<\/strong><\/li>\n<li><strong><code>IntlDateFormatter::SHORT<\/code>:<\/strong> Nur numerisch, wie <strong>10\/11\/17<\/strong> oder <strong>11:22pm<\/strong><\/li>\n<\/ul>\n<p>Jede dieser Varianten hat auch ihre eigene <code>RELATIVE_<\/code>-Variante, die die Datumsformatierung in einem begrenzten Bereich vor oder nach dem aktuellen Datum setzt. In PHP sind das die Werte <strong>gestern, heute<\/strong> und <strong>morgen<\/strong>.<\/p>\n<p>Angenommen, du m\u00f6chtest die lange Variante f\u00fcr das Jahr und die kurze Variante f\u00fcr den Monat verwenden, wie z.B. <strong>10\/11\/2017<\/strong>. Ab PHP 8.0 kannst du das nicht.<\/p>\n<p>In PHP 8.1+ kannst du mit der neuen Klasse <strong>IntlDatePatternGenerator<\/strong> festlegen, welche Formate f\u00fcr das Datum, den Monat und die Uhrzeit verwendet werden sollen. Die genaue Reihenfolge dieser Komponenten kannst du dem Formatierer \u00fcberlassen.<\/p>\n<p>Du solltest beachten, dass diese Klasse zwar nur das Wort <strong>Date<\/strong> in sich tr\u00e4gt, aber mit dem <strong>DateTimePatternGenerator<\/strong> von ICU \u00fcbereinstimmt. Das bedeutet, dass du sie auch benutzen kannst, um flexible Zeitformate zu erstellen. Um die Namensgebung zu vereinfachen, hat sich das PHP-Team f\u00fcr den k\u00fcrzeren Begriff <strong>IntlDatePatternGenerator <\/strong>entschieden.<\/p>\n<p>Hier ist ein Beispiel direkt aus <a href=\"https:\/\/wiki.php.net\/rfc\/intldatetimepatterngenerator\">dem RFC<\/a>:<\/p>\n<pre><code class=\"language-php\">$skeleton = \"YYYYMMdd\";\n \n$today = \\DateTimeImmutable::createFromFormat('Y-m-d', '2021-04-24');\n \n$dtpg = <span id=\"urn:enhancement-65367893-ae08-48ca-a4f4-97f64ac1a8ef\" class=\"textannotation\">new<\/span> \\IntlDatePatternGenerator(\"de_DE\");\n$pattern = $dtpg-&gt;getBestPattern($skeleton);\necho \"de: \", \\IntlDateFormatter::formatObject($today, $pattern, \"de_DE\"), \"<span id=\"urn:enhancement-e9b606d0-9fcf-4b36-8bc5-3250d8592c37\" class=\"textannotation\">\\n<\/span>\";\n \n$dtpg = <span id=\"urn:enhancement-ab3d89bc-4fc8-4d24-84fc-621f993a69f0\" class=\"textannotation\">new<\/span> \\IntlDatePatternGenerator(\"en_US\");\n$pattern = $dtpg-&gt;getBestPattern($skeleton), \"<span id=\"urn:enhancement-5c47a4e5-3ad0-419a-bebf-cbd70f31eb2e\" class=\"textannotation\">\\n<\/span>\";\necho \"en: \", \\IntlDateFormatter::formatObject($today, $pattern, \"en_US\"), \"<span id=\"urn:enhancement-9a9f85c3-f8ca-4ce9-9fbb-acf75b49c7cc\" class=\"textannotation\">\\n<\/span>\";\n \n\/*\nde: 24.04.2021\nen: 04\/24\/2021\n*\/<\/code><\/pre>\n<p>Im obigen Code definiert die <strong>Skelettvariable<\/strong> die jeweiligen Datums- oder Zeitformate, die verwendet werden sollen. Der Formatierer k\u00fcmmert sich jedoch um die Reihenfolge des Endergebnisses.<\/p>\n<h3>Support f\u00fcr AVIF Image Format<\/h3>\n<p>AVIF, oder AV1 Image File Format, ist ein relativ neues lizenzfreies <a href=\"https:\/\/kinsta.com\/de\/blog\/bilddateitypen\/\">Bildformat<\/a>, das auf dem AV1 Videocodierungsformat basiert. Es bietet nicht nur eine h\u00f6here Komprimierung (und damit kleinere Dateigr\u00f6\u00dfen), sondern unterst\u00fctzt auch verschiedene Features wie Transparenz, HDR und mehr.<\/p>\n<p>Das AVIF-Format wurde erst k\u00fcrzlich (8. Juni 2021) <a href=\"https:\/\/aomediacodec.github.io\/av1-avif\/\">standardisiert<\/a>. Das hat den Weg f\u00fcr Browser, wie Chrome 85+ und Firefox 86+, geebnet, die Unterst\u00fctzung f\u00fcr AVIF-Bilder hinzuf\u00fcgen.<\/p>\n<p>PHP 8.1&#8217;s Bildverarbeitung und GD-Erweiterung f\u00fcgt Unterst\u00fctzung f\u00fcr AVIF-Bilder hinzu.<\/p>\n<p>Um diese Funktionalit\u00e4t einzubinden, musst du jedoch die GD-Erweiterung mit AVIF-Unterst\u00fctzung kompilieren. Du kannst dies tun, indem du die folgenden Befehle ausf\u00fchrst.<\/p>\n<p>F\u00fcr Debian\/Ubuntu:<\/p>\n<pre><code class=\"language-bash\">apt install libavif-dev<\/code><\/pre>\n<p>F\u00fcr Fedora\/RHEL:<\/p>\n<pre><code class=\"language-bash\">dnf install libavif-devel<\/code><\/pre>\n<p>Das wird alle aktuellen Abh\u00e4ngigkeiten installieren. Als n\u00e4chstes kannst du die AVIF Unterst\u00fctzung kompilieren, indem du das <code>--with-avif<\/code> Flag mit dem <code>.\/configure<\/code> Skript ausf\u00fchrst.<\/p>\n<pre><code class=\"language-bash\">.\/buildconf --force\n.\/configure --enable-gd --with-avif<\/code><\/pre>\n<p>Wenn du eine neue Umgebung von Grund auf neu aufbaust, kannst du hier auch andere PHP-Erweiterungen aktivieren.<\/p>\n<p>Nach der Installation kannst du testen, ob die AVIF-Unterst\u00fctzung aktiviert ist, indem du den folgenden Befehl in deinem PHP-Terminal ausf\u00fchrst:<\/p>\n<pre><code class=\"language-bash\">php -i | grep AVIF<\/code><\/pre>\n<p>Wenn du AVIF korrekt installiert hast, wirst du folgendes Ergebnis sehen:<\/p>\n<pre><code class=\"language-bash\">AVIF Support =&gt; enabled<\/code><\/pre>\n<p>Du kannst auch den <code>gd_info()<\/code>-Aufruf verwenden, um eine Liste der GD-Funktionen abzurufen, einschlie\u00dflich der Frage, ob die <strong>AVIF-Support-<\/strong>Funktionalit\u00e4t aktiviert ist.<\/p>\n<p>Diese aktualisierte PHP 8.1 GD Erweiterung f\u00fcgt auch zwei neue Funktionen f\u00fcr die Arbeit mit AVIF Bildern hinzu: <code>imagecreatefromavif<\/code> und <code>imageavif<\/code>. Sie funktionieren \u00e4hnlich wie ihre JPEG und PNG Gegenst\u00fccke.<\/p>\n<p>Die <code>imagecreatefromavif<\/code>-Funktion gibt eine GdImage-Instanz von einem gegebenen AVIF-Bild zur\u00fcck. Du kannst diese Instanz dann verwenden, um das Bild zu bearbeiten oder zu konvertieren.<\/p>\n<p>Die andere <code>imageavif<\/code> Funktion gibt die AVIF Bilddatei aus. Du kannst sie zum Beispiel benutzen, um ein JPEG nach AVIF zu konvertieren:<\/p>\n<pre><code class=\"language-php\">$<span id=\"urn:enhancement-8e851b69-3481-4260-bfea-827215ce3ad5\" class=\"textannotation\">image<\/span> = imagecreatefromjpeg('image.jpeg');\nimageavif($<span id=\"urn:enhancement-6966e113-0ad8-4e02-bba2-0df49099b4ef\" class=\"textannotation\">image<\/span>, 'image.avif');<\/code><\/pre>\n<p>Du kannst mehr \u00fcber diese neue Funktion auf der <a href=\"https:\/\/github.com\/php\/php-src\/pull\/7026\">GitHub Seite<\/a> lesen.<\/p>\n<h3><strong>Neue <code>$_FILES: full_path<\/code> Schl\u00fcssel f\u00fcr Verzeichnis Uploads<\/strong><\/h3>\n<p>PHP verwaltet eine gro\u00dfe Anzahl von vordefinierten Variablen, um verschiedene Dinge zu verfolgen. Eine davon ist die <a href=\"https:\/\/www.php.net\/manual\/en\/reserved.variables.files.php\">Variable $_FILES<\/a>, die ein assoziatives Array von Elementen enth\u00e4lt, die \u00fcber die HTTP POST Methode hochgeladen werden.<\/p>\n<p>Die meisten modernen Browser unterst\u00fctzen <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/file#htmlattrdefwebkitdirectory_non-standard_inline\">das Hochladen eines ganzen Verzeichnisses<\/a> mit <a href=\"https:\/\/kinsta.com\/de\/blog\/wie-man-ein-html-datei-in-wordpress-hochladt\/\">HTML-Datei-Upload-<\/a>Feldern. Sogar PHP &lt;8.1 unterst\u00fctzte diese Funktionalit\u00e4t, aber mit einem gro\u00dfen Vorbehalt. Du konntest einen Ordner nicht mit seiner genauen Verzeichnisstruktur oder relativen Pfaden hochladen, da PHP diese Informationen nicht an das <code>$_FILES<\/code> Array weitergab.<\/p>\n<p>Das \u00e4ndert sich in PHP 8.1 mit der Hinzuf\u00fcgung eines neuen Schl\u00fcssels namens <code>full_path<\/code> zum <code>$_FILES<\/code> Array. Mit diesen neuen Daten kannst du relative Pfade speichern oder die genaue Verzeichnisstruktur auf dem Server duplizieren.<\/p>\n<p>Du kannst diese Informationen testen, indem du das <code>$FILES<\/code> Array mit dem <code>var_dump($_FILES);<\/code> Befehl ausgibst.<\/p>\n<p>Gehe jedoch mit Vorsicht vor, wenn du diese Funktion verwendest. Stelle sicher, dass du dich gegen <a href=\"https:\/\/php.watch\/versions\/8.1\/%24_FILES-full-path#security-hardening\">Standard-Attacken beim Hochladen von Dateien<\/a> absicherst.<\/p>\n<h3>Array Unpacking Support f\u00fcr String-Keyed Arrays<\/h3>\n<p>PHP 7.4 hat <a href=\"https:\/\/kinsta.com\/de\/blog\/php-7-4\/#array-spread-operator\">Unterst\u00fctzung f\u00fcr das Entpacken von Arrays<\/a> mit dem Array-Spread-Operator (&#8230;) hinzugef\u00fcgt. Dies ist eine schnellere Alternative zur Verwendung der <code>array_merge()<\/code> Funktion. Allerdings war diese Funktion auf Arrays mit numerischen Schl\u00fcsseln beschr\u00e4nkt, da das Entpacken von Arrays mit String-Schl\u00fcsseln Konflikte beim Zusammenf\u00fchren von Arrays mit doppelten Schl\u00fcsseln verursachte.<\/p>\n<p>PHP 8 f\u00fcgte jedoch <a href=\"https:\/\/kinsta.com\/de\/blog\/php-8\/#named-arguments\">Unterst\u00fctzung f\u00fcr benannte Argumente<\/a> hinzu, wodurch diese Einschr\u00e4nkung aufgehoben wurde. Daher wird das Entpacken von Arrays nun auch Arrays mit String-Schl\u00fcsseln unterst\u00fctzen, indem die gleiche Syntax verwendet wird:<\/p>\n<pre><code class=\"language-php\">$array = [...$array1, ...$array2];<\/code><\/pre>\n<p>This <a href=\"https:\/\/wiki.php.net\/rfc\/array_unpacking_string_keys\" target=\"_blank\" rel=\"noopener noreferrer\">RFC example<\/a> illustrates how merging arrays with duplicate string keys is handled in PHP 8.1:<\/p>\n<pre><code class=\"language-php\">$array1 = [\"a\" =&gt; 1];\n$array2 = [\"a\" =&gt; 2];\n$array = [\"a\" =&gt; 0, ...$array1, ...$array2];\nvar_dump($array); \/\/ [\"a\" =&gt; 2]<\/code><\/pre>\n<p>Hier taucht der String-Schl\u00fcssel &#8222;a&#8220; dreimal auf, bevor er per Array-Entpacken zusammengef\u00fchrt wird. Aber nur sein letzter Wert, der zu <code>$array2<\/code> geh\u00f6rt, gewinnt.<\/p>\n<h3>Explizite oktale Zahlendarstellung<\/h3>\n<p>PHP unterst\u00fctzt verschiedene Zahlensysteme, einschlie\u00dflich dezimal (Basis-10), bin\u00e4r (Basis-2), oktal (Basis-8) und hex (Basis-16). Das dezimale Zahlensystem ist die Standardeinstellung.<\/p>\n<p>Wenn du ein anderes Zahlensystem verwenden m\u00f6chtest, musst du jeder Zahl ein Standardpr\u00e4fix voranstellen:<\/p>\n<ul>\n<li><strong>Hex:<\/strong> <code>0x<\/code> prefix. (e.g. 17 = <code>0x11<\/code>)<\/li>\n<li><strong>Binary:<\/strong> <code>0b<\/code> prefix. (e.g. 3 = <code>0b11<\/code>)<\/li>\n<li><strong>Octal:<\/strong>\u00a0<code>0<\/code> prefix. (e.g. 9 = <code>011<\/code>)<\/li>\n<\/ul>\n<p>Du kannst sehen, wie sich das Pr\u00e4fix des oktalen Zahlensystems vom Rest unterscheidet. Um dieses Problem zu standardisieren, unterst\u00fctzen viele Programmiersprachen eine explizite oktale Zahlendarstellung: <code>0o<\/code> oder <code>0O<\/code>.<\/p>\n<p>Beginnend mit PHP 8.1 kannst du das oben gezeigte Beispiel (d.h. die Zahl 9 in Basis-10) im oktalen Zahlensystem als <code>0o11<\/code> oder <code>0O11<\/code> schreiben.<\/p>\n<pre><code class=\"language-php\">0o16 === 14; \/\/ true\n0o123 === 83; \/\/ true\n \n0O16 === 14; \/\/ true\n0O123 === 83; \/\/ true\n \n016 === 0o16; \/\/ true\n016 === 0O16; \/\/ true<\/code><\/pre>\n<p>Au\u00dferdem funktioniert dieses neue Feature auch mit dem in PHP 7.4 eingef\u00fchrten <a href=\"https:\/\/wiki.php.net\/rfc\/numeric_literal_separator\">numerischen Literalseparator mit Unterstrich<\/a>.<\/p>\n<p>Lies mehr \u00fcber dieses neue PHP 8.1 Feature in <a href=\"https:\/\/wiki.php.net\/rfc\/explicit_octal_notation\">seinem RFC<\/a>.<\/p>\n<h3>MurmurHash3 und xxHash Hash Algorithmen Support<\/h3>\n<p>PHP 8.1 bietet Unterst\u00fctzung f\u00fcr die Hash-Algorithmen MurmurHash3 und xxHash. Sie sind nicht f\u00fcr den kryptographischen Einsatz konzipiert, bieten aber dennoch eine beeindruckende Zuf\u00e4lligkeit, Streuung und Einzigartigkeit der Ausgabe.<\/p>\n<p>Diese <a href=\"https:\/\/php.watch\/articles\/php-hash-benchmark\">neuen Hash-Algorithmen<\/a> sind schneller als die meisten der existierenden Hash-Algorithmen von PHP. Tats\u00e4chlich sind einige der Varianten dieser Hash-Algorithmen schneller als der RAM-Durchsatz.<\/p>\n<p>Da PHP 8.1 auch die Unterst\u00fctzung f\u00fcr die Deklaration von Algorithmus-spezifischen <code>$options<\/code>-Parametern hinzuf\u00fcgt, kannst du dies auch mit diesen neuen Algorithmen tun. Der Standardwert f\u00fcr dieses neue Argument ist <code>[]<\/code>. Es wird also keine unserer bestehenden Hash-Funktionen beeinflussen.<\/p>\n<p>Du kannst mehr \u00fcber diese neuen PHP 8.1 Features auf deren GitHub Seiten lesen: <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6059\">MurmurHash3<\/a>, <a href=\"https:\/\/php.watch\/versions\/8.1\/xxHash\">xxHash<\/a>, <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6400\">Algorithmus-spezifische $options<\/a>.<\/p>\n<h3>DNS-over-HTTPS (DoH) Support<\/h3>\n<p>DNS-over-HTTPS (DoH) ist ein Protokoll zur <a href=\"https:\/\/kinsta.com\/de\/blog\/was-ist-dns\/\">DNS-Aufl\u00f6sung<\/a> \u00fcber das HTTPS-Protokoll. Durch die Verwendung von HTTPS zur Verschl\u00fcsselung der Daten zwischen Client und DNS-Resolver erh\u00f6ht DoH die Privatsph\u00e4re und Sicherheit der Benutzer, indem es MitM-Angriffe verhindert.<\/p>\n<p>Beginnend mit PHP 8.1 kannst du die <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6612\">Curl-Erweiterung<\/a> verwenden, um einen DoH-Server anzugeben. Sie erfordert, dass PHP mit <strong>libcurl<\/strong> 7.62+ Versionen kompiliert wird. Das ist f\u00fcr die meisten g\u00e4ngigen Betriebssysteme, einschlie\u00dflich Linux-Distros, kein Problem, da sie oft Curl 7.68+ enthalten.<\/p>\n<p>Du kannst die DoH Server URL konfigurieren, indem du die Option <code>CURLOPT_DOH_URL<\/code> angibst.<\/p>\n<pre><code class=\"language-php\">$doh = curl_init('https:\/\/kinsta.com');\ncurl_setopt($doh, CURLOPT_DOH_URL, 'https:\/\/dns.google\/dns-query');\ncurl_exec($doh);<\/code><\/pre>\n<p>Im obigen Beispiel haben wir den \u00f6ffentlichen DNS-Server von Google verwendet. Beachte auch die Verwendung von <code>https:\/\/<\/code> in allen verwendeten URLs. Achte darauf, dass du dies perfekt konfigurierst, da es in Curl keinen Standard-DNS-Server gibt, auf den du zur\u00fcckgreifen kannst.<\/p>\n<p>Du kannst auch aus einer <a href=\"https:\/\/github.com\/curl\/curl\/wiki\/DNS-over-HTTPS\">Liste von \u00f6ffentlichen DoH-Servern<\/a> w\u00e4hlen, die in der Curl-Dokumentation enthalten ist.<\/p>\n<p>Au\u00dferdem wird in der Curl-Dokumentation in der <a href=\"https:\/\/curl.se\/libcurl\/c\/CURLOPT_DOH_URL.html\">CURLOPT_DOH_URL-Referenz<\/a> ausf\u00fchrlich erkl\u00e4rt, wie die verschiedenen Argumente zu verwenden sind.<\/p>\n<h3>Datei-Uploads von Strings mit CURLStringFile<\/h3>\n<p>Die PHP Curl Erweiterung unterst\u00fctzt <a href=\"https:\/\/kinsta.com\/de\/blog\/umleitung-http-zu-https\/\">HTTP(S)<\/a>-Requests mit Datei-Uploads. Sie verwendet dazu die<strong> CURLFile<\/strong> Klasse, die eine URI oder einen Dateipfad, einen Mime-Type und den endg\u00fcltigen Dateinamen akzeptiert.<\/p>\n<p>Allerdings kannst du mit der <strong>CURLFile<\/strong> Klasse nur den Dateipfad oder URI akzeptieren, aber nicht den Inhalt der Datei selbst. In F\u00e4llen, in denen du die hochzuladende Datei bereits im Speicher hattest (z.B. bearbeitete Bilder, XML Dokumente, PDFs), musstest du <code>data:\/\/<\/code> URIs mit Base64 Kodierung verwenden.<\/p>\n<p>Aber <strong>libcurl<\/strong> unterst\u00fctzt bereits einen einfacheren Weg, den Inhalt der Datei zu \u00fcbernehmen. Die neue Klasse <strong>CURLStringFile<\/strong> unterst\u00fctzt genau das.<\/p>\n<p>Du kannst die <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6456\">GitHub Seite lesen<\/a>, um mehr dar\u00fcber zu erfahren, wie sie in PHP 8.1 implementiert ist.<\/p>\n<h3>Neue <code>MYSQLI_REFRESH_REPLICA<\/code> Konstante<\/h3>\n<p>Die <strong>mysqli<\/strong> Erweiterung von PHP 8.1 f\u00fcgt eine neue Konstante namens <code>MYSQLI_REFRESH_REPLICA<\/code> hinzu. Sie ist \u00e4quivalent zur existierenden <code>MYSQLI_REFRESH_SLAVE<\/code> Konstante.<\/p>\n<p>Diese \u00c4nderung wurde in <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6632\">MySQL 8.0.23<\/a> willkommen gehei\u00dfen, um die Rassenunsensibilit\u00e4t im technischen Vokabular zu adressieren (die h\u00e4ufigsten Beispiele sind &#8222;Slave&#8220; und &#8222;Master&#8220;).<\/p>\n<p>Du solltest beachten, dass die \u00e4ltere Konstante nicht entfernt oder veraltet wird. Entwickler und Anwendungen k\u00f6nnen sie weiterhin verwenden. Die neue Konstante ist nur eine Option f\u00fcr Entwickler und Unternehmen, die diese Terminologie hinter sich lassen wollen.<\/p>\n<h3>Performanceverbesserungen mit Inheritance Cache<\/h3>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/commit\/4b79dba93202ed5640dff317046ce2fdd42e1d82\">Inheritance Cache<\/a> ist eine neue Erg\u00e4nzung zu opcache, die den Overhead der PHP-Klassenvererbung eliminiert.<\/p>\n<p>PHP-Klassen werden von opcache separat kompiliert und <a href=\"https:\/\/kinsta.com\/de\/blog\/was-ist-cache\/\">zwischengespeichert<\/a>. Allerdings werden sie bereits zur Laufzeit bei jeder Anfrage gelinkt. Dieser Prozess kann mehrere Kompatibilit\u00e4tspr\u00fcfungen und das Ausleihen von Methoden\/Properties\/Konstanten von Elternklassen und Traits beinhalten.<\/p>\n<p>Das Ergebnis ist, dass die Ausf\u00fchrung sehr viel Zeit in Anspruch nimmt, auch wenn das Ergebnis f\u00fcr jede Anfrage das gleiche ist.<\/p>\n<p>Der Inheritance Cache verkn\u00fcpft alle eindeutigen abh\u00e4ngigen Klassen (Parent, Interfaces, Traits, Property Typen, Methoden) und speichert die Ergebnisse im opcache shared memory. Da dies nur noch einmal geschieht, ben\u00f6tigt die Vererbung weniger Anweisungen.<\/p>\n<p>Dar\u00fcber hinaus werden Einschr\u00e4nkungen f\u00fcr unver\u00e4nderliche Klassen, wie unaufgel\u00f6ste Konstanten, typisierte Properties und kovariante Typ\u00fcberpr\u00fcfungen entfernt. Somit sind alle im Opcache gespeicherten Klassen unver\u00e4nderlich, was die Anzahl der ben\u00f6tigten Anweisungen weiter reduziert.<\/p>\n<p>Alles in allem verspricht es signifikante Leistungsvorteile. <a href=\"https:\/\/github.com\/dstogov\">Dimitry Stogov<\/a>, der Autor dieses Patches, fand heraus, dass er eine Verbesserung von 8% im Vergleich zum Basis Symfony &#8222;Hello, World!&#8220;-Programm zeigt. Wir k\u00f6nnen es kaum erwarten, ihn in unseren folgenden <a href=\"https:\/\/kinsta.com\/de\/blog\/php-benchmarks\/\">PHP-Benchmarks<\/a> auszuprobieren.<\/p>\n<h3>First-Class Callable-Syntax<\/h3>\n<p>PHP 8.1 f\u00fcgt eine First-Class-Callable-Syntax hinzu, die die bestehenden Kodierungen mit Strings und Arrays abl\u00f6st. Neben der Schaffung eines saubereren <strong>Closure<\/strong> ist diese neue Syntax auch f\u00fcr statische <a href=\"https:\/\/kinsta.com\/de\/blog\/code-review-tools\/\">Analysetools<\/a> zug\u00e4nglich und respektiert den deklarierten Scope.<\/p>\n<p>Hier sind ein paar Beispiele aus <a href=\"https:\/\/wiki.php.net\/rfc\/first_class_callable_syntax\">dem RFC<\/a>:<\/p>\n<pre><code class=\"language-php\">$fn = Closure::fromCallable('strlen');\n$fn = strlen(...);\n \n$fn = Closure::fromCallable([$this, 'method']);\n$fn = $this-&gt;method(...)\n \n$fn = Closure::fromCallable([Foo::class, 'method']);\n$fn = Foo::method(...);<\/code><\/pre>\n<p>Hier sind alle Ausdruckspaare gleichwertig. Die dreifach gepunktete (<strong>&#8230;<\/strong>) Syntax ist \u00e4hnlich der Syntax zum Auspacken von Argumenten (<code>...$args<\/code>). Nur dass hier die Argumente noch nicht ausgef\u00fcllt sind.<\/p>\n<h2>\u00c4nderungen in PHP 8.1<\/h2>\n<p>PHP 8.1 beinhaltet auch \u00c4nderungen an der bestehenden Syntax und den Funktionen. Lass uns diese besprechen:<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"7\" sub-toc=\"true\"><\/kinsta-auto-toc>\n<h3>PHP Interactive Shell ben\u00f6tigt readline Erweiterung<\/h3>\n<p>Die <strong>Readline<\/strong>-Erweiterung von PHP erm\u00f6glicht <a href=\"https:\/\/kinsta.com\/de\/blog\/einstiegen-nutzung-ssh\/\">interaktive Shell<\/a>-Funktionen wie Navigation, Autovervollst\u00e4ndigung, Bearbeitung und mehr. Obwohl sie mit PHP mitgeliefert wird, ist sie standardm\u00e4\u00dfig nicht aktiviert.<\/p>\n<p>Du kannst die interaktive PHP-Shell mit der <code>-a<\/code> Kommandozeilenoption von PHP CLI aufrufen:<\/p>\n<pre><code class=\"language-php\">php -a\n\nInteractive shell\n\nphp &gt;\nphp &gt; echo \"Hello\";\nHello\nphp &gt; function test() {\nphp { echo \"Hello\";\nphp { }\nphp &gt; test();\nHello<\/code><\/pre>\n<p>Vor PHP 8.1 konnte man die interaktive Shell mit PHP CLI auch ohne aktivierte <strong>Readline<\/strong>-Erweiterung \u00f6ffnen. Wie erwartet, funktionierten die interaktiven Funktionen der Shell nicht, was die Option <code>-a<\/code> sinnlos machte.<\/p>\n<p>In PHP 8.1 CLI beendet sich die interaktive Shell mit einer Fehlermeldung, wenn du die <a href=\"https:\/\/github.com\/php\/php-src\/commit\/959e5787bdf7c088a57dce5f4f7570abd7fe35f8\">Readline-Erweiterung nicht aktiviert hast<\/a>.<\/p>\n<pre><code class=\"language-php\">php -a\nInteractive shell (-a) requires the readline extension.<\/code><\/pre>\n<h3>MySQLi Standard-Fehlermodus auf Exceptions gesetzt<\/h3>\n<p>Vor PHP 8.1 hat <a href=\"https:\/\/kinsta.com\/de\/blog\/was-ist-mysql\/\">MySQLi<\/a> die Fehler standardm\u00e4\u00dfig verschwiegen. Dieses Verhalten f\u00fchrte oft zu Code, der sich nicht an die strenge Fehler-\/Ausnahmebehandlung hielt. Die Entwickler mussten ihre eigenen expliziten Funktionen zur Fehlerbehandlung implementieren.<\/p>\n<p>PHP 8.1 \u00e4ndert dieses Verhalten, indem es den Standard-Fehlermeldemodus von MySQLi so einstellt, dass eine Ausnahme geworfen wird.<\/p>\n<pre><code class=\"language-php\">Fatal error: Uncaught mysqli_sql_exception: Connection refused in ...:...<\/code><\/pre>\n<p>Da dies eine einschneidende \u00c4nderung ist, solltest du f\u00fcr PHP &lt;8.1 Versionen den Fehlerbehandlungsmodus explizit mit der <code>mysqli_report<\/code> Funktion setzen, bevor du die erste MySQLi Verbindung herstellst. Alternativ kannst du dies auch tun, indem du den Wert f\u00fcr die Fehlerberichterstattung durch die Instanzierung einer <code>mysqli_driver<\/code>-Instanz ausw\u00e4hlst.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/mysqli_default_errmode\">Der RFC<\/a> folgt einer <a href=\"https:\/\/wiki.php.net\/rfc\/pdo_default_errmode\">\u00e4hnlichen \u00c4nderung, die in PHP 8.0 eingef\u00fchrt wurde<\/a>.<\/p>\n<h3>Anpassbare Zeilenenden f\u00fcr CSV Schreibfunktionen<\/h3>\n<p>Vor PHP 8.1 waren die in PHP eingebauten <a href=\"https:\/\/kinsta.com\/changelog\/export-redirects-csv\/\">CSV<\/a>-Schreibfunktionen <code>fputcsv<\/code> und <code>SplFileObject::fputcsv<\/code> so programmiert, dass sie am Ende jeder Zeile <code>\\n<\/code> (oder das Line-Feed-Zeichen) anf\u00fcgten.<\/p>\n<p>PHP 8.1 f\u00fcgt diesen Funktionen Unterst\u00fctzung f\u00fcr einen neuen Parameter namens <code>eol<\/code> hinzu. Du kannst ihn benutzen, um ein konfigurierbares Zeilenendezeichen zu \u00fcbergeben.\u00a0 Standardm\u00e4\u00dfig wird immer noch das <code>\\n<\/code>-Zeichen verwendet. Du kannst es also weiterhin in deinem bestehenden Code verwenden.<\/p>\n<p>F\u00fcr die Verwendung von Zeilenende-Zeichen gelten die Standardzeichen-Escaping-Regeln. Wenn du <code>\\r<\/code>, <code>\\n<\/code> oder <code>\\r\\n<\/code> als EOL-Zeichen verwenden willst, musst du sie in doppelte Anf\u00fchrungszeichen einschlie\u00dfen.<\/p>\n<p>Hier ist die <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6403\">GitHub Seite<\/a>, die diese neue \u00c4nderung dokumentiert.<\/p>\n<h3>Neue <code>version_compare<\/code> Operator-Einschr\u00e4nkungen<\/h3>\n<p>Die Funktion <code>version_compare()<\/code> von PHP vergleicht zwei Versionsnummern-Strings. Diese Funktion akzeptiert ein optionales drittes Argument namens <code>operator<\/code>, um auf eine bestimmte Beziehung zu testen.<\/p>\n<p>Obwohl nicht explizit in der Dokumentation beschrieben, konnte man vor PHP 8.1 diesen Parameter auf einen Teilwert (z.B. <code>g<\/code>, <code>l<\/code>, <code>n<\/code>) setzen, ohne einen Fehler zu erhalten.<\/p>\n<p>PHP 8.1 f\u00fcgt strengere Einschr\u00e4nkungen f\u00fcr das <code>Operator<\/code>-Argument der Funktion <code>version_compare()<\/code> hinzu, um diese Situation zu umgehen. Die einzigen Operatoren, die du jetzt verwenden kannst, sind:<\/p>\n<ul>\n<li><strong>==<\/strong>, <strong>=<\/strong>, und <strong>eq<\/strong><\/li>\n<li><strong>!=<\/strong>, <strong>&lt;&gt;<\/strong>, und <strong>ne<\/strong><\/li>\n<li><strong>&gt;<\/strong> und <strong>gt<\/strong><\/li>\n<li><strong>&gt;=<\/strong> und <strong>ge<\/strong><\/li>\n<li><strong>&lt;<\/strong> und <strong>lt<\/strong><\/li>\n<li><strong>&lt;=<\/strong> und <strong>le<\/strong><\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/pull\/6510\">Keine partiellen Operatorwerte mehr<\/a>.<\/p>\n<h3>HTML Kodierungs- und Dekodierungsfunktionen verwenden jetzt <code>ENT_QUOTES | ENT_SUBSTITUTE<\/code><\/h3>\n<p>HTML-Entities sind textuelle Repr\u00e4sentationen von Zeichen, die sonst als HTML interpretiert werden w\u00fcrden. Denke an Zeichen wie <code>&lt;<\/code> und <code>&gt;<\/code>, die verwendet werden, um <a href=\"https:\/\/kinsta.com\/de\/blog\/bewaehrte-html-praktiken\/\">HTML-Tags zu definieren<\/a> (z.B. <code>&lt;a&gt;<\/code>, <code>&lt;h3&gt;<\/code>, <code>&lt;script&gt;<\/code>).<\/p>\n<p>Die HTML Entit\u00e4t f\u00fcr <code>&lt;<\/code> ist <code>&lt;<\/code>\u00a0(kleiner als Symbol) und <code>&gt;<\/code> ist <code>&gt;<\/code> (gr\u00f6\u00dfer als Symbol).<\/p>\n<p><strong>Hinweis:<\/strong> Entferne das Leerzeichen zwischen &#8222;&#038;&#8220; und &#8222;amp&#8220;.<\/p>\n<p>Du kannst diese HTML-Entities sicher in einem HTML-Dokument verwenden, ohne die Rendering-Engine des Browsers auszul\u00f6sen.<\/p>\n<p>Zum Beispiel wird <code>&lt;script&gt;<\/code> im Browser als <code>&lt;script&gt;<\/code> angezeigt, anstatt als HTML-Tag interpretiert zu werden.<\/p>\n<p>Vor PHP 8.1 wandelten die Funktionen <a href=\"https:\/\/www.php.net\/manual\/function.htmlspecialchars.php\">htmlspecialchars()<\/a> und <a href=\"https:\/\/www.php.net\/manual\/en\/function.htmlentities.php\">htmlentities()<\/a> Symbole wie <code>\"<\/code>, <code>&lt;<\/code>, <code>&gt;<\/code> und <code>&<\/code> in die entsprechenden HTML-Entit\u00e4ten um. Aber sie wandelten das einfache Anf\u00fchrungszeichen (<code>'<\/code>) standardm\u00e4\u00dfig nicht in seine HTML-Entit\u00e4t um. Au\u00dferdem gaben sie einen leeren String zur\u00fcck, wenn der Text ein fehlerhaftes UTF-8 enthielt.<\/p>\n<p>In PHP 8.1. werden diese HTML-Kodierungs- und Dekodierungsfunktionen (und ihre verwandten Funktionen) standardm\u00e4\u00dfig auch <a href=\"https:\/\/github.com\/php\/php-src\/commit\/50eca61f68815005f3b0f808578cc1ce3b4297f0\">einfache Anf\u00fchrungszeichen<\/a> in ihre HTML-Entit\u00e4t umwandeln.<\/p>\n<p>Und wenn der angegebene Text ung\u00fcltige Zeichen enth\u00e4lt, werden die Funktionen diese durch ein Unicode-Ersatzzeichen (\ufffd) ersetzen, anstatt einen leeren String zur\u00fcckzugeben. PHP 8.1 erreicht dies, indem es die Signaturen dieser Funktionen standardm\u00e4\u00dfig auf <code>ENT_QUOTES | ENT_SUBSTITUTE<\/code> statt <code>ENT_COMPAT<\/code> \u00e4ndert.<\/p>\n<p>Die meisten Frameworks verwenden bereits <code>ENT_QUOTES<\/code> als Standard-Flag-Wert. Du wirst also keinen gro\u00dfen Unterschied durch diese \u00c4nderung sehen. Allerdings wird das neue <code>ENT_SUBSTITUTE<\/code> Flag nicht so h\u00e4ufig verwendet. PHP 8.1 bewirkt, dass ung\u00fcltige UTF-8 Zeichen durch das \ufffd Zeichen ersetzt werden, anstatt einen leeren String zur\u00fcckzugeben.<\/p>\n<h3>Warnung bei unzul\u00e4ssigen kompakten Funktionsaufrufen<\/h3>\n<p>Die Funktion <code>compact()<\/code> von PHP ist super praktisch. Du kannst sie benutzen, um ein Array mit Variablen zu erstellen, indem du ihre Namen und Werte benutzt.<\/p>\n<p>Betrachte zum Beispiel den folgenden Code:<\/p>\n<pre><code class=\"language-php\">$animal = 'Cat';\n$sound = 'Meow';\n$region = 'Istanbul';\ncompact('animal', 'sound', 'region');\n\/\/ ['animal' =&gt; \"Cat\", 'sound' =&gt; \"Meow\", 'region' =&gt; \"Istanbul\"]<\/code><\/pre>\n<p>Die <a href=\"https:\/\/www.php.net\/manual\/en\/function.compact.php\">Dokumentation der compact-Funktion<\/a> besagt, dass sie nur String-Parameter oder Array-Werte mit String-Werten akzeptiert. Vor PHP 7.3 wurden jedoch alle Strings, die nicht gesetzt waren, stillschweigend \u00fcbersprungen.<\/p>\n<p>PHP 7.3 hat die <code>compact()<\/code>-Funktion dahingehend ge\u00e4ndert, dass sie eine Meldung ausgibt, wenn du undefinierte Variablen verwendest. <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6921\">PHP 8.1 geht noch einen Schritt weiter<\/a> und gibt eine Warnung aus.<\/p>\n<p>Du kannst <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6921\">die GitHub Seite lesen<\/a>, um zu verstehen, wie es zu dieser \u00c4nderung kam.<\/p>\n<h3>Neue Migrationen von Ressourcen zu Klassenobjekten<\/h3>\n<p>Eines der langfristigen Ziele von PHP ist es, weg <a href=\"https:\/\/php.watch\/articles\/resource-object\">von Ressourcen hin zu Standardklassenobjekten zu kommen<\/a>.<\/p>\n<p>Aus historischen Gr\u00fcnden werden Ressourcen-Objekte in PHP-Applikationen ausgiebig genutzt. Daher muss die Migration von Ressourcen zu Klassenobjekten so wenig st\u00f6rend wie m\u00f6glich sein. PHP 8.1 migriert f\u00fcnf solcher Ressourcen:<\/p>\n<h4>Die <code>file_info<\/code> Ressource migriert zu <code>finfo<\/code> Objekten<\/h4>\n<p>PHPs <a href=\"https:\/\/www.php.net\/manual\/en\/class.finfo.php\">finfo Klasse<\/a> bietet eine <a href=\"https:\/\/kinsta.com\/de\/blog\/objektorientierten-programmierung-python\/#what-is-objectoriented-programming-in-python\">objektorientierte<\/a> Schnittstelle f\u00fcr die <code>fileinfo<\/code> Funktionen. Allerdings gibt die Verwendung der <code>finfo<\/code>-Funktionen <code>Resource<\/code> nobjekte mit dem Typ <code>file_info<\/code> zur\u00fcck, anstatt eine Instanz der <code>finfo<\/code>-Klasse selbst.<\/p>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/pull\/5987\">PHP 8.1 behebt diese Anomalie<\/a>.<\/p>\n<h4>IMAP-Ressourcen werden zu Objekten der <code>IMAP\\Connection<\/code> migriert<\/h4>\n<p>In \u00dcbereinstimmung mit dem Ziel der Migration von Ressourcen zu Objekten, minimiert die neue IMAP\\Connection Klasse potentielle \u00c4nderungen, wenn PHP die Implementierungsdetails der Klasse modifiziert.<\/p>\n<p>Diese neue Klasse ist auch als <code>final<\/code> deklariert, du darfst sie also nicht <code>extend<\/code>.<\/p>\n<p>Lies mehr \u00fcber die Implementierung auf ihrer <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6418\">GitHub Seite<\/a>.<\/p>\n<h4>FTP-Verbindungsressourcen sind jetzt Objekte der Klasse <code>FTP\\Connection<\/code><\/h4>\n<p>Wenn du in PHP &lt;8.1 eine <a href=\"https:\/\/kinsta.com\/de\/blog\/besten-ftp-clients\/\">FTP-Verbindung<\/a> mit den Funktionen <code>ftp_connect()<\/code> oder <code>ftp_ssl_connect()<\/code> erstellst, erh\u00e4ltst du ein <strong>Ressourcen <\/strong>objekt vom Typ <strong>ftp<\/strong> zur\u00fcck.<\/p>\n<p>PHP 8.1 f\u00fcgt die neue <code>FTP\\Connection<\/code> Klasse hinzu, um das zu korrigieren. Und wie die <code>IMAP\\Connection<\/code> Klasse ist auch diese als <code>final<\/code> deklariert, um zu verhindern, dass sie erweitert wird.<\/p>\n<p>Lies mehr \u00fcber die <a href=\"https:\/\/github.com\/php\/php-src\/commit\/b4503fbf882e490f16d85915e83173bd1e414e84\">Implementierung<\/a> auf ihrer GitHub Seite.<\/p>\n<h4>Font Identifier migriert zu <code>GdFont<\/code> Klassenobjekten<\/h4>\n<p>PHPs GD-Erweiterung bietet die Funktion <a href=\"https:\/\/www.php.net\/manual\/en\/function.imageloadfont.php\">imageloadfont()<\/a>, um eine benutzerdefinierte Bitmap zu laden und ihre Font-Identifier-Ressource-ID (eine Ganzzahl) zur\u00fcckzugeben.<\/p>\n<p>In PHP 8.1 wird diese Funktion stattdessen eine <strong>GdFont<\/strong>-Klasseninstanz zur\u00fcckgeben. Um die Migration problemlos zu gestalten, werden alle Funktionen, die bisher eine Resource ID von <code>imageloadfont()<\/code> akzeptiert haben, nun die neuen <strong>GdFont<\/strong>-Klassenobjekte annehmen.<\/p>\n<p>Lies mehr \u00fcber diese Migration auf der <a href=\"https:\/\/github.com\/php\/php-src\/commit\/bc40bce868e208fa2d7af950845759d3ef498b5d\">GitHub Seite<\/a>.<\/p>\n<h4>LDAP Ressourcen zu Objekten migriert<\/h4>\n<p><a href=\"https:\/\/www.php.net\/manual\/en\/intro.ldap.php\">LDAP<\/a>, oder Lightweight Directory Access Protocol, wird f\u00fcr den Zugriff auf &#8222;Directory Servers&#8220; verwendet. Wie eine Verzeichnisstruktur auf der Festplatte ist es eine einzigartige Datenbank, die Daten in einer Baumstruktur h\u00e4lt.<\/p>\n<p>PHP beinhaltet eine LDAP-Erweiterung, die vor PHP 8.1 <strong>Ressourcen <\/strong>objekte akzeptierte oder zur\u00fcckgab. Allerdings sind sie jetzt alle nahtlos in neue Klasseninstanzen migriert. Die <strong>Ressourcen <\/strong>typen, die umgestellt wurden, sind:<\/p>\n<ul>\n<li><code>ldap link<\/code> Ressource zu <code>\\LDAP\\Connection<\/code> Klassenobjekt<\/li>\n<li><code>ldap result<\/code> Ressource zu <code>\\LDAP\\Result<\/code> Klassenobjekt<\/li>\n<li><code>ldap result entry<\/code> Ressource zu <code>\\LDAP\\ResultEntry<\/code> Klassenobjekt<\/li>\n<\/ul>\n<p>Schau dir die <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6770\">GitHub Seite<\/a> an, um diese Migration besser zu verstehen.<\/p>\n<h4>Pspell Ressourcen sind jetzt Klassenobjekte<\/h4>\n<p>Die <a href=\"https:\/\/www.php.net\/manual\/en\/intro.pspell.php\">PHP-Erweiterung Pspell<\/a> erm\u00f6glicht es dir, Rechtschreibfehler und Wortvorschl\u00e4ge zu \u00fcberpr\u00fcfen.<\/p>\n<p>PHP &lt;8.1 verwendete die Ressource-Objekttypen <code>pspell<\/code> und <code>pspell config<\/code> mit einem Integer-Bezeichner. Diese beiden Ressourcenobjekte werden nun durch die Klassenobjekte <code>PSpell\\Dictionary<\/code> und <code>PSpell\\Config<\/code> ersetzt.<\/p>\n<p>Wie bei fr\u00fcheren Migrationen werden <a href=\"https:\/\/php.watch\/versions\/8.1\/PSpell-resource#PSpell-Dictionary\">alle Pspell-Funktionen<\/a>, die vorher Resource-Objekt-Identifikatoren akzeptiert oder zur\u00fcckgegeben haben, die neuen Klassenobjekt-Instanzen annehmen.<\/p>\n<p>Weitere Informationen findest du auf der <a href=\"https:\/\/github.com\/php\/php-src\/commit\/bd12c94f46438dad03d1d3c02fff37b9b950ae6f\">GitHub-Seite<\/a>.<\/p>\n<h2>Verwerfungen in PHP 8.1<\/h2>\n<p>Mit PHP 8.1 werden viele der bisherigen Funktionen veraltet sein. Die folgende Liste bietet einen kurzen \u00dcberblick \u00fcber die Funktionalit\u00e4ten, die mit PHP 8.1 veraltet sind:<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"10\" sub-toc=\"true\"><\/kinsta-auto-toc>\n<h3>Kann nicht <code>null<\/code> an nicht-nullbare interne Funktionsparameter \u00fcbergeben<\/h3>\n<p>Seit PHP 8.0 akzeptieren die internen Funktionen stillschweigend Nullwerte, auch f\u00fcr nicht-<code>null<\/code>bare Argumente. Das Gleiche gilt nicht f\u00fcr benutzerdefinierte Funktionen &#8211; sie akzeptieren nur <code>null<\/code> f\u00fcr nullbare Argumente.<\/p>\n<p>Betrachte zum Beispiel diese Anwendung:<\/p>\n<pre><code class=\"language-php\">var_dump(<strong>str_contains<\/strong>(\"foobar\", null));\n\/\/ bool(<strong>true<\/strong>)<\/code><\/pre>\n<p>Hier wird der <code>Null<\/code>-Wert stillschweigend in einen leeren String umgewandelt. Somit gibt das Ergebnis <code>true<\/code> zur\u00fcck.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/deprecate_null_to_scalar_internal_arg\">Dieser RFC<\/a> zielt darauf ab, das Verhalten der internen Funktionen zu synchronisieren, indem eine Deprecation-Warnung in PHP 8.1 geworfen wird.<\/p>\n<pre><code class=\"language-php\">var_dump(str_contains(\"foobar\", null));\n\/\/ Deprecated: Passing null to argument of type string is deprecated<\/code><\/pre>\n<p>Die Verwerfung wird in der n\u00e4chsten gr\u00f6\u00dferen PHP-Version (d.h. PHP &gt;=9.0) zu einem TypeError, wodurch das Verhalten der internen Funktionen mit den benutzerdefinierten Funktionen konsistent wird.<\/p>\n<h3>Eingeschr\u00e4nkte <code>$GLOBALS<\/code>-Verwendung<\/h3>\n<p>PHP&#8217;s <code>$GLOBALS<\/code> Variable bietet einen direkten Verweis auf die interne Symboltabelle. Die Unterst\u00fctzung dieser Funktionalit\u00e4t ist komplex und beeinflusst die Performance von Array-Operationen. Au\u00dferdem wurde sie selten benutzt.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/restrict_globals_usage\">Laut RFC<\/a> ist es nicht mehr erlaubt, <code>$GLOBALS<\/code> indirekt zu modifizieren. Diese \u00c4nderung ist nicht r\u00fcckw\u00e4rtskompatibel.<\/p>\n<p>Der Einfluss dieser \u00c4nderung ist relativ gering:<\/p>\n<p style=\"padding-left: 40px\"><em>In den Top 2k Composer Paketen habe ich <a href=\"https:\/\/gist.github.com\/nikic\/9fd95866f9811b349b947f63214ad7a9\">23 F\u00e4lle gefunden, die $GLOBALS<\/a> verwenden, ohne es direkt zu derefenzieren. Basierend auf einer fl\u00fcchtigen Inspektion, gibt es nur zwei F\u00e4lle, in denen <strong>$GLOBALS<\/strong> nicht schreibgesch\u00fctzt verwendet wird.<\/em><\/p>\n<p>Allerdings funktioniert die Nur-Lese-Verwendung von <code>$GLOBALS<\/code> weiterhin wie gewohnt. Was nicht mehr unterst\u00fctzt wird, ist das Schreiben in <code>$GLOBALS<\/code> als Ganzes. Als Ergebnis kannst du einen leichten <a href=\"https:\/\/kinsta.com\/de\/blog\/tools-fuer-performance-tests\/\">Performance-Schub<\/a> erwarten, besonders wenn du mit gew\u00f6hnlichen PHP-Arrays arbeitest.<\/p>\n<h3>R\u00fcckgabetyp-Deklarationen f\u00fcr interne Funktionen<\/h3>\n<p>PHP 8.0 erlaubte es Entwicklern, Parameter und R\u00fcckgabetypen f\u00fcr die meisten internen Funktionen und Methoden zu deklarieren. Dies war dank verschiedener RFCs wie <a href=\"https:\/\/kinsta.com\/de\/blog\/php-8\/#type-errors-internal-functions\">Consistent type errors for internal functions<\/a>, <a href=\"https:\/\/kinsta.com\/de\/blog\/php-8\/#union-types-2-0\">Union Types 2.0<\/a> und <a href=\"https:\/\/wiki.php.net\/rfc\/mixed_type_v2\">Mixed Type v2<\/a> m\u00f6glich.<\/p>\n<p>Allerdings gibt es viele F\u00e4lle, in denen Typinformationen fehlen k\u00f6nnen. Einige davon sind ein Typ mit Ressourcen, <strong>out<\/strong> pass-by-ref Parameter, R\u00fcckgabetyp von nicht-finalen Methoden und Funktionen oder Methoden, die Parameter nicht nach den allgemeinen Regeln parsen. Die genauen Details kannst du in <a href=\"https:\/\/wiki.php.net\/rfc\/internal_method_return_types\">seinem RFC<\/a> nachlesen.<\/p>\n<p>Dieser RFC behandelt nur das Problem mit dem R\u00fcckgabetyp von nicht-finalen Methoden. Anstatt es jedoch sofort ganz abzuschaffen, bietet das PHP-Team einen schrittweisen Migrationspfad an, um deine Codebases mit den relevanten Methodenr\u00fcckgabetypen zu aktualisieren.<\/p>\n<p><em>Nicht-finale interne Methoden-R\u00fcckgabetypen werden &#8211; wenn m\u00f6glich &#8211; in PHP 8.1 vorl\u00e4ufig deklariert, und sie werden in PHP 9.0 erzwungen werden. Das bedeutet, dass in PHP 8.x-Versionen eine &#8222;deprecated&#8220;-Meldung w\u00e4hrend der Vererbungspr\u00fcfung ausgegeben wird, wenn eine interne Methode so \u00fcberschrieben wird, dass die R\u00fcckgabetypen inkompatibel sind, und PHP 9.0 wird dies zu einem fatalen Fehler machen.<\/em><\/p>\n<p>Wenn du diese Deprecation Notice nach dem Update auf PHP 8.1 siehst, stelle sicher, dass du die R\u00fcckgabetypen deiner Methoden aktualisierst.<\/p>\n<h3>Serialisierbare Schnittstelle Veraltet<\/h3>\n<p>PHP 7.4 hat den Mechanismus der <a href=\"https:\/\/kinsta.com\/de\/blog\/php-7-4\/#serialization\">benutzerdefinierten Objektserialisierung<\/a> mit zwei neuen magischen Methoden eingef\u00fchrt: <code>__serialize()<\/code> und <code>__unserialize()<\/code>. Diese neuen Methoden zielen darauf ab, das kaputte <strong>Serializable<\/strong> Interface irgendwann zu ersetzen.<\/p>\n<p>Dieser <a href=\"https:\/\/wiki.php.net\/rfc\/phase_out_serializable\">RFC schl\u00e4gt vor<\/a>, diese Entscheidung zu finalisieren, indem er einen Plan f\u00fcr die eventuelle Entfernung von <strong>Serializable<\/strong> aufstellt.<\/p>\n<p>Wenn du in PHP 8.1 das <strong>Serializable<\/strong> Interface implementierst, ohne die <code>__serialize()<\/code> und <code>__unserialize()<\/code> Methoden zu implementieren, wird PHP eine &#8222;Deprecated&#8220; Warnung ausgeben.<\/p>\n<pre><code class=\"language-php\">Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in ... on line ...<\/code><\/pre>\n<p>Wenn du <strong>PHP &lt;7.4<\/strong> und <strong>PHP &gt;=7.4<\/strong> unterst\u00fctzt, solltest du sowohl das <strong>Serializable<\/strong> Interface als auch die neuen magischen Methoden implementieren. Bei <strong>PHP &gt;=7.4<\/strong> Versionen haben die magischen Methoden Vorrang.<\/p>\n<h3>Nicht kompatible <code>float<\/code> to <code>int<\/code> Conversions Veraltet<\/h3>\n<p>PHP ist eine dynamisch typisierte Sprache. Als solche gibt es viele F\u00e4lle, in denen Typenzwang nat\u00fcrlich vorkommt. Die meisten dieser Zw\u00e4nge sind harmlos und superpraktisch.<\/p>\n<p>Wenn jedoch eine<strong> Float<\/strong>-Zahl in eine <strong>Integer<\/strong>-Zahl umgewandelt wird, ist dies oft mit Datenverlust verbunden. Wenn zum Beispiel die Float-Zahl <strong>3,14<\/strong> in eine Integer-Zahl <strong>3<\/strong> umgewandelt wird, verliert sie ihren Nachkommawert.<\/p>\n<p>Das Gleiche passiert, wenn der Float au\u00dferhalb des Plattform-Integer-Bereichs liegt, oder wenn ein Float-String in einen Integer konvertiert wird.<\/p>\n<p>PHP 8.1 korrigiert dieses Verhalten und bringt die dynamische Typenzwangssteuerung mehr in Einklang mit den meisten modernen Programmiersprachen. Das Ziel ist es, solche Zw\u00e4nge vorhersehbar und intuitiv zu machen.<\/p>\n<p>In PHP 8.1 wirst du eine Deprecation-Notiz sehen, wenn ein nicht kompatibler <strong>Float<\/strong> implizit in einen <strong>Int<\/strong> umgewandelt wird. Aber was ist ein integer-kompatibler Float? <a href=\"https:\/\/wiki.php.net\/rfc\/implicit-float-int-deprecate\">Der RFC<\/a> beantwortet dies:<\/p>\n<p><em>Ein Float wird als integer-kompatibel bezeichnet, wenn er die folgenden Eigenschaften besitzt:<\/em><\/p>\n<ul>\n<li><em>Ist eine Zahl (d.h. nicht NaN oder Infinity)<\/em><\/li>\n<li><em>Liegt im Bereich eines PHP Integers (plattformabh\u00e4ngig)<\/em><\/li>\n<li><em>Hat keinen Nachkommaanteil<\/em><\/li>\n<\/ul>\n<p>Dieser Hinweis wird in der n\u00e4chsten PHP Version (d.h. PHP 9.0) in einen <strong>TypeError<\/strong> umgewandelt.<\/p>\n<h3><strong>Die <code>mysqli::get_client_info<\/code> Methode und <code>mysqli_get_client_info($param)<\/code> veraltet.<\/strong><\/h3>\n<p>Die MySQL Client API definiert zwei Konstanten: <code>client_info<\/code> (ein String) und <code>client_version<\/code> (ein int). Der MySQL Native Driver (MySQLnd) ist Teil des offiziellen PHP-Source und bindet diese Konstanten an die PHP-Version. In libmysql repr\u00e4sentieren sie die Version der Client-Bibliothek zum Zeitpunkt der Kompilierung.<\/p>\n<p>Vor PHP 8.1 wurden diese Konstanten von mysqli auf vier Arten offengelegt: <code>mysqli_driver<\/code> properties, <code>mysqli <strong>properties<\/strong><\/code>, <code>mysqli_get_client_info()<\/code> Funktion und <code>mysqli::get_client_info<\/code> Methode. Allerdings gibt es keine Methode f\u00fcr <code>client_version<\/code>.<\/p>\n<p>MySQLnd gibt diese Konstanten auf 2 Arten an PHP weiter: als Konstante und als Funktionsaufruf. Um die mysqli-Zugriffsmethoden mit diesen beiden Optionen zu vereinheitlichen, veraltet PHP 8.1 diese beiden anderen Optionen:<\/p>\n<ul>\n<li>Die <code>get_client_info<\/code> Methode in der <strong>mysqli<\/strong> Stattdessen kannst du einfach die Funktion <code>mysqli_get_client_info()<\/code> verwenden.<\/li>\n<li><code>mysqli_get_client_info()<\/code> Funktion mit Parametern. Rufe die Funktion ohne Parameter auf, um den Verwerfungshinweis zu vermeiden.<\/li>\n<\/ul>\n<p>Lies mehr \u00fcber diese Verwerfung auf <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6777\">der GitHub Seite<\/a>.<\/p>\n<h3><strong>Alle <code>mhash*()<\/code>-Funktionen (Hash-Erweiterung) sind veraltet<\/strong><\/h3>\n<p>PHP 5.3 integrierte <code>mhash*()<\/code> Funktionen in <code>ext\/hash<\/code> als Kompatibilit\u00e4tsschicht f\u00fcr <code>ext\/mhash<\/code>. Sp\u00e4ter, mit PHP 7.0, wurde <code>ext\/mhash<\/code> entfernt.<\/p>\n<p>Anders als die <code>hash_*()<\/code> Funktionen sind die <code>mhash*()<\/code> Funktionen nicht immer verf\u00fcgbar. Du musst sie separat bei der Konfiguration von PHP aktivieren.<\/p>\n<p>In PHP 7.4 wurde die Hash-Erweiterung zusammen mit PHP geb\u00fcndelt, was sie zu einer Standarderweiterung f\u00fcr PHP machte. Aus Kompatibilit\u00e4tsgr\u00fcnden wurde jedoch weiterhin die Option <code>--enable-mhash<\/code> aktiviert.<\/p>\n<p>Das PHP-Team hat beschlossen, <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1#mhash_function_family\">die mhash*()-Funktionen<\/a> in PHP 8.1 zu verwerfen und sie in PHP 9.0 ganz zu entfernen. Die veralteten Funktionen sind <code>mhash()<\/code>,<code> mhash_keygen_s2k()<\/code>, <code>mhash_count()<\/code>, <code>mhash_get_block_size()<\/code> und <code>mhash_get_hash_name()<\/code>. Du kannst stattdessen die Standard <code>ext\/hash<\/code> Funktionalit\u00e4t verwenden.<\/p>\n<h3>Beide <code>filter.default<\/code> und <code>filter.default_options<\/code> INI-Einstellungen sind veraltet<\/h3>\n<p>PHPs <code>filter.default<\/code> INI-Einstellungen erlauben es dir, einen Filter auf alle PHP-Superglobals anzuwenden &#8211; d.h. GPCRS-Daten (<code>$_GET<\/code>, <code>$_POST<\/code>, <code>$_COOKIE<\/code>, <code>$_REQUEST<\/code> und <code>$_SERVER<\/code>).<\/p>\n<p>Zum Beispiel kannst du <code>filter.default=magic_quotes<\/code> oder <code>filter.default=add_slashes<\/code> (je nach PHP Version) setzen, um <a href=\"https:\/\/en.wikipedia.org\/wiki\/Magic_quotes\">die umstrittene und unsichere Funktion der magischen Anf\u00fchrungszeichen<\/a> (die in PHP 5.4 entfernt wurde) wieder aufleben zu lassen.<\/p>\n<p>Die <code>filter.default<\/code> INI-Einstellung bietet zus\u00e4tzliche Funktionalit\u00e4t, indem sie viele weitere Filter zul\u00e4sst, was es noch schlimmer macht. Zum Beispiel erm\u00f6glicht eine weitere Option &#8211; <code>filter.default=special_chars<\/code> &#8211; magische Anf\u00fchrungszeichen nur f\u00fcr HTML. Es gibt viel weniger Bewusstsein f\u00fcr diese Einstellungen.<\/p>\n<p>PHP 8.1 wird <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1#filterdefault_ini_setting\">eine Deprecation-Warnung ausgeben<\/a>, wenn <code>filter.default<\/code> auf einen anderen Wert als <code>unsafe_raw<\/code> (der Standard) gesetzt ist. F\u00fcr <code>filter.default_options<\/code> gibt es keine gesonderte Warnung, aber PHP 9.0 wird diese beiden INI-Einstellungen entfernen.<\/p>\n<p>Als Alternative kannst du die Funktion <a href=\"https:\/\/www.php.net\/manual\/en\/function.filter-var.php\">filter_var()<\/a> verwenden. Sie filtert Variablen mit dem angegebenen Filter.<\/p>\n<h3>Deprecate <code>autovivification<\/code> auf false<\/h3>\n<p>PHP erlaubt die Autovivification (automatische Erstellung von Arrays aus falschen Werten). Diese Funktion ist sehr hilfreich, wenn die Variable undefiniert ist.<\/p>\n<p>Nichtsdestotrotz ist es nicht ideal, ein Array automatisch zu erstellen, wenn der Wert falsch oder null ist.<\/p>\n<p>Dieser RFC <a href=\"https:\/\/wiki.php.net\/rfc\/autovivification_false\">verbietet die Autovivification<\/a> von falschen Werten. Beachte jedoch, dass Autovivification von undefinierten Variablen und null immer noch erlaubt ist.<\/p>\n<p>In PHP 8.1 wird das Anh\u00e4ngen an eine Variable vom Typ false eine Deprecation Notice ausgeben:<\/p>\n<pre><code class=\"language-php\">Deprecated: Automatic conversion of false to array is deprecated in<\/code><\/pre>\n<p>PHP 9.0 wirft einen fatalen Fehler f\u00fcr dasselbe aus, was identisch mit anderen skalaren Typen ist.<\/p>\n<h3><strong>Die <code>mysqli_driver-&gt;driver_version<\/code> Property ist veraltet<\/strong><\/h3>\n<p>Das Property <strong>mysqli_driver-&gt;driver_version<\/strong> der MySQLi Extension wurde seit 13 Jahren nicht mehr aktualisiert. Trotz vieler \u00c4nderungen am Treiber seither, gibt sie immer noch den alten Wert der Treiberversion zur\u00fcck, was diese Property bedeutungslos macht.<\/p>\n<p>In PHP 8.1 ist die <a href=\"https:\/\/github.com\/php\/php-src\/commit\/3dfd3558ca2f63f\">mysqli_driver-&gt;driver_version Property veraltet<\/a>.<\/p>\n<h2>Andere kleinere Verwerfungen<\/h2>\n<p>Es gibt noch <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1\">viele weitere Verwerfungen in PHP 8.1<\/a>. Sie alle hier aufzulisten, w\u00e4re eine anstrengende Aufgabe. Wir empfehlen dir, direkt im RFC nachzuschauen, um diese kleineren Verwerfungen zu finden.<\/p>\n<p>Auf der GitHub Seite von PHP gibt es auch einen <a href=\"https:\/\/github.com\/php\/php-src\/blob\/master\/UPGRADING\">PHP 8.1 UPGRADE NOTES<\/a> Guide. Er listet alle \u00c4nderungen auf, die du vor dem Upgrade auf PHP 8.1 beachten solltest.<\/p>\n\n<h2>Zusammenfassung<\/h2>\n<p>PHP 8.1 ist besser als <a href=\"https:\/\/kinsta.com\/de\/blog\/php-8\/\">sein Vorg\u00e4nger<\/a>, was keine kleine Leistung ist. Die aufregendsten Funktionen von PHP 8.1 sind unserer Meinung nach Enums, Fibers, Pure Intersection Types und die vielen Leistungsverbesserungen. Au\u00dferdem k\u00f6nnen wir es kaum erwarten, PHP 8.1 auf Herz und Nieren zu pr\u00fcfen und verschiedene <a href=\"https:\/\/kinsta.com\/de\/blog\/php-frameworks\/\">PHP-Frameworks<\/a> und <a href=\"https:\/\/kinsta.com\/de\/wordpress-marktanteil\/\">CMS<\/a> zu vergleichen.<\/p>\n<p>Setze ein Lesezeichen f\u00fcr diesen Blogpost f\u00fcr deine zuk\u00fcnftige Referenz.<\/p>\n<p><em>Welches PHP 8.1 Feature ist dein Favorit? Teile deine Gedanken mit der Community in den Kommentaren unten.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Seit dem 25. November 2021 ist PHP 8.1 endlich da, vollgepackt mit vielen spannenden Funktionen. In diesem Artikel werden wir detailliert auf die Neuerungen in PHP &#8230;<\/p>\n","protected":false},"author":117,"featured_media":43358,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[38,509],"topic":[971],"class_list":["post-43352","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-php","tag-php-8-1","topic-php-updates"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v24.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Was ist neu in PHP 8.1? Funktionen &amp; Verbesserungen - Kinsta<\/title>\n<meta name=\"description\" content=\"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1&#039;s neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Was ist neu in PHP 8.1: Funktionen, \u00c4nderungen, Verbesserungen und mehr\" \/>\n<meta property=\"og:description\" content=\"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1&#039;s neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Kinsta-Deutschland-207459890108303\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-09-06T11:51:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-27T10:42:50+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1460\" \/>\n\t<meta property=\"og:image:height\" content=\"730\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Salman Ravoof\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1&#039;s neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png\" \/>\n<meta name=\"twitter:creator\" content=\"@salmanravoof\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_DE\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Salman Ravoof\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"34\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/\"},\"author\":{\"name\":\"Salman Ravoof\",\"@id\":\"https:\/\/kinsta.com\/de\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987\"},\"headline\":\"Was ist neu in PHP 8.1: Funktionen, \u00c4nderungen, Verbesserungen und mehr\",\"datePublished\":\"2021-09-06T11:51:38+00:00\",\"dateModified\":\"2023-07-27T10:42:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/\"},\"wordCount\":7167,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/de\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png\",\"keywords\":[\"php\",\"php 8.1\"],\"articleSection\":[\"Webentwicklung\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/\",\"url\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/\",\"name\":\"Was ist neu in PHP 8.1? Funktionen & Verbesserungen - Kinsta\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png\",\"datePublished\":\"2021-09-06T11:51:38+00:00\",\"dateModified\":\"2023-07-27T10:42:50+00:00\",\"description\":\"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1's neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png\",\"contentUrl\":\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png\",\"width\":1460,\"height\":730},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PHP-Updates\",\"item\":\"https:\/\/kinsta.com\/de\/thema\/php-updates\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Was ist neu in PHP 8.1: Funktionen, \u00c4nderungen, Verbesserungen und mehr\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/de\/#website\",\"url\":\"https:\/\/kinsta.com\/de\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Schnelle, sichere und hochwertige Hosting-L\u00f6sungen\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/de\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/de\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/de\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/kinsta.com\/de\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/de\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Kinsta-Deutschland-207459890108303\/\",\"https:\/\/x.com\/Kinsta_DE\",\"https:\/\/www.instagram.com\/kinstahosting\/\",\"https:\/\/www.linkedin.com\/company\/kinsta\/\",\"https:\/\/www.pinterest.com\/kinstahosting\/\",\"https:\/\/www.youtube.com\/c\/Kinsta\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kinsta.com\/de\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987\",\"name\":\"Salman Ravoof\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/kinsta.com\/de\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g\",\"caption\":\"Salman Ravoof\"},\"description\":\"Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.\",\"sameAs\":[\"https:\/\/salmanravoof.com\",\"https:\/\/www.linkedin.com\/in\/salman-ravoof-5a749133\/\",\"https:\/\/x.com\/salmanravoof\"],\"url\":\"https:\/\/kinsta.com\/de\/blog\/author\/salmanravoof\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Was ist neu in PHP 8.1? Funktionen & Verbesserungen - Kinsta","description":"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1's neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/","og_locale":"de_DE","og_type":"article","og_title":"Was ist neu in PHP 8.1: Funktionen, \u00c4nderungen, Verbesserungen und mehr","og_description":"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1's neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!","og_url":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/Kinsta-Deutschland-207459890108303\/","article_published_time":"2021-09-06T11:51:38+00:00","article_modified_time":"2023-07-27T10:42:50+00:00","og_image":[{"width":1460,"height":730,"url":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png","type":"image\/png"}],"author":"Salman Ravoof","twitter_card":"summary_large_image","twitter_description":"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1's neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!","twitter_image":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png","twitter_creator":"@salmanravoof","twitter_site":"@Kinsta_DE","twitter_misc":{"Verfasst von":"Salman Ravoof","Gesch\u00e4tzte Lesezeit":"34\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/"},"author":{"name":"Salman Ravoof","@id":"https:\/\/kinsta.com\/de\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987"},"headline":"Was ist neu in PHP 8.1: Funktionen, \u00c4nderungen, Verbesserungen und mehr","datePublished":"2021-09-06T11:51:38+00:00","dateModified":"2023-07-27T10:42:50+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/"},"wordCount":7167,"commentCount":0,"publisher":{"@id":"https:\/\/kinsta.com\/de\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png","keywords":["php","php 8.1"],"articleSection":["Webentwicklung"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kinsta.com\/de\/blog\/php-8-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/","url":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/","name":"Was ist neu in PHP 8.1? Funktionen & Verbesserungen - Kinsta","isPartOf":{"@id":"https:\/\/kinsta.com\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png","datePublished":"2021-09-06T11:51:38+00:00","dateModified":"2023-07-27T10:42:50+00:00","description":"Entdecke, was in PHP 8.1 neu ist. Von PHP 8.1's neuen Funktionen und Leistungsverbesserungen bis hin zu \u00c4nderungen und Verwerfungen, wir decken alles ab!","breadcrumb":{"@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/de\/blog\/php-8-1\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#primaryimage","url":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png","contentUrl":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2021\/09\/php-8-1.png","width":1460,"height":730},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/de\/blog\/php-8-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/de\/"},{"@type":"ListItem","position":2,"name":"PHP-Updates","item":"https:\/\/kinsta.com\/de\/thema\/php-updates\/"},{"@type":"ListItem","position":3,"name":"Was ist neu in PHP 8.1: Funktionen, \u00c4nderungen, Verbesserungen und mehr"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/de\/#website","url":"https:\/\/kinsta.com\/de\/","name":"Kinsta\u00ae","description":"Schnelle, sichere und hochwertige Hosting-L\u00f6sungen","publisher":{"@id":"https:\/\/kinsta.com\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/de\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/kinsta.com\/de\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/de\/wp-content\/uploads\/sites\/5\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Kinsta-Deutschland-207459890108303\/","https:\/\/x.com\/Kinsta_DE","https:\/\/www.instagram.com\/kinstahosting\/","https:\/\/www.linkedin.com\/company\/kinsta\/","https:\/\/www.pinterest.com\/kinstahosting\/","https:\/\/www.youtube.com\/c\/Kinsta"]},{"@type":"Person","@id":"https:\/\/kinsta.com\/de\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987","name":"Salman Ravoof","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/kinsta.com\/de\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0c5885f75cb78473fb7408e5e49ad190?s=96&d=mm&r=g","caption":"Salman Ravoof"},"description":"Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.","sameAs":["https:\/\/salmanravoof.com","https:\/\/www.linkedin.com\/in\/salman-ravoof-5a749133\/","https:\/\/x.com\/salmanravoof"],"url":"https:\/\/kinsta.com\/de\/blog\/author\/salmanravoof\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/posts\/43352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/users\/117"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/comments?post=43352"}],"version-history":[{"count":15,"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/posts\/43352\/revisions"}],"predecessor-version":[{"id":46423,"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/posts\/43352\/revisions\/46423"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/translations\/en"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/translations\/fr"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/translations\/it"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/translations\/es"},{"embeddable":true,"hreflang":"pt","title":"Portuguese","href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/translations\/pt"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/translations\/de"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/translations\/nl"},{"href":"https:\/\/kinsta.com\/de\/wp-json\/kinsta\/v1\/posts\/43352\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/media\/43358"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/media?parent=43352"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/tags?post=43352"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/de\/wp-json\/wp\/v2\/topic?post=43352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}