{"id":40052,"date":"2021-09-16T09:28:38","date_gmt":"2021-09-16T07:28:38","guid":{"rendered":"https:\/\/kinsta.com\/?p=101567"},"modified":"2023-05-22T14:20:19","modified_gmt":"2023-05-22T12:20:19","slug":"php-8-1","status":"publish","type":"post","link":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/","title":{"rendered":"Wat is er nieuw in PHP 8.1: features, veranderingen, verbeteringen en meer"},"content":{"rendered":"<p><a href=\"https:\/\/wiki.php.net\/todo\/php81\">PHP 8.1, uitgebracht op 25 november 2021 is eindelijk hier<\/a>, boordevol verschillende opwindende features.<\/p>\n<p>In dit artikel bespreken we in detail wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen tot belangrijke wijzigingen en afschrijvingen, we behandelen ze allemaal uitvoerig.<\/p>\n<p>Let&#8217;s go!<\/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>Nieuwe features in PHP 8.1<\/h2>\n<p>Laten we beginnen met het behandelen van alle nieuwe features in PHP 8.1. En dat is nogal een lijst.<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"20\" sub-toc=\"true\"><\/kinsta-auto-toc>\n\n<h3>Pure intersection types<\/h3>\n<p>PHP 8.1 voegt ondersteuning toe voor intersection types. Deze zijn vergelijkbaar met <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-8\/#union-types-2-0\">union types<\/a> die met PHP 8.0 hun intrede deden, maar waarvoor je ze kan gebruiken is precies het tegenovergestelde.<\/p>\n<p>Om het gebruik ervan beter uit te leggen, is het goed om even kort te herhalen hoe type declarations werken in PHP.<\/p>\n<p>In wezen kan je type declarations toevoegen aan function arguments, return values en class properties. Deze toewijzing wordt type hinting genoemd en zorgt ervoor dat de waarde van het juiste type is wanneer je deze callt. In andere gevallen geeft deze meteen een <a href=\"https:\/\/www.php.net\/manual\/en\/class.typeerror.php\">TypeError<\/a>. Dit helpt je om je code beter de debuggen.<\/p>\n<p>Het declaren van een enkel type heeft echter zijn beperkingen. Union types helpen je dit obstakel te overbruggen door je toe te staan een waarde met meerdere types te declaren, en de invoer moet ten minste voldoen aan \u00e9\u00e9n van de gedeclareerde types.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/pure-intersection-types\">Het RFC<\/a> beschrijft intersection types als volgt:<\/p>\n<blockquote><p><em>Een &#8220;intersection type&#8221; vereist een waarde om te voldoen aan meerdere type constraints in plaats van aan \u00e9\u00e9n.<\/em><\/p>\n<p><em>&#8230;pure intersection types worden gespecificeerd met behulp van de syntaxis T1&#038;T2&#038;&#8230; en kunnen worden gebruikt in alle posities waar types momenteel worden geaccepteerd&#8230;<\/em><\/p><\/blockquote>\n<p>Let op het gebruik van de <code>&<\/code> (AND) operator om de intersection types te declareren. Daarentegen gebruiken we de <code>|<\/code> (OR) operator om union types te declaren.<\/p>\n<p>Het gebruik van de meeste standaardtypes in een intersection type zal resulteren in een type waaraan nooit kan worden voldaan (bijv. integer en string). Daarom kunnen intersection types alleen class types bevatten (bijv. interfaces en class names).<\/p>\n<p>Dit is voorbeeldcode van hoe je intersection types kan gebruiken:<\/p>\n<pre><code class=\"language-php\">class A {\n\u00a0 \u00a0 private Traversable&Countable $countableIterator;\n \n\u00a0 \u00a0 public function setIterator(Traversable&Countable $countableIterator): void {\n\u00a0 \u00a0 \u00a0 \u00a0 $this-&gt;countableIterator = $countableIterator;\n\u00a0 \u00a0 }\n \n\u00a0 \u00a0 public function getIterator(): Traversable&Countable {\n\u00a0 \u00a0 \u00a0 \u00a0 return $this-&gt;countableIterator;\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n<p>In de bovenstaande code hebben we een variabele <strong>countableIterator<\/strong> gedefinieerd als intersection van twee types: <strong>Traversable<\/strong> en <strong>Countable<\/strong>. In dit geval zijn de twee gedeclareerde types interfaces.<\/p>\n<p>Intersection types voldoen ook aan de standaard PHP regels met betrekking tot variance die al worden gebruikt voor type checking en inheritance. Maar er zijn twee aanvullende regels met betrekking tot de interactie tussen intersection types en subtyping. Je kan in de RFC meer lezen over <a href=\"https:\/\/wiki.php.net\/rfc\/pure-intersection-types#variance\">de variance regels rond intersection types<\/a>.<\/p>\n<p>In sommige programmeertalen kan je Union Types en Intersection Types combineren in dezelfde declaration. Maar PHP 8.1 verbiedt dit. Daarom wordt de implementatie ervan &#8220;pure&#8221; intersection types genoemd. De RFC vermeldt echter wel dat dit iets is waar ze in de toekomst nog naar willen kijken.<\/p>\n<h3>Enums<\/h3>\n<p>PHP 8.1 voegt eindelijk ondersteuning toe voor enums (ook wel enumerations of enumerated types genoemd). Ze zijn een user-defined data type dat bestaat uit een reeks mogelijke waarden.<\/p>\n<p>De meest voorkomende voorbeelden van enums in programmeertalen is het <strong>boolean<\/strong> type met <code>true<\/code> en <code>false<\/code> als twee mogelijke waarden. Het is inmiddels zo gewoon dat het in veel <a href=\"https:\/\/kinsta.com\/nl\/blog\/beste-programmeertaal-om-te-leren\/\">moderne programmeertalen<\/a> is ingebakken.<\/p>\n<p>Volgens <a href=\"https:\/\/wiki.php.net\/rfc\/enumerations\">de RFC<\/a> zijn enums in PHP in eerste instantie beperkt tot unit enumerations:<\/p>\n<blockquote><p><em>De scope van deze RFC is beperkt tot &#8220;unit enumerations&#8221;, dat wil zeggen enums die zelf een waarde zijn, in plaats van eenvoudigweg een fancy syntax voor een primitive constant, en die geen aanvullende bijbehorende informatie bevatten. Deze mogelijkheid biedt sterk uitgebreide ondersteuning voor gegevensmodellering, custom type definitions en monad-style behavior. Enums maken de modelleringstechniek mogelijk van &#8220;ongeldige toestanden onrepresenteerbaar maken&#8221;, wat leidt tot robuustere code met minder noodzaak aan veel testen.<\/em><\/p><\/blockquote>\n<p>Het PHP team heeft veel talen bestudeerd die al enumerations ondersteunen. Uit <a href=\"https:\/\/github.com\/Crell\/enum-comparison\">hun onderzoek<\/a> bleek dat je enums in drie algemene groepen kunt indelen: Fancy Constants, Fancy Objects en volledige Algebraic Data Types (ADT&#8217;s). Het is interessant om te lezen!<\/p>\n<p>PHP implementeert &#8220;Fancy Objects&#8221; enums, met plannen om het in de toekomst uit te breiden naar volledige ADT&#8217;s. Het is conceptueel en semantisch gemodelleerd naar de enumerated types in Swift, Rust en Kotlin, hoewel het niet direct op een van hen is gemodelleerd.<\/p>\n<p>De RFC gebruikt de welbekende analogie van kleuren in een pak kaarten om uit te leggen hoe het zal werken:<\/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 definieert de enum <strong>Suit<\/strong> vier mogelijke waarden: <strong>Hearts<\/strong>, <strong>Diamonds<\/strong>, <strong>Clubs<\/strong> en <strong>Spades<\/strong>. Je kan deze waarden rechtstreeks benaderen met behulp van de syntax: <code>Suit::Hearts<\/code>, <code>Suit::Diamonds<\/code>, <code>Suit::Clubs<\/code> en <code>Suit::Spades<\/code>.<\/p>\n<p>Dit gebruik lijkt misschien bekend, omdat enums bovenop classes en objects worden gebouwd. Ze gedragen op dezelfde manier en hebben bijna dezelfde vereisten. Enums delen dezelfde namespaces als classes, interfaces en traits.<\/p>\n<p>De hierboven genoemde enums worden <strong>Pure Enums<\/strong> genoemd.<\/p>\n<p>Je kan ook <strong>Backed Enums<\/strong> defini\u00ebren als je aan alle gevallen een scalar equivalent value wil geven aan cases. Backed enums kunnen echter maar \u00e9\u00e9n type hebben, ofwel <code>int<\/code> of <code>string<\/code> (nooit beide).<\/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>Bovendien moeten alle verschillende cases van een backed enum een unieke waarde hebben. En je kan nooit pure en backed enums mengen.<\/p>\n<p>De RFC gaat dieper in op enum methods, static methods, constants, constant expressions en nog veel meer. Het valt buiten de scope van dit artikel om ze allemaal te behandelen. Je kan de documentatie raadplegen om vertrouwd te raken met alles wat ermee te maken heeft.<\/p>\n<h3>Het <code>never<\/code> return type<\/h3>\n<p>PHP 8.1 voegt een nieuwe return type hint toe met de naam <code>never<\/code>. Deze is superhandig te gebruiken in functions die altijd <code>throw<\/code> of <code>exit<\/code> hebben.<\/p>\n<p>Volgens <a href=\"https:\/\/wiki.php.net\/rfc\/noreturn_type\">de RFC<\/a> zijn URL redirect functions die altijd <code>exit<\/code> (expliciet of impliciet) teruggeven, een goed voorbeeld van het gebruik ervan.<\/p>\n<pre><code class=\"language-php\">function redirect(string $uri): never {\n\u00a0 \u00a0 header('Location: ' . $uri);\n\u00a0 \u00a0 exit();\n}\n \nfunction redirectToLoginPage(): never {\n\u00a0 \u00a0 redirect('\/login');\n}<\/code><\/pre>\n<p>Een met <code>never<\/code> gedeclareerde function moet aan de volgende drie voorwaarden voldoen:<\/p>\n<ul>\n<li>Het mag het <code>return<\/code> statement niet expliciet hebben gedefinieerd.<\/li>\n<li>Het mag het <code>return<\/code> statement niet impliciet hebben gedefinieerd (bijv <strong>if-else<\/strong> statements)<strong>.<\/strong><\/li>\n<li>Het moet de uitvoering be\u00ebindigen met een <code>exit<\/code> statement (expliciet of impliciet).<\/li>\n<\/ul>\n<p>Het <a href=\"https:\/\/kinsta.com\/nl\/docs\/wordpress-hosting\/redirect-regels\/\">URL redirection<\/a> voorbeeld hierboven laat zowel expliciet als impliciet gebruik van het <code>never<\/code> return type zien.<\/p>\n<p>Het <code>never<\/code> return type heeft veel overeenkomsten met het <code>void<\/code> return type. Ze zorgen er allebei voor dat de function of method geen waarde teruggeeft. Het verschilt echter door strengere regels op te leggen. Een <code>void<\/code> gedeclareerde function kan nog steeds <code>return<\/code> zonder een expliciete waarde, maar hetzelfde geldt niet voor een <code>never<\/code> gedeclareerde function.<\/p>\n<p>Als vuistregel: gebruik <code>void<\/code> wanneer je verwacht dat PHP blijft uitvoeren naar de function call. Kies voor <code>never<\/code> wanneer je het tegenovergestelde wilt.<\/p>\n<p>Bovendien wordt <code>never<\/code> gedefinieerd als een &#8220;bottom&#8221; type. Daarom kan elke class method die als <code>never<\/code> wordt gedeclared nooit zijn return type in iets anders veranderen. Je kan echter een als <code>void<\/code> gedeclareerde method uitbreiden met een als <code>never<\/code> gedeclareerde method.<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-info\">\n            <h3>Info<\/h3>\n        <p>De originele RFC meldt het <code>never<\/code> return type als <code>noreturn<\/code>, wat een return type was dat al werd ondersteund door twee statische PHP analysetools, namelijk Psalm en PHPStan. Omdat dit werd voorgesteld door de auteurs van Psalm en PHPStan zelf, behielden ze de terminologie ervan. Vanwege de naamgevingsconventies hield het PHP team echter een peiling voor <code>noreturn<\/code> vs <code>never<\/code>, waarbij <code>never<\/code> als winnaar uit de bus kwam. Vervang daarom voor PHP 8.1 versies <code>noreturn<\/code> altijd door <code>never<\/code>.<\/p>\n<\/aside>\n\n<h3>Fibers<\/h3>\n<p>Historisch gezien is PHP code bijna altijd synchrone code geweest. De uitvoering van de code stopt totdat het resultaat is geretourneerd, zelfs voor I\/O operations. Je kan je voorstellen waarom dit proces de uitvoering van de code langzamer maakt.<\/p>\n<p>Er zijn meerdere oplossingen van derden om dit obstakel te overwinnen, zodat developers PHP code asynchroon kunnen schrijven, met name voor gelijktijdige I\/O bewerkingen. Sommige populaire voorbeelden zijn <a href=\"https:\/\/amphp.org\/\">amphp<\/a>, <a href=\"https:\/\/reactphp.org\/\">ReactPHP<\/a> en <a href=\"https:\/\/guzzlephp.org\/\">Guzzle<\/a>.<\/p>\n<p>Er is echter geen standaardmanier om dergelijke instanties in PHP af te handelen. Bovendien leidt het behandelen van synchrone en asynchrone code binnen dezelfde call stack <a href=\"https:\/\/journal.stuffwithstuff.com\/2015\/02\/01\/what-color-is-your-function\/\">tot andere problemen<\/a>.<\/p>\n<p>Fibers zijn PHP&#8217;s manier om parallellisme af te handelen via virtuele threads (of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Green_threads\">groene threads<\/a>). Het probeert het verschil tussen synchrone en asynchrone code te elimineren door PHP functions te onderbreken zonder de hele call stack te be\u00efnvloeden.<\/p>\n<p>Dit is wat <a href=\"https:\/\/wiki.php.net\/rfc\/fibers\">de RFC<\/a> <em>belooft<\/em>:<\/p>\n<ul>\n<li>Ondersteuning voor Fibers toegevoegd aan PHP.<\/li>\n<li>Introductie van een nieuwe Fiber class en de bijbehorende reflection class ReflectionFiber.<\/li>\n<li>Het toevoegen van exception classes FiberError en FiberExit om fouten te representen.<\/li>\n<li>Fibers zorgen voor transparante non-blocking I\/O implementaties van bestaande interfaces (PSR-7, Doctrine ORM, etc.). Dat komt omdat het tijdelijke placeholder (promise) object wordt ge\u00eblimineerd. In plaats daarvan kunnen functions het I\/O result type declaren in plaats van een placeholder object dat geen resolution type kan specificeren omdat PHP geen generics ondersteunt.<\/li>\n<\/ul>\n<p>Je kan Fibers gebruiken om full-stack, interruptible PHP functions te ontwikkelen, die je vervolgens kan gebruiken om co\u00f6peratieve multitasking te implementeren in PHP. Omdat Fibers de hele <a href=\"https:\/\/kinsta.com\/nl\/docs\/wordpress-hosting\/wordpress-monitoring\/apm-tool\/#stack-trace\">execution stack<\/a> pauzeren, kan je erop vertrouwen dat dit de rest van je code niet schaadt.<\/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=\"Grafiek die de executionflow van PHP code met Fibers illustreert \" width=\"1100\" height=\"894\"><\/a><figcaption id=\"caption-attachment-110018\" class=\"wp-caption-text\">Grafiek die de executionflow van PHP code met Fibers illustreert (Bron: <a href=\"https:\/\/www.php.net\/\">PHP.net<\/a>).<\/figcaption><\/figure>\n<p>Om het gebruik van Fibers te illustreren, gebruikt de RFC dit simpele voorbeeld:<\/p>\n<pre><code class=\"language-php\">$fiber = new Fiber(function (): void {\n\u00a0 \u00a0 $value = Fiber::suspend('fiber');\n\u00a0 \u00a0 echo \"Value used to resume fiber: \", $value, \"\\n\";\n});\n \n$value = $fiber-&gt;start();\n \necho \"Value from fiber suspending: \", $value, \"\\n\";\n \n$fiber-&gt;resume('test');<\/code><\/pre>\n<p>In bovenstaande code maak je een &#8220;fiber&#8221; die je onmiddellijk suspendt met de string <code>fiber<\/code>. Het <code>echo<\/code> statement dient als een visuele cue voor de hervatting van de fiber.<\/p>\n<p>Je kan deze string value uit de call ophalen naar <code>$fiber-&gt;start()<\/code>.<\/p>\n<p>Vervolgens hervat je de fiber met de string &#8220;test&#8221; die wordt geretourneerd door de call naar <code>Fiber::suspend()<\/code>. De volledige uitvoering van de code resulteert in de volgende output:<\/p>\n<pre><code class=\"language-php\">Value from fiber suspending: fiber\nValue used to resume fiber: test<\/code><\/pre>\n<p>Dit is een simpel schoolvoorbeeld van de werking van PHP Fibers. <a href=\"https:\/\/github.com\/nox7\/async-php-8-io-http\">Dit is nog een ander Fibers voorbeeld<\/a> van het uitvoeren van zeven asynchrone GET verzoeken.<\/p>\n<p>Dat gezegd hebbende, de meeste PHP developers zullen nooit rechtstreeks te maken krijgen met Fibers. Dit is ook wat de RFC suggereert:<\/p>\n<blockquote><p><em>Fibers zijn een geavanceerde features die de meeste gebruikers niet rechtstreeks zullen gebruiken. Deze feature is voornamelijk bedoeld voor auteurs van libraries and frameworks om een event loop en asynchrone programming API te bieden. Met Fibers kan je naadloos asynchrone code-uitvoering in synchrone code integreren zonder dat het nodig is om de call stack van de applicatie te wijzigen of boilerplate code te gebruiken.<\/em><\/p>\n<p><em>De Fiber API zal naar verwachting niet rechtstreeks worden gebruikt in code op applicatieniveau. Met Fibers bieden we een simpele, low-level flow-control API om abstracties op hoger niveau te cre\u00ebren die vervolgens worden gebruikt in applicatiecode.<\/em><\/p><\/blockquote>\n<p>Gezien de prestatievoordelen kan je verwachten dat vooral PHP libraries en frameworks profiteren van deze nieuwe feature. Het zal interessant zijn om te zien hoe ze Fibers in hun ecosysteem implementeren.<\/p>\n<h3>Nieuwe <code>readonly<\/code> properties<\/h3>\n<p>PHP 8.1 voegt ondersteuning toe voor <code>readonly<\/code> properties. Ze kunnen slechts een keer worden ge\u00efnitialiseerd vanuit de scope waarin ze zijn gedeclared. Zodra ze eenmaal ge\u00efnitialiseerd zijn, kan de waarde nooit meer gewijzigd worden. Als je dit toch doet, wordt een <strong>Error<\/strong> exception gegenereerd.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/readonly_properties_v2\">De RFC<\/a> luidt:<\/p>\n<blockquote><p><em>Een <strong>readonly<\/strong> property kan slechts \u00e9\u00e9n keer worden ge\u00efnitialiseerd, en alleen vanuit de scope waarin het is gedeclared. Een andere assignment of wijziging van de property zal resulteren in een Error exception.<\/em><\/p><\/blockquote>\n<p>Hier volgt een voorbeeld van hoe je het kan gebruiken:<\/p>\n<pre><code class=\"language-php\">class Test {\n\u00a0 \u00a0 public readonly string $kinsta;\n \n\u00a0 \u00a0 public function __construct(string $kinsta) {\n\u00a0 \u00a0 \u00a0 \u00a0 \/\/ Legal initialization.\n\u00a0 \u00a0 \u00a0 \u00a0 $this-&gt;kinsta = $kinsta;\n\u00a0 \u00a0 }\n}<\/code><\/pre>\n<p>Zodra hij ge\u00efnitialiseerd is, is er geen weg meer terug. Nu deze feature is ingebakken in PHP, wordt het gebruik aanzienlijk verminderd van boilerplate-code, die vaak wordt gebruikt om deze feature in te schakelen.<\/p>\n<p>De <code>readonly<\/code> property biedt een sterke &#8220;onveranderlijkheidsgarantie&#8221;, zowel binnen als buiten de class. Het maakt niet uit welke code ertussen wordt uitgevoerd. Het callen van een <code>readonly<\/code> property zorgt altijd dat dezelfde waarde wordt geretourneerd.<\/p>\n<p>Het gebruik van de <code>readonly<\/code> property is echter niet voor elke use-case ideaal. Je kan hem alleen gebruiken naast een <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-7-4\/#typed-properties\">typed property<\/a>, omdat declarations zonder een type impliciet <code>null<\/code> zijn en niet <code>readonly<\/code> kunnen zijn.<\/p>\n<p>Bovendien maakt het instellen van een <code>readonly<\/code> property objecten niet meteen onveranderlijk. De <code>readonly<\/code> property zal hetzelfde object bevatten, maar het object zelf kan natuurlijk wel veranderen.<\/p>\n<p>Een ander klein probleem met deze property is dat je het niet kan klonen. Er is echter al een <a href=\"https:\/\/stitcher.io\/blog\/cloning-readonly-properties-in-php-81\">work-around voor deze specifieke use-case<\/a>. Kijk er even naar als dit nodig is.<\/p>\n<h3><code>final<\/code> class constants defini\u00ebren<\/h3>\n<p>Vanaf PHP 8.0 kun je class constants overschrijven met de bijbehorende child classes. Dit komt door de manier waarop inheritance werkt in PHP.<\/p>\n<p>Hier is een voorbeeld van hoe je de waarde van een eerder gedeclareerde constant kan overschrijven:<\/p>\n<pre><code class=\"language-php\">class Moo\n{\n\u00a0 \u00a0 public const M = \"moo\";\n}\n \nclass Meow extends Moo\n{\n\u00a0 \u00a0 public const M = \"meow\";\n}\u00a0\u00a0<\/code><\/pre>\n<p>Als de koeien strenger willen zijn met hoe de katten zich gedroegen (tenminste wat constants betreft), kunnen ze dat doen met de nieuwe <code>final<\/code> modifier van PHP 8.1.<\/p>\n<p>Zodra je een constant declareert als <code>final<\/code>, dan betekent het simpel dat.<\/p>\n<pre><code class=\"language-php\">class Moo\n{\n\u00a0 \u00a0 final public const M = \"moo\";\n}\n \nclass Meow extends Moo\n{\n\u00a0 \u00a0 public const M = \"meow\";\n}\n \n\/\/ Fatal error: Meow::M cannot override final constant Moo::M<\/code><\/pre>\n<p>Je kan meer lezen in de PHP RFC van de <a href=\"https:\/\/wiki.php.net\/rfc\/final_class_const\">final class constants<\/a>.<\/p>\n<h3>Nieuwe <code>fsync()<\/code> en <code>fdatasync()<\/code> functions<\/h3>\n<p>PHP 8.1 voegt twee nieuwe file system functions toe genaamd <code>fsync()<\/code> en <code>fdatasync()<\/code>. Ze zullen bekend voorkomen met mensen die gewend zijn <a href=\"https:\/\/linux.die.net\/man\/2\/fsync\">aan Linux functions met dezelfde naam<\/a>. Dat komt omdat ze gerelateerd zijn, maar in dit geval ge\u00efmplementeerd voor PHP.<\/p>\n<p>Deze toevoeging heeft al lang op zich laten wachten. PHP is een van de weinige grote programmeertalen die <a href=\"https:\/\/wiki.php.net\/rfc\/fsync_function\">fsync() en fdatasync<\/a> nog steeds niet hebben ge\u00efmplementeerd &#8211; dat wil zeggen <a href=\"https:\/\/wiki.php.net\/rfc\/fsync_function\">tot PHP 8.1<\/a>.<\/p>\n<p>De <code>fsync()<\/code> function is te vergelijken met de bestaande <code>fflush()<\/code> function, maar verschilt op \u00e9\u00e9n manier aanzienlijk. Waar <code>fflush()<\/code> de interne buffers van de applicatie naar de OS flusht, gaat <code>fsync()<\/code> nog een stapje verder en zorgt ervoor dat de interne buffers naar de fysieke <a href=\"https:\/\/kinsta.com\/nl\/blog\/wat-is-ssd\/\">opslag<\/a> worden geflusht. Dat zorgt voor een volledige en persistente schrijfbewerking, zodat je zelfs na een applicatie- of systeemcrash gegevens kan retrieven.<\/p>\n<p>Hier is een voorbeeld van hoe je het kunt gebruiken.<\/p>\n<pre><code class=\"language-php\">$doc = 'kinsta.txt';\n\n$kin = fopen($doc, 'ki');\nfwrite($kin, 'doc info');\nfwrite($kin, \"\\r\\n\");\nfwrite($kin, 'more info');\n\nfsync($kin);\nfclose($kin);<\/code><\/pre>\n<p>Het toevoegen van de <code>fsync()<\/code> call aan het einde zorgt ervoor dat alle gegevens die zich in de interne buffer van PHP of het besturingssysteem bevinden, naar de opslag worden geschreven. Alle andere code-uitvoeringen zijn tot die tijd geblokkeerd.<\/p>\n<p>De gerelateerde function is <code>fdatasync()<\/code>. Gebruik deze om data te syncen, maar niet per se metadata. Voor data waarvan de metadata niet essentieel zijn, maakt deze function call het schrijfproces een beetje sneller.<\/p>\n<p>Houd er echter rekening mee dat PHP 8.1 <code>fdatasync()<\/code> nog niet volledig ondersteunt op Windows. Het fungeert alleen als een alias van <code>fsync()<\/code>. Op POSIX is <code>fdatasync()<\/code>\u00a0correct ge\u00efmplementeerd.<\/p>\n<h3>Nieuwe <code>array_is_list()<\/code> function<\/h3>\n<p>PHP arrays kunnen zowel integer als string keys bevatten. Dit betekent dat je ze voor verschillende dingen, waaronder lijsten, hashtabellen, woordenboeken, collecties, stacks, queues en nog veel meer. Je kan zelfs arrays binnen arrays hebben, waardoor multidimensionale arrays worden gemaakt.<\/p>\n<p>Je kan effici\u00ebnt checken of een bepaald item een array is, maar het is niet zo eenvoudig om te controleren of het missende array offsets, out-of-order keys, enz. heeft. Kortom, je kan niet snel checken of een array een lijst is.<\/p>\n<p>De <a href=\"https:\/\/wiki.php.net\/rfc\/is_list\">array_is_list() function<\/a> checkt of de keys van een array in sequenti\u00eble volgorde staan, beginnend bij <code>0<\/code> en zonder gaps. Als aan alle voorwaarden is voldaan, wordt <code>true<\/code> geretourneerd. Standaard retourneert het ook <code>true<\/code> voor lege arrays.<\/p>\n<p>Hier zijn een paar voorbeelden van het gebruik ervan waarin zowel aan <code>true<\/code> als <code>false<\/code> voorwaarden wordt voldaan:<\/p>\n<pre><code class=\"language-php\">\/\/ true array_is_list() examples\narray_is_list([]); \/\/ true\narray_is_list([1, 2, 3]); \/\/ true\narray_is_list(['cats', 2, 3]); \/\/ true\narray_is_list(['cats', 'dogs']); \/\/ true\narray_is_list([0 =&gt; 'cats', 'dogs']); \/\/ true\narray_is_list([0 =&gt; 'cats', 1 =&gt; 'dogs']); \/\/ true \n\n\/\/ false array_is_list() examples \narray_is_list([1 =&gt; 'cats', 'dogs']); \/\/ as first key isn't 0\narray_is_list([1 =&gt; 'cats', 0 =&gt; 'dogs']); \/\/ keys are out of order\narray_is_list([0 =&gt; 'cats', 'bark' =&gt; 'dogs']); \/\/ non-integer keys\narray_is_list([0 =&gt; 'cats', 2 =&gt; 'dogs']); \/\/ gap in between keys <\/code><\/pre>\n<p>Een PHP array list met out-of-order keys is <a href=\"https:\/\/kinsta.com\/nl\/blog\/wordpress-beveiliging\/#2-use-latest-php-version\">een potenti\u00eble bron van bugs<\/a>. Het gebruik van deze function om een strikte naleving van <strong>list<\/strong> vereisten af te dwingen voordat verder wordt gegaan met het uitvoeren van de code, is een geweldige aanvulling op PHP.<\/p>\n<h3>Nieuwe Sodium XchaCha20 functions<\/h3>\n<p>Sodium is een moderne, gebruiksvriendelijke cryptografische bibliotheek voor encryptie, decryptie, hashing van <a href=\"https:\/\/kinsta.com\/nl\/blog\/wachtwoordmanagers\/\">wachtwoorden<\/a>, handtekeningen en meer. De <a href=\"https:\/\/pecl.php.net\/package\/libsodium\">PECL libsodium package<\/a> voegt een wrapper toe voor Sodium zodat PHP developers het kunnen gebruiken.<\/p>\n<p>Zelfs <a href=\"https:\/\/doc.libsodium.org\/libsodium_users\">toonaangevende technologiebedrijven<\/a> als Facebook, Discord, Malwarebytes en Valve gebruiken libsodium om hun gebruikers te beveiligen met snelle en veilige verbindingen.<\/p>\n<p>libsodium ondersteunt het <a href=\"https:\/\/www.cryptopp.com\/wiki\/XChaCha20\">XChaCha20 encryptie-algoritme<\/a> om data te encrypten en decrypten, met name voor stream-encryptie. Daarnaast ondersteunt de PECL libsodium extensie XChaCha20 al0 al, maar alleen met Poly1305 bericht authenticatiecode.<\/p>\n<p>Veel PHP applicaties gebruiken XChaCha20 rechtstreeks voor stream-encryptie. Om het je gemakkelijker te maken heb je vanaf PHP 8.1 drie nieuwe functions om data te encrypten of decrypten met XchaCha zonder dat er authenticatie nodig is. Deze modus wordt &#8220;detached mode&#8221; genoemd.<\/p>\n<p>De nieuw ge\u00efntroduceerde XChaCha20 functions zijn:<\/p>\n<ul>\n<li><code>sodium_crypto_stream_xchacha20_keygen<\/code>: Retourneert een veilige willekeurige key voor gebruik met natrium_crypto_stream_xchacha20.<\/li>\n<li><code>sodium_crypto_stream_xchacha20<\/code>: Breidt de key en nonce uit tot een keystream van pseudo-willekeurige bytes.<\/li>\n<li><code>sodium_crypto_stream_xchacha20_xor<\/code>: versleutelt een bericht met een nonce en een secret key (geen authenticatie).<\/li>\n<\/ul>\n<p>Daarnaast zijn er twee nieuwe PHP constants gedefinieerd in de globale namespace:<\/p>\n<ul>\n<li><code>SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES<\/code> (toegewezen <strong>32<\/strong>)<\/li>\n<li><code>SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES<\/code> (toegewezen <strong>24<\/strong>)<\/li>\n<\/ul>\n<p>Gebruik het echter met de nodige voorzichtigheid. Omdat het zonder authenticatie is, is deze decoderingsbewerking kwetsbaar voor veelvoorkomende ciphertext aanvallen.<\/p>\n<p>Je kan meer lezen over het gebruik en de vereisten op de <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6868\">Github pagina<\/a>.<\/p>\n<h3>Nieuwe IntlDatePatternGenerator class<\/h3>\n<p>De onderliggende ICU library van PHP ondersteunt het maken van <a href=\"https:\/\/kinsta.com\/blog\/wordpress-calendar-plugin\/\">gelokaliseerde datum- en tijdnotaties<\/a>, maar is niet volledig aanpasbaar.<\/p>\n<p>Als je in versies tot PHP 8.0 bijvoorbeeld landspecifieke gegevens- en tijdnotaties wilt maken, kan je de <a href=\"https:\/\/www.php.net\/manual\/en\/class.intldateformatter.php\">vooraf gedefinieerde IntlDateFormatter constant<\/a> gebruiken om dit op 6 manieren te doen:<\/p>\n<ul>\n<li><strong><code>IntlDateFormatter::LONG<\/code>: <\/strong>langer, zoals\u00a0November 10<strong>, 2017<\/strong>\u00a0of\u00a0<strong>11:22:33pm<\/strong><\/li>\n<li><strong><code>IntlDateFormatter::MEDIUM<\/code>:<\/strong> Iets korter, zoals November 10<strong>, 2017<\/strong><\/li>\n<li><strong><code>IntlDateFormatter::SHORT<\/code>:<\/strong> Alleen nummers zoals\u00a0<strong>10\/11\/17<\/strong>\u00a0of\u00a0<strong>11:22pm<\/strong><\/li>\n<\/ul>\n<p>Elk van deze heeft ook zijn eigen <code>RELATIVE_<\/code> variants, die de datumnotatie binnen een beperkt bereik voor of na de huidige datum instellen. In PHP zijn de waarden <strong>yesterday<\/strong>, <strong>today<\/strong> en <strong>tomorrow<\/strong>.<\/p>\n<p>Stel dat je de lange versie voor het jaar en de korte versie voor de maand wil gebruiken, zoals <strong>10\/11\/2017<\/strong>. In PHP 8.0 en eerdere versies kan dit niet.<\/p>\n<p>Vanaf PHP 8.1+ kan je opgeven welke indeling je wil gebruiken voor de datum, maand en tijd met de nieuwe class <strong>IntlDatePatternGenerator<\/strong>. De exacte volgorde van deze componenten kan je aan de formatter overlaten.<\/p>\n<p>Houd er rekening mee dat hoewel deze class alleen het woord <strong>Date<\/strong> bevat, het consistent is met ICU&#8217;s <strong>DateTimePatternGenerator<\/strong>. Dit bekent dat je het ook kan gebruiken om flexibele tijdformats te maken. Om de naamgeving te vereenvoudigen, heeft het PHP team gekozen voor de kortere term <strong>IntlDatePatternGenerator<\/strong>.<\/p>\n<p>Hier volgt een voorbeeld rechtstreeks uit <a href=\"https:\/\/wiki.php.net\/rfc\/intldatetimepatterngenerator\">de 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 = new \\IntlDatePatternGenerator(\"de_DE\");\n$pattern = $dtpg-&gt;getBestPattern($skeleton);\necho \"de: \", \\IntlDateFormatter::formatObject($today, $pattern, \"de_DE\"), \"\\n\";\n \n$dtpg = new \\IntlDatePatternGenerator(\"en_US\");\n$pattern = $dtpg-&gt;getBestPattern($skeleton), \"\\n\";\necho \"en: \", \\IntlDateFormatter::formatObject($today, $pattern, \"en_US\"), \"\\n\";\n \n\/*\nde: 24.04.2021\nen: 04\/24\/2021\n*\/<\/code><\/pre>\n<p>In de bovenstaande code definieert de <strong>skeleton<\/strong> variabele de specifieke datum- of tijdnotaties die moeten worden gebruikt. De formatter handelt echter de volgorde van het eindresultaat af.<\/p>\n<h3>Ondersteuning voor de AVIF afbeeldingsindeling<\/h3>\n<p>AVIF, of AV1 Image File Format, is een relatief nieuw royaltyvrije <a href=\"https:\/\/kinsta.com\/nl\/blog\/bestandstypen-afbeeldingen\/\">afbeeldingsindeling<\/a> op basis van de AV1 videocoderingsindeling. Naast het bieden van hogere compressie (en dus kleinere bestandsgroottes) ondersteunt het ook verschillende features als transparantie, HDR en meer.<\/p>\n<p>De AVIF indeling was pas <a href=\"https:\/\/aomediacodec.github.io\/av1-avif\/\">recentelijk gestandaardiseerd<\/a> (8 juni 2021). Dit maakte de weg vrij voor browsers als Chrome 85+ en Firefox 86+ om ook AVIF afbeeldingen te ondersteunen.<\/p>\n<p>PHP 8.1&#8217;s afbeeldingsverwerking en GD extensie voegt ondersteuning toe voor AVIF afbeeldingen.<\/p>\n<p>Om deze functionaliteit op te nemen, moet je wel de GD extensie compileren met AVIF ondersteuning. Je kan dit doen door de onderstaande opdrachten uit te voeren.<\/p>\n<p>Voor Debian\/Ubuntu:<\/p>\n<pre><code class=\"language-bash\">apt install libavif-dev<\/code><\/pre>\n<p>Voor Fedora\/RHEL:<\/p>\n<pre><code class=\"language-bash\">dnf install libavif-devel<\/code><\/pre>\n<p>Hiermee installeer je de nieuwste dependencies. Vervolgens kan je de AVIF ondersteuning compileren door de <code>--with-avif<\/code> flag te runnen met het <code>.\/configure<\/code> script.<\/p>\n<pre><code class=\"language-bash\">.\/buildconf --force\n.\/configure --enable-gd --with-avif<\/code><\/pre>\n<p>Als je een volledig nieuwe omgeving aan het opbouwen bent, kan je hier ook andere PHP extensies inschakelen.<\/p>\n<p>Eenmaal ge\u00efnstalleerd kan je testen of AVIF ondersteuning is ingeschakeld door de volgende opdracht in je PHP terminal uit te voeren:<\/p>\n<pre><code class=\"language-bash\">php -i | grep AVIF<\/code><\/pre>\n<p>Als je AVIF correct hebt ge\u00efnstalleerd, zie je het volgende resultaat:<\/p>\n<pre><code class=\"language-bash\">AVIF Support =&gt; enabled<\/code><\/pre>\n<p>Je kan ook de <code>gd_info()<\/code> call gebruiken om een lijst met GD features op te halen, inclusief of <strong>AVIF Support<\/strong> functionaliteit is ingeschakeld.<\/p>\n<p>Deze bijgewerkte PHP 8.1 GD extensie voegt ook twee nieuwe functions toe voor het werken met AVIF afbeeldingen: <code>imagecreatefromavif<\/code> en <code>imageavif<\/code>. Ze werken op dezelfde manier als hun JPEG en PNG tegenhangers.<\/p>\n<p>De <code>imagecreatefromavif<\/code> function retourneert een GdImage instance van een bepaalde AVIF afbeelding. Je kan deze instance vervolgens gebruiken om de afbeelding te bewerken of te converteren.<\/p>\n<p>De andere <code>imageavif<\/code> function heeft als output het AVIF afbeeldingsbestand. Je kan het bijvoorbeeld gebruiken om een JPEG naar AVIF te converteren:<\/p>\n<pre><code class=\"language-php\">$image = imagecreatefromjpeg('image.jpeg');\nimageavif($image, 'image.avif');<\/code><\/pre>\n<p>Je kan meer lezen over deze nieuwe feature op de <a href=\"https:\/\/github.com\/php\/php-src\/pull\/7026\">GitHub pagina<\/a>.<\/p>\n<h3>Nieuwe <code>$_FILES<\/code> full_path key voor directory uploads<\/h3>\n<p>PHP bevat een groot aantal vooraf gedefinieerde variabelen om verschillende dingen te tracken. Een daarvan is de <a href=\"https:\/\/www.php.net\/manual\/en\/reserved.variables.files.php\">$_FILES variabele<\/a> die een associatieve array van items bevat die zijn ge\u00fcpload via de HTTP POST methode.<\/p>\n<p>De meeste moderne browsers ondersteunen <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/input\/file#htmlattrdefwebkitdirectory_non-standard_inline\">het uploaden van een volledige map<\/a> met <a href=\"https:\/\/kinsta.com\/nl\/blog\/zo-upload-je-een-html-bestand-naar-wordpress\/\">HTML bestandsupload<\/a> velden. Zelfs versies van voor PHP 8.1 ondersteunen deze functionaliteit, maar wel met een grote kanttekening. Je kan namelijk geen map uploaden met dezelfde mappenstructuur of relatieve paden, omdat PHP deze informatie niet doorgaf aan de <code>$_FILES<\/code> array.<\/p>\n<p>Dit verandert in PHP 8.1 met de toevoeging van een nieuwe key genaamd <code>full_path<\/code> aan de <code>$_FILES<\/code> array. Met behulp van deze nieuwe data kan je nieuwe relatieve paden opslaan of de exacte directorystructuur op de server dupliceren.<\/p>\n<p>Je kan deze informatie testen door de <code>$FILES<\/code> array te outputten met behulp van de opdracht <code>var_dump($_FILES);<\/code>.<\/p>\n<p>Ga echter voorzichtig te werk als je deze nieuwe feature gebruikt. Zorg dat je beschermd bent tegen de <a href=\"https:\/\/php.watch\/versions\/8.1\/%24_FILES-full-path#security-hardening\">standaard aanvallen bij het uploaden van bestanden<\/a>.<\/p>\n<h3>Ondersteuning array unpacking voor string-keyed arrays<\/h3>\n<p>PHP 7.4 voegde <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-7-4\/#array-spread-operator\">ondersteuning toe voor array unpacking<\/a> met de array spread operator (<strong>&#8230;<\/strong>). Deze fungeert als een sneller alternatief dan wanner je de <code>array_merge<\/code> function gebruikt. Deze feature was echter beperkt tot numeric-keyed arrays omdat het unpacken van stringed-key arrays voor conflicten zorgde bij het mergen van arrays met dubbele keys.<\/p>\n<p>PHP 8 voegde echter <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-8\/#named-arguments\">ondersteuning toe voor named arguments<\/a> waardoor deze beperking is opgeheven. Daarom ondersteunt array unpacking nu ook string-keyed arrays met dezelfde syntax:<\/p>\n<pre><code class=\"language-php\">$array = [...$array1, ...$array2];<\/code><\/pre>\n<p>Dit <a href=\"https:\/\/wiki.php.net\/rfc\/array_unpacking_string_keys\">RFC voorbeeld<\/a> illustreert hoe het samenvoegen van arrays met dubele string keys wordt afgehandeld 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 verschijnt de string key &#8220;a&#8221; driemaal voordat deze wordt gemerged via array unpacking. Maar alleen de laatste waarde die hoort bij <code>$array2<\/code> wint.<\/p>\n<h3>Expliciete notatie van octale cijfers<\/h3>\n<p>PHP ondersteunt verschillende cijfersystemen, waaronder decimaal (base-10), binair (base-2), octaal (base-8) en hex (base-16). Het decimale cijfersysteem is de standaard.<\/p>\n<p>Als je een ander cijfersysteem wil gebruiken, moet je een prefix toevoegen aan elk nummer met een standaard prefix:<\/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>Je kan zien hoe het prefix van het octale cijfersysteem verschilt van de rest. Om deze zorg te standaardiseren, voegen veel programmeertalen ondersteuning toe voor een expliciete octale cijfernotatie: <code>0o<\/code> of <code>0O<\/code>.<\/p>\n<p>Beginnend met PHP 8.1 kan je het bovenstaande voorbeeld (d.w.z. nummer 9 in base-10) in het octale numerieke systeem schrijven als <code>0o11<\/code>\u00a0of\u00a0<code>0O11<\/code>.<\/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>Bovendien werkt deze nieuwe feature ook met de <a href=\"https:\/\/wiki.php.net\/rfc\/numeric_literal_separator\">underscore numeric literal separator<\/a> die werd ge\u00efntroduceerd in PHP 7.4.<\/p>\n<p>Lees meer over deze nieuwe PHP 8.1 feature in <a href=\"https:\/\/wiki.php.net\/rfc\/explicit_octal_notation\">de RFC<\/a>.<\/p>\n<h3>Ondersteuning MurmurHas3 en xxHash hash algoritmes<\/h3>\n<p>PHP 8.1 voegt ondersteuning toe voor MurmurHash3 en xxHash hashing algoritmes. Ze zijn niet bedoeld voor cryptografisch gebruik, maar ze bieden desalniettemin een indrukwekkende willekeur, spreiding en uniciteit van de output.<\/p>\n<p>Deze <a href=\"https:\/\/php.watch\/articles\/php-hash-benchmark\">nieuwe hashing algoritmes zijn sneller<\/a> dan de meeste bestaande hashing algoritmes van PHP. Sommige varianten van deze hashing algoritmen zijn zelfs sneller dan de RAM throughput.<\/p>\n<p>Omdat PHP 8.1 ook ondersteuning toevoegt voor het declaren van algoritme-specifieke <code>$options<\/code> parameters, kun je hetzelfde doen met deze nieuwe algoritmen. De standaardwaarde van dit nieuwe argument is <code>[]<\/code>. Het heeft dus geen invloed op onze bestaande hash functions.<\/p>\n<p>Je kan meer lezen over deze nieuwe PHP 8.1 features op hun GitHub pagina&#8217;s <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6059\">MurmurHash3<\/a>,\u00a0<a href=\"https:\/\/php.watch\/versions\/8.1\/xxHash\">xxHash<\/a>,\u00a0<a href=\"https:\/\/github.com\/php\/php-src\/pull\/6400\">Algorithm-specific $options<\/a>.<\/p>\n<h3>Ondersteuning DNS-over-HTTPS (DoH)<\/h3>\n<p>DNS-over-HTTPS (DoH) is een protocol voo <a href=\"https:\/\/kinsta.com\/nl\/blog\/wat-is-dns\/\">DNS resolutie<\/a> via het HTTPSprotocol. Door HTTPS te gebruiken om gegevens tussen de client en de DNS resolver te versleutelen, verhoogt DoH de privacy en veiligheid van gebruikers door MitM aanvallen te voorkomen.<\/p>\n<p>Vanaf PHP 8.1 kan je de <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6612\">\u00a0Curl extensie gebruiken om een DoH server te specificeren<\/a>. Het vereist dat PHP wordt gecompileerd met <strong>libcurl<\/strong> 7.62+ versies. Dit is geen probleem voor de meeste populaire besturingssystemen, inclusief Linux distro\u2019s, omdat ze vaak al Curl 7.68+ bevatten.<\/p>\n<p>Je kan de DoH server URL configureren door de <code>CURLOPT_DOH_URL<\/code> option op te geven.<\/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>In het bovenstaande voorbeeld hebben we de openbare DNS server van Google gebruikt. Let ook het gebruik van <code>https:\/\/<\/code> in alle URL&#8217;s die je gebruikt. Zorg dat je dit perfect configureert omdat er geen standaard DNS server is om op terug te vallen in Curl.<\/p>\n<p>Je kan ook kiezen uit een <a href=\"https:\/\/github.com\/curl\/curl\/wiki\/DNS-over-HTTPS\">lijst met openbare DoH servers<\/a> die je in de Curl documentatie kan vinden.<\/p>\n<p>Bovendien legt de <a href=\"https:\/\/curl.se\/libcurl\/c\/CURLOPT_DOH_URL.html\">CURLOPT_DOH_URL reference<\/a> van de documentatie van Curl uit hoe je de verschillende arguments kan gebruiken.<\/p>\n<h3>Bestandsuploads van strings met CURLStringFile<\/h3>\n<p>De PHP Curl extensie ondersteunt <a href=\"https:\/\/kinsta.com\/nl\/blog\/http-naar-https-redirect\/\">HTTP(S)<\/a> verzoeken bij bestandsuploads. Het gebruik de <strong>CURLFile<\/strong> class om dit te bereiken, die een URI of een bestandspad, een mime type en de uiteindelijke bestandsnaam accepteert.<\/p>\n<p>Met de <strong>CURLFile<\/strong> class kan je echter alleen het bestandspad of URI accepteren, maar niet de inhoud van het bestand zelf. In scenario\u2019s waar je het bestand al moest uploaden naar het geheugen (bijv. verwerkte afbeeldingen, XML documenten, PDF&#8217;s) dan moest je <code>data:\/\/<\/code> URI&#8217;s gebruiken met Base64 encoding.<\/p>\n<p>Maar <strong>libcurl<\/strong> ondersteunt al een veel makkelijkere manier om de inhoud van het bestand te accepteren. De nieuwe <strong>CURLStringFile<\/strong> class voegt die ondersteuning dus toe.<\/p>\n<p>Je kan <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6456\">de GitHub pagina lezen<\/a> om meer te leren over hoe het is ge\u00efmplementeerd in PHP 8.1.<\/p>\n<h3>Nieuwe <code>MYSQLI_REFRESH_REPLICA<\/code> constant<\/h3>\n<p>PHP 8.1&#8217;s <strong>mysqli<\/strong> extensie voegt een nieuwe constant toe genaamd <code>MYSQLI_REFRESH_REPLICA<\/code>. Het is vergelijkbaar met de al bestaande <code>MYSQLI_REFRESH_SLAVE<\/code> constant.<\/p>\n<p>Deze wijziging was welkom in <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6632\">MySQL 8.0.23<\/a> om raciaal getinte termen te adresseren in tech vocabulaire (met als meest bekende voorbeeld &#8220;slave&#8221; en &#8220;master&#8221;).<\/p>\n<p>Merk wel op dat de oudere constant niet verwijderd of afgeschreven is. Developers en applicaties kunnen het blijven gebruiken. De nieuwe constant is eigenlijk niets meer dan een optie voor developers en bedrijven om deze terminologie niet te gebruiken.<\/p>\n<h3>Prestatieverbeteringen met Inheritance Cache<\/h3>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/commit\/4b79dba93202ed5640dff317046ce2fdd42e1d82\">Inheritance Cache<\/a> is een nieuwe toevoeging voor opcache die de overhead van PHP class inheritance elimineert.<\/p>\n<p>PHP classes worden afzonderlijk door opcache gecompileerd en <a href=\"https:\/\/kinsta.com\/nl\/blog\/wat-is-caching\/\">gecachet<\/a>. Ze worden echter in run-time aan elkaar gelinkt bij elk verzoek. Dit proces kan een paar compabiliteitschecks omvatten, plus het lenen van methods\/properties\/constants van parent classes en traits.<\/p>\n<p>Als gevolg kan het nogal wat tijd kosten om het uit te voeren, ook al is het resultaat van elk verzoek hetzelfde.<\/p>\n<p>Inheritance Cache linkt alle unieke dependent classes (parent, interfaces, traits, property types, methods) en slaat de resultaten op in het gedeelde geheugen van opcache. Omdat dit nu maar \u00e9\u00e9n keer gebeurt, kost inheritance minder nu instructies.<\/p>\n<p>Bovendien verwijdert dit beperkingen voor immutable classes, zoals unresolved constants, typed properties en covariant type checks. Daarom zijn alle classes die zijn opgeslagen in opcache immutable, wat het aantal vereiste instructies nog meer vermindert.<\/p>\n<p>Al met al belooft het belangrijke prestatieverbeteringen. <a href=\"https:\/\/github.com\/dstogov\">Dimitry Stogov<\/a>, de auteur van deze patch, heeft laten zien dat het 8% verbeteringen brengt op het base Symfony programma &#8220;Hello, World!&#8221;. We kunnen niet wachten om het uit te testen in de <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-benchmarks\/\">PHP benchmarks<\/a>.<\/p>\n<h3>First-class callable syntax<\/h3>\n<p>PHP 8.1 voegt een first-class callable syntax toe om bestaande encodings met strings en arrays te vervangen. Naast het cre\u00ebren van een strakkere <strong>Closure<\/strong> is deze nieuwe syntax ook toegankelijk is voor statische <a href=\"https:\/\/kinsta.com\/nl\/blog\/code-review-tools\/\">analysetools<\/a> en respecteert het de gedeclarede scope.<\/p>\n<p>Hier zijn een paar voorbeelden uit <a href=\"https:\/\/wiki.php.net\/rfc\/first_class_callable_syntax\">de 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 zijn alle expression pairs equivalenten. De triple-dot (<strong>&#8230;<\/strong>) syntax is vergelijkbaar met de argument-unpacking syntax (<code>...$args<\/code>). Maar in dit geval zijn de arguments nog niet ingevuld.<\/p>\n<h2>Wijzigingen in PHP 8.1<\/h2>\n<p>PHP 8.1 bevat ook wijzigingen aan de bestaande syntax en features. Laten we ze behandelen:<\/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 vereist readline extensie<\/h3>\n<p>PHP&#8217;s <strong>readline<\/strong> extensie schakeld <a href=\"https:\/\/kinsta.com\/nl\/blog\/ssh-gebruiken\/\">interactive shell<\/a> features in zoals navigatie, autocompletion, bewerken en meer. Hoewel het is gebundeld met PHP, is het niet standaard ingeschakeld.<\/p>\n<p>Je krijgt toegang tot de interactive shell van PHP door gebruik te maken van PHP CLI&#8217;s <code>-a<\/code> command-line optie:<\/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>V\u00f3\u00f3r PHP 8.1 kon je zelfs met PHP CLI de interactive shell openen zonder dat de <strong>readline<\/strong> extensie was ingeschakeld. Zoals verwacht werkten de interactive features van de shell niet, wat de -a optie zinloos maakte.<\/p>\n<p>In PHP 8.1 CLI, maakt de interactive shell een exit met een foutbericht als je <a href=\"https:\/\/github.com\/php\/php-src\/commit\/959e5787bdf7c088a57dce5f4f7570abd7fe35f8\">de readline extensie niet ingeschakeld hebt<\/a>.<\/p>\n<pre><code class=\"language-php\">php -a\nInteractive shell (-a) requires the readline extension.<\/code><\/pre>\n<h3>MySQLi standaard error mode ingesteld op exceptions<\/h3>\n<p>V\u00f3\u00f3r PHP 8.1 was het de standaard in <a href=\"https:\/\/kinsta.com\/nl\/blog\/wat-is-mysql\/\">MySQLi<\/a> om de errors als silent te beschouwen. Dit gedrag zorgde vaak voor code die niet de strikte Error\/Exception handling volgde. Developers moesten hun eigen expliciete error handling functions implementeren.<\/p>\n<p>PHP 8.1 verandert dit gedrag door de standaard modus van MySQLi&#8217;s om errors te reporten te veranderen in het geven van een exception.<\/p>\n<pre><code class=\"language-php\">Fatal error: Uncaught mysqli_sql_exception: Connection refused in ...:...<\/code><\/pre>\n<p>Aangezien dit een belangrijke wijziging is, moet je voor PHP &lt;8.1 versies expliciet de error handling mode instellen met de function <code>mysqli_report<\/code> voordat je de eerste MySQLi verbinding maakt. Je kan hetzelfde bereiken door de error reporting waarde te selecteren door een <code>mysqli_driver<\/code> instance te instanti\u00ebren.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/mysqli_default_errmode\">De RFC<\/a> volgt een <a href=\"https:\/\/wiki.php.net\/rfc\/pdo_default_errmode\">vergelijkbare wijziging die werd ge\u00efntroduceerd in PHP 8.0<\/a>.<\/p>\n<h3>Aanpasbare line endings voor CSV writing functions<\/h3>\n<p>V\u00f3\u00f3r PHP 8.1 waren de ingebouwde <a href=\"https:\/\/kinsta.com\/changelog\/export-redirects-csv\/\">CSV<\/a> writing functions van PHP, <code>fputcsv<\/code>\u00a0and\u00a0<code>SplFileObject::fputcsv<\/code>, hard-coded om <code>\\n<\/code> (of het Line-Feed teken) toe te voegen aan het einde van elke regel.<\/p>\n<p>PHP 8.1 voegt ondersteuning toe aan deze functions voor een nieuwe parameter genaamd <code>eol<\/code>. Je kan het gebruiken om een configureerbaar end-of-line teken door te geven. Standaard gebruikt het nog steeds het <code>\\n<\/code> teken. Je kan het dus blijven gebruiken in je bestaande code.<\/p>\n<p>Standaard character escaping regels zijn van toepassing voor het gebruik van end-of-line karakters. Als je <code>\\r<\/code>, <code>\\n<\/code> of <code>\\r\\n<\/code> als EOL tekens wilt gebruiken, moet je deze tussen dubbele aanhalingstekens plaatsen.<\/p>\n<p>Hier is de <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6403\">GitHub pagina<\/a> die deze nieuwe wijziging trackt.<\/p>\n<h3>Nieuwe beperkingen <code>version_compare<\/code> operator<\/h3>\n<p>PHP&#8217;s <code>version_compare()<\/code> vergelijkt twee versienummer strings. Deze function accepteert een derde optionele argument genaamd <code>operator<\/code> om te testen op een bepaalde relatie.<\/p>\n<p>Hoewel dit niet expliciet in de documentatie wordt behandeld, kon je deze parameter instellen open een gedeeltelijke waarde (bijv. <code>g<\/code>, <code>l<\/code>, <code>n<\/code>) zonder dat dit een error opleverde.<\/p>\n<p>PHP 8.1 voegt strengere beperkingen toe aan de <code>version_compare()<\/code> function&#8217;s <code>operator<\/code> argument om deze situatie te verhelpen. De enige operators die je nu kan gebruiken zijn:<\/p>\n<ul>\n<li><strong>==<\/strong>, <strong>=<\/strong>, en <strong>eq<\/strong><\/li>\n<li><strong>!=<\/strong>, <strong>&lt;&gt;<\/strong>, en <strong>ne<\/strong><\/li>\n<li><strong>&gt;<\/strong> en <strong>gt<\/strong><\/li>\n<li><strong>&gt;=<\/strong> en <strong>ge<\/strong><\/li>\n<li><strong>&lt;<\/strong> en <strong>lt<\/strong><\/li>\n<li><strong>&lt;=<\/strong> en <strong>le<\/strong><\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/pull\/6510\">Geen gedeeltelijke operatorwaarden meer<\/a>.<\/p>\n<h3>HTML encoding en decoding functions gebruiken nu <code>ENT_QUOTES | ENT_SUBSTITUTE<\/code><\/h3>\n<p>HTML entities zijn tekstuele representaties van tekens die anders als HTML zouden worden ge\u00efnterpreteerd. Denk aan tekens als <code>&lt;<\/code> en <code>&gt;<\/code> die worden gebruikt om <a href=\"https:\/\/kinsta.com\/nl\/blog\/html-best-practices\/\">HTML tags te defini\u00ebren<\/a> (bijv. <code>&lt;a&gt;<\/code>, <code>&lt;h3&gt;<\/code>, <code>&lt;script&gt;<\/code>).<\/p>\n<p>De HTML entity voor <code>&lt;<\/code> is <code>&lt;<\/code> (kleiner dan symbool) en <code>&gt;<\/code> is <code>&gt;<\/code> (groter dan symbool). Je kan deze HTML entities veilig gebruiken binnen een HTML document zonder dat je de rendering engine van de browser triggert.<\/p>\n<p>Je zal bijvoorbeeld in de browser <code>&lt;script&gt;<\/code> als <code>&lt;script&gt;<\/code> zien, in plaats van dat het wordt ge\u00efnterpreteerd als HTML tag.<\/p>\n<p>V\u00f3\u00f3r PHP 8.1 converteerden de <a href=\"https:\/\/www.php.net\/manual\/function.htmlspecialchars.php\">htmlspecialchars()<\/a> en <a href=\"https:\/\/www.php.net\/manual\/en\/function.htmlentities.php\">htmlentities()<\/a> functions symbolen als <code><strong>\u201c<\/strong><\/code>,\u00a0<code>&lt;<\/code>,\u00a0<code>&gt;<\/code>, en\u00a0<code>&<\/code> naar hun respectievelijke HTML entities. Maar ze converteerden niet standaard het enkele aanhalingsteken (<strong>\u2018<\/strong>) naar de HTML entity. Bovendien gaven ze een lege string terug als er een misvormde UTF-8 in de tekst stond.<\/p>\n<p>In PHP 8.1. zullen deze HTML encoding en decoding functions (en hun gerelateerde functions) ook <a href=\"https:\/\/github.com\/php\/php-src\/commit\/50eca61f68815005f3b0f808578cc1ce3b4297f0\">standaard enkele aanhalingstekens<\/a> naar hun HTML entity converteren.<\/p>\n<p>En als de gegeven tekst ongeldige tekens bevat, zullen de functions deze vervangen door een Unicode vervangingsteken (\ufffd) in plaats van een lege string terug te geven. PHP 8.1 doet dit door de signatures van deze functions standaard te wijzigen in <code>ENT_QUOTES | ENT_SUBSTITUTE<\/code> in plaats van <code>ENT_COMPAT<\/code> .<\/p>\n<p>De meeste frameworks gebruiken <code>ENT_QUOTES<\/code> als de standaard flag waarde. Je zal dus niet zo heel veel verschil zien door deze wijziging. De nieuwe <code>ENT_SUBSTITUTE<\/code> flag wordt echter niet zo veel gebruikt. PHP 8.1 zorgt ervoor dat ongeldige UTF-8 tekens worden vervangen door het \ufffd teken in plaats van een lege string terug te geven.<\/p>\n<h3>Waarschuwing voor illegale compact function calls<\/h3>\n<p>PHP&#8217;s <code>compact()<\/code> function is superhandig. Je kan hem gebruiken om een array met variabelen te maken met hun namen en waarden.<\/p>\n<p>Bekijk de volgende 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>De <a href=\"https:\/\/www.php.net\/manual\/en\/function.compact.php\">documentatie van de compact function<\/a> vermeldt dat het alleen string parameters of array waarden met string waarden accepteert. V\u00f3\u00f3r PHP 7.3 zouden alle strings die niet zijn ingesteld silent worden overgeslagen.<\/p>\n<p>PHP 7.3 heeft de <code>compact()<\/code> function aangepast om een melding weer te geven als je ongedefinieerde variabelen gebruikt. <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6921\">PHP 8.1 gaat nog een stap verder<\/a> en geeft een waarschuwing.<\/p>\n<p>Je kunt de <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6921\">GitHub pagina<\/a> lezen om te begrijpen hoe deze verandering tot stand kwam.<\/p>\n<h3>Nieuwe migraties van resources naar class objects<\/h3>\n<p>Een van de langetermijndoelen van PHP is om weg te gaan <a href=\"https:\/\/php.watch\/articles\/resource-object\">van resources naar standard class objects<\/a>.<\/p>\n<p>Om historische redenen worden resource objects veel gebruikt in PHP applicaties. Daarom moet de migratie van resources naar class objects zo min mogelijk verstorend werken. PHP 8.1 migreert vijf van dergelijke resources:<\/p>\n<h4>The <code>file_info<\/code> resource migreert naar <code>finfo<\/code> objects<\/h4>\n<p>PHP&#8217;s <a href=\"https:\/\/www.php.net\/manual\/en\/class.finfo.php\">finfo class<\/a> biedt een <a href=\"https:\/\/kinsta.com\/nl\/blog\/python-object-oriented-programming\/#what-is-objectoriented-programming-in-python\">object-oriented<\/a> interface voor de <code>fileinfo<\/code> functions. Het gebruik van <code>finfo<\/code> functions retourneert echter <code>resource<\/code> objects met het <code>file_info<\/code> type in plaats van een instance met de <code>finfo<\/code> class zelf.<\/p>\n<p><a href=\"https:\/\/github.com\/php\/php-src\/pull\/5987\">PHP 8.1 lost deze anomalie op<\/a>.<\/p>\n<h4>IMAP resources migreren naar <code>IMAP\\Connection<\/code> class objects<\/h4>\n<p>In lijn met het doel van de resource-naar-object migratie, minimaliseert de nieuwe <code>IMAP\\Connection<\/code> class\u00a0 wijzigingen wanneer PHP uiteindelijk de implementatiedetails van de class wijzigt.<\/p>\n<p>Deze nieuwe class wordt ook gedeclared als <code>final<\/code>, wat een <code>extend<\/code> onmogelijk maakt.<\/p>\n<p>Lees meer over de implementatie ervan op <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6418\">de GitHub pagina<\/a>.<\/p>\n<h4>FTP connection resources zijn nu <code>FTP\\Connection<\/code> class objects<\/h4>\n<p>Als je in PHP &lt;8.1 een <a href=\"https:\/\/kinsta.com\/nl\/blog\/beste-ftp-clients\/\">FTP verbinding<\/a> maakte met de <code>ftp_connect<\/code> of <code>ftp_ssl_connect()<\/code> functions, dan kreeg je een <strong>resource<\/strong> object terug van het <strong>ftp<\/strong> type.<\/p>\n<p>PHP 8.1 voegt de nieuwe <code>FTP\/Connection<\/code> class toe om dat recht te zetten. En net als bij de <code>IMAP\\Connection<\/code> class, wordt ook deze als <code>final<\/code> gedeclared zodat het niet kan worden extend.<\/p>\n<p>Lees meer over <a href=\"https:\/\/github.com\/php\/php-src\/commit\/b4503fbf882e490f16d85915e83173bd1e414e84\">de implementatie<\/a> op de GitHub pagina.<\/p>\n<h4>Font identifiers migreren naar <code>GdFont<\/code> class objects<\/h4>\n<p>PHP&#8217;s GD extensie heeft de <a href=\"https:\/\/www.php.net\/manual\/en\/function.imageloadfont.php\">imageloadfont() function<\/a> om een user-defined bitmap te loaden en de resource ID van de font-identifier terug te geven (een integer).<\/p>\n<p>In PHP 8.1 zal deze function echter in plaats daaran een <strong>GdFont<\/strong> class instance teruggeven. Om de migratie probleemloos te laten verlopen, zullen alle functions die voorheen een resource ID van <code>imageloadfont()<\/code> accepteerden, nu de nieuwe <strong>GdFont<\/strong> class objects gebruiken.<\/p>\n<p>Lees meer over deze migratie in de <a href=\"https:\/\/github.com\/php\/php-src\/commit\/bc40bce868e208fa2d7af950845759d3ef498b5d\">GitHub pagina<\/a>.<\/p>\n<h4>LDAP resources migreren naar objects<\/h4>\n<p><a href=\"https:\/\/www.php.net\/manual\/en\/intro.ldap.php\">LDAP<\/a> or Lightweight Directory Access Protocol wordt gebruikt om toegang te krijgen tot &#8220;Directory Servers&#8221;. Net als een directory structuur van een harde schijf is het een unieke database die gegevens bevat in een boomstructuur.<\/p>\n<p>PHP bevatte v\u00f3\u00f3r PHP 8.1 een LDAP extensie die <strong>resource<\/strong> objects accepteerde of teruggaf. Ze zijn nu echter allemaal naadloos gemigreerd naar nieuwe class instances. De <strong>resource<\/strong> types die zijn overgezet zijn:<\/p>\n<ul>\n<li><code>ldap link<\/code> resource naar <code>\\LDAP\\Connection<\/code> class object<\/li>\n<li><code>ldap result<\/code> resource naar <code>\\LDAP\\Result<\/code> class object<\/li>\n<li><code>ldap result entry<\/code> resource naar <code>\\LDAP\\ResultEntry<\/code> class object<\/li>\n<\/ul>\n<p>Blader vooral door de <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6770\">GitHub pagina<\/a> om deze migratie beter te begrijpen.<\/p>\n<h4>Pspell resources zijn nu class objects<\/h4>\n<p>Met de <a href=\"https:\/\/www.php.net\/manual\/en\/intro.pspell.php\">Pspell extensie<\/a> van PHP kan je spelling en woordsuggesties checken.<\/p>\n<p>PHP &lt;8.1 gebruikte <code>psell<\/code> en <code>pspell config<\/code> resources object types met een integer identifier. Deze twee resource objects worden nu vervangen door <code>PSpell\\Dictionary<\/code> en <code>PSpell\\Config<\/code> class objects.<\/p>\n<p>Net als bij eerdere migraties zullen alle <a href=\"https:\/\/php.watch\/versions\/8.1\/PSpell-resource#PSpell-Dictionary\">Pspell functions<\/a> die voorheen resource object identifiers accepteerden of teruggaven de nieuwe class object instances gebruiken.<\/p>\n<p>Raadpleeg de <a href=\"https:\/\/github.com\/php\/php-src\/commit\/bd12c94f46438dad03d1d3c02fff37b9b950ae6f\">GitHub pagina<\/a> voor meer informatie.<\/p>\n<h2>Afschrijvingen in PHP 8.1<\/h2>\n<p>PHP 8.1 deprecieert veel van zijn vorige features. De volgende lijst geeft een kort overzicht van de functionaliteiten die PHP 8.1 afschrijft:<\/p>\n<div><\/div><kinsta-auto-toc list-style=\"disc\" selector=\"h3\" count-number=\"10\" sub-toc=\"true\"><\/kinsta-auto-toc>\n<h3>Kan <code>null<\/code> niet doorgeven aan non-nullable internal function paramters<\/h3>\n<p>In PHP 8.0 accepteren de internal functions (silent) <code>null<\/code> waarden, zelfs voor non-nullable arguments. Hetzelfde geldt niet voor user-defined functions &#8211; deze accepteren alleen <code>null<\/code> voor nullable arguments.<\/p>\n<p>Kijk bijvoorbeeld eens naar het volgende gebruik:<\/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 wordt de <code>null<\/code> waarde (silent) geconverteerd naar een lege string. Het resultaat retourneert dus <code>true<\/code>.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/deprecate_null_to_scalar_internal_arg\">Deze RFC<\/a> is bedoeld om het gedrag van internal functions te synchroniseren door in PHP 8.1 een deprecation waarschuwing te geven.<\/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>Deze afschrijving wordt een TypeError in de volgende grote PHP versie (bijv. PHP &gt;=9.0), waardoor het gedrag van internal functions consistent is met user-defined functions.<\/p>\n<h3>Beperkt gebruik <code>$GLOBALS<\/code><\/h3>\n<p>PHP&#8217;s <code>$GLOBALS<\/code> variabele biedt een directe verwijzing naar zijn interne symbooltabel. Het ondersteunen van deze functionaliteit is complex en be\u00efnvloedt de prestatie van array operations. Bovendien werd er zelden gebruik van gemaakt.<\/p>\n<p><a href=\"https:\/\/wiki.php.net\/rfc\/restrict_globals_usage\">Volgens de RFC<\/a> is het indirect wijzigen van <code>$GLOBALS<\/code> niet langer toegestaan. Deze wijziging is achterwaarts incompatibel.<\/p>\n<p>De impact van deze wijziging is relatief laag:<\/p>\n<blockquote><p><em>In de top 2k composer packages vond ik <\/em><a href=\"https:\/\/gist.github.com\/nikic\/9fd95866f9811b349b947f63214ad7a9\"><em>23 gevallen die $GLOBALS gebruiken<\/em><\/a><em> zonder er rechtstreeks naar te verwijzen. Op basis van een vluchtige inspectie zijn er slechts twee instances waar <strong>$GLOBALS<\/strong> niet wordt gebruikt op een read-only manier.<\/em><\/p><\/blockquote>\n<p>Read-only gebruik van <code>$GLOBALS<\/code> blijft echter gewoon werken. Wat niet langer wordt ondersteund is het schrijven naar <code>$GLOBALS<\/code> als geheel. Als gevolg hiervan kan je een lichte <a href=\"https:\/\/kinsta.com\/nl\/blog\/tools-testen-performance\/\">prestatiebump<\/a> verwachten, helemaal als je met gewone PHP arrays werkt.<\/p>\n<h3>Return type declarations voor internal functions<\/h3>\n<p>PHP 8.0 stond developers toe om parameters en return types te declaren voor de meeste interne functions en methods. Dit was mogelijk dankzij verschillende RFC&#8217;s, zoals <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-8\/#type-errors-internal-functions\">Consistent type errors voor internal functions<\/a>, <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-8\/#union-types-2-0\">Union Types 2.0<\/a> en <a href=\"https:\/\/wiki.php.net\/rfc\/mixed_type_v2\">Mixed Type v2<\/a>.<\/p>\n<p>Er zijn echter veel gevallen waarin type informatie kan ontbreken. Sommigen van hen bevatten een type met resources, <strong>out<\/strong> pass-by-ref parameters, return type van non-final methods en functions of methods die volgens de algemene regels geen parameters parsen. Je kan de precieze details lezen in de <a href=\"https:\/\/wiki.php.net\/rfc\/internal_method_return_types\">de RFC<\/a>.<\/p>\n<p>Deze RFC lost alleen het probleem op met het return type van non-final methods. Maar in plaats van het echter onmiddellijk volledig uit te faseren, biedt het PHP team een geleidelijke migratie zodat je je codebase kan bijwerken met de relevante method return types.<\/p>\n<p><em>Non final internal method return types &#8211; indien mogelijk &#8211; worden voorlopig gedeclareerd in PHP 8.1 en zullen worden afgedwongen in PHP 9.0. Dit betekent dat je in PHP 8.x versies een &#8220;deprecated&#8221; melding krijgt tijdens inheritance checks wanneer een internal method op zo&#8217;n manier wordt overschreven dat de return types incompatibel zijn. In PHP 9.0 krijg je een fatal error.<\/em><\/p>\n<p>Als je deze deprecation melding krijgt na het updaten naar PHP 8.1, zorg er dan voor dat je de return types van je methods bijwerkt.<\/p>\n<h3>Serializable interface afgeschreven<\/h3>\n<p>PHP 7.4 introduceerde het <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-7-4\/#serialization\">custom object serialization mechanisme<\/a> met twee nieuwe magic methods: <code>__seralize()<\/code> en <code>__unserialize()<\/code>. Deze nieuwe methods zijn bedoeld om de niet functionerende <strong>Serializable<\/strong> interface uiteindelijk te vervangen.<\/p>\n<p>Deze <a href=\"https:\/\/wiki.php.net\/rfc\/phase_out_serializable\">RFC stelt voor<\/a> om die beslissing af te ronden door een plan op te stellen voor de uiteindelijke verwijdering van <strong>Serializable<\/strong>.<\/p>\n<p>Als je in PHP 8.1 de <strong>Seriazable<\/strong> interface implementeert zonder <code>__serialize()<\/code> en <code>__unserialize<\/code> methods te implementeren, dan geeft PHP je een &#8220;Deprecated&#8221; waarschuwing.<\/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>Als je <strong>PHP &lt;7.4<\/strong> en <strong>PHP &gt;=7.4<\/strong> ondersteunt, dan moet je zowel de <strong>Serializable<\/strong> als de nieuwe magic methods implementeren. Bij <strong>PHP &gt;=7.4<\/strong> versies, hebben de magic methods voorrang.<\/p>\n<h3>Niet-compatibele <code>float<\/code> naar <code>int<\/code> conversies afgeschreven<\/h3>\n<p>PHP is een dynamisch getypte taal. Als zodanig zijn er veel gevallen waarin type coercion van nature voorkomt. De meeste van de coercions zijn ongevaarlijk en eigenlijk superhandig.<\/p>\n<p>Wanneer een <strong>float<\/strong> nummer echter wordt geconverteerd naar een <strong>integer<\/strong>, gaat dit echter vaak gepaard met gegevensverlies. Wanneer de float <strong>3.14<\/strong> bijvoorbeeld wordt geconverteerd naar een integer <strong>3<\/strong>, dan verliest het zijn fractionele waarde.<\/p>\n<p>Hetzelfde gebeurt wanneer de float buiten het platform integer bereik valt, of wanneer een float string wordt geconverteerd naar een integer.<\/p>\n<p>PHP 8.1 corrigeert dit gedrag en brengt de dynamische type coercing meer in overeenstemming met de meeste moderne programmeertalen. Het doel is om dergelijke coercions voorspelbaar en intu\u00eftief te maken.<\/p>\n<p>In PHP 8.1 zie je een deprecation melding wanneer impliciete coercion optreedt van niet-compatibele <strong>float<\/strong> naar een <strong>int<\/strong>. Maar wat is een integer-compatible float? <a href=\"https:\/\/wiki.php.net\/rfc\/implicit-float-int-deprecate\">De RFC<\/a> antwoordt hierop:<\/p>\n<p><em>Van een float wordt gezegd dat hij integer-compatible is als hij de volgende kenmerken bezit:<\/em><\/p>\n<ul>\n<li><em>Is een getal (dus niet NaN of Infinity)<\/em><\/li>\n<li><em>Ligt binnen het bereik van een PHP integer (platformafhankelijk)<\/em><\/li>\n<li><em>Heeft geen fractioneel deel<\/em><\/li>\n<\/ul>\n<p>Deze deprecation melding zal worden ge\u00fcpgraded naar een <strong>TypeError<\/strong> in de volgende grote PHP-versie (dwz PHP 9.0).<\/p>\n<h3>De <code>mysqli::get_client_info<\/code> Method en <code>mysqli_get_client_info($param)<\/code> afgeschreven<\/h3>\n<p>De MySQL client API definieert twee constants: <code>client_info<\/code>\u00a0(een string) en\u00a0<code>client_version<\/code>\u00a0(een int). MySQL Native Driver (MySQLnd) maakt deel uit van de offici\u00eble PHP source koppelt deze constants aan de PHP versie. In libmysql vertegenwoordigen ze de versie van de client library op het moment van compilatie.<\/p>\n<p>V\u00f3\u00f3r PHP 8.1\u00a0 exposede mysqli deze constants op 4 manieren: <code>mysqli_driver<\/code> properties,\u00a0<code>mysqli<strong>\u00a0properties<\/strong><\/code>,\u00a0<code>mysqli_get_client_info()<\/code>\u00a0function, en\u00a0<code>mysqli::get_client_info<\/code>\u00a0method. Er is echter geen method voor <code>client_version<\/code>.<\/p>\n<p>MySQLnd exposet deze constants op 2 manieren aan PHP: een constant en een function call. Om mysqli acces methods te verenigen met dezelfde twee options, schrijft PHP 8.1 deze twee options af:<\/p>\n<ul>\n<li><code>get_client_info<\/code>\u00a0method in de\u00a0<strong>mysqli<\/strong>\u00a0class. In plaats daarvan kan je simpelweg de function <code>mysqli_get_client_info()<\/code> gebruiken.<\/li>\n<li><code>mysqli_get_client_info()<\/code>\u00a0function met parameters. Call de function met elke parameter om de deprecation melding te vermijden.<\/li>\n<\/ul>\n<p>Lees meer over deze afschrijving op de <a href=\"https:\/\/github.com\/php\/php-src\/pull\/6777\">GitHub pagina<\/a>.<\/p>\n<h3>Alle <code>mhash*()<\/code> functions (hash extensie) zijn afgeschreven<\/h3>\n<p>PHP 5.3 integreerde <code>mhash*()<\/code> functions in <code>ext\/hash<\/code> als een compatibility layer voor <code>ext\/mhash<\/code>. Later werd deze <code>ext\/mhash<\/code> verwijderd in PHP 7.0.<\/p>\n<p>In tegenstelling tot de <code>hash_*()<\/code> functions, zijn de <code>mhash*()<\/code> functions niet altijd beschikbaar. Je moet ze afzonderlijk inschakelen tijdens het configureren van PHP.<\/p>\n<p>In PHP 7.4 was de hash extensie samen met PHP gebundeld, wat het tot een standaard extensie voor PHP maakt. Het ondersteunde echter om compatibiliteitsredenen nog wel het inschakelen van de <code>--enable-mhash<\/code> optie.<\/p>\n<p>Het PHP heeft besloten om <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1#mhash_function_family\">mhash*() functions af te schrijven<\/a> in pHP 8.1 en ze in PHP 9.0 helemaal te verwijderen. De af te schrijven functions zijn\u00a0<code>mhash()<\/code>,\u00a0<code>mhash_keygen_s2k()<\/code>,\u00a0<code>mhash_count()<\/code>,\u00a0<code>mhash_get_block_size()<\/code>\u00a0en\u00a0<code>mhash_get_hash_name()<\/code>. Je kan in plaats daarvan de standaard <code>ext\/hash<\/code> functionaliteit gebruiken.<\/p>\n<h3>Zowel <code>filter.default<\/code> als <code>filter.default_options<\/code> INI instellingen afgeschreven<\/h3>\n<p>Met PHP&#8217;s <code>filter.default<\/code> INI instellingen kan je een filter toepassen op alle PHP super-globals \u2014 dwz GPCRS data (<code>$_GET<\/code>,\u00a0<code>$_POST<\/code>,\u00a0<code>$_COOKIE<\/code>,\u00a0<code>$_REQUEST<\/code>, en\u00a0<code>$_SERVER<\/code>).<\/p>\n<p>Je kan bijvoorbeeld <code>filter.default=magic_quotes<\/code> of\u00a0<code>filter.default=add_slashes<\/code> instellen \u00a0(gebaseerd op de PHP versie) om PHP&#8217;s <a href=\"https:\/\/en.wikipedia.org\/wiki\/Magic_quotes\">controversi\u00eble en onveilige magic quotes<\/a> feature nieuw leven in te blazen (verwijderd in PHP 5.4).<\/p>\n<p>De <code>filter.default<\/code> INI instelling biedt extra functionaliteit door veel meer filters toe te staan, wat het alleen maar erger maakt. De another option &#8211; <code>filter.default=special_chars<\/code> &#8211; maakt bijvoorbeeld magic quotes alleen voor HTML mogelijk. Er is veel minder bekendheid met deze instellingen.<\/p>\n<p>PHP 8.1 <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1#filterdefault_ini_setting\">geeft een deprecation melding<\/a> als <code>filter.default<\/code> is ingesteld op een andere waarde dan <code>unsafe_raw<\/code> (de standaardwaarde). Je ziet geen aparte deprecation melding voor <code>filter.default_options<\/code>, maar PHP 9.0 zal deze beide INI instellingen verwijderen.<\/p>\n<p>Als alternatief kan je de function <a href=\"https:\/\/www.php.net\/manual\/en\/function.filter-var.php\">filter_var()<\/a> gaan gebruiken. Het filtert variabelen met het opgegeven filter.<\/p>\n<h3><code>autovivification<\/code> bij false afgeschreven<\/h3>\n<p>PHP maakt autovivification mogelijk (automatische creatie van arrays van false waarden). Deze feature is superhandig als de variabele niet is gedefinieerd.<\/p>\n<p>Desalniettemin is het niet ideaal om automatisch een array te maken wanneer de waarde false of null is.<\/p>\n<p>Deze <a href=\"https:\/\/wiki.php.net\/rfc\/autovivification_false\">RFC verbiedt autovivification<\/a> van false waarden. Merk echter op dat autovivification van ongedefinieerde variabelen en null nog steeds is toegestaan.<\/p>\n<p>In PHP 8.1 zal het appenden aan een variabele van het type false een deprecation melding geven:<\/p>\n<pre><code class=\"language-php\">Deprecated: Automatic conversion of false to array is deprecated in<\/code><\/pre>\n<p>PHP 9.0 zal een fatal error laten zien voor hetzelfde, die identiek is aan andere scalar types.<\/p>\n<h3>De <code>mysqli_driver-&gt;driver_version<\/code> property wordt afgeschreven<\/h3>\n<p>De <strong>mysqli_driver-&gt;driver_version<\/strong> property van MySQLi&#8217;s extensie is al 13 jaar niet bijgewerkt. Ondanks vele wijzigingen die sindsdien aan de driver zijn gemaakt, geeft het nog steeds de waarde van de versie van de oude driver, wat deze property zinloos maakt.<\/p>\n<p>In PHP 8.1 wordt de <a href=\"https:\/\/github.com\/php\/php-src\/commit\/3dfd3558ca2f63f\">mysqli_driver-&gt;driver_version property afgeschreven<\/a>.<\/p>\n<h2>Overige kleine wijzigingen<\/h2>\n<p>Er zijn <a href=\"https:\/\/wiki.php.net\/rfc\/deprecations_php_8_1\">veel meer deprecations in PHP 8.1<\/a>. Het wordt te veel om ze allemaal in dit artikel te benoemen. We raden aan om rechtstreeks de RFC te lezen voor deze kleine afschrijvingen.<\/p>\n<p>PHP&#8217;s GitHub pagina bevat ook een <a href=\"https:\/\/github.com\/php\/php-src\/blob\/master\/UPGRADING\">PHP 8.1 UPGRADE NOTES<\/a> gids. Het geeft een overzicht van alle belangrijke wijzigingen die je moet overwegen voordat je een upgrade naar PHP 8.1 uitvoert.<\/p>\n\n<h2>Samenvatting<\/h2>\n<p>PHP 8.1 is beter dan <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-8\/\">zijn voorganger<\/a>, wat geen geringe prestatie is. We denken dat de meest spannende PHP 8.1 features Enums, Fibers, Pure Intersection Types en de vele prestatieverbeteringen zijn. We kunnen dan ook niet wachten om PHP 8.1 op de proef te stellen en verschillende <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-frameworks\/\">PHP frameworks<\/a> en <a href=\"https:\/\/kinsta.com\/nl\/wordpress-marktaandeel\/\">CMS&#8217;en<\/a> te benchmarken.<\/p>\n<p>Zorg ervoor dat je dit blogartikel opslaat in je favorieten als toekomstig naslagwerk.<\/p>\n<p><em>Welke PHP 8.1 feature is jouw favoriet? <\/em><em>Deel je mening met de community in de reacties hieronder.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>PHP 8.1, uitgebracht op 25 november 2021 is eindelijk hier, boordevol verschillende opwindende features. In dit artikel bespreken we in detail wat er nieuw is in &#8230;<\/p>\n","protected":false},"author":117,"featured_media":40056,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[32,484],"topic":[867],"class_list":["post-40052","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>Wat is er nieuw in PHP 8.1? Features &amp; Verbeteringen - Kinsta<\/title>\n<meta name=\"description\" content=\"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!\" \/>\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\/nl\/blog\/php-8-1\/\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Wat is er nieuw in PHP 8.1: features, veranderingen, verbeteringen en meer\" \/>\n<meta property=\"og:description\" content=\"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-09-16T07:28:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-05-22T12:20:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/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=\"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png\" \/>\n<meta name=\"twitter:creator\" content=\"@salmanravoof\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_NL\" \/>\n<meta name=\"twitter:label1\" content=\"Geschreven door\" \/>\n\t<meta name=\"twitter:data1\" content=\"Salman Ravoof\" \/>\n\t<meta name=\"twitter:label2\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data2\" content=\"36 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/\"},\"author\":{\"name\":\"Salman Ravoof\",\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987\"},\"headline\":\"Wat is er nieuw in PHP 8.1: features, veranderingen, verbeteringen en meer\",\"datePublished\":\"2021-09-16T07:28:38+00:00\",\"dateModified\":\"2023-05-22T12:20:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/\"},\"wordCount\":7224,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png\",\"keywords\":[\"php\",\"php 8.1\"],\"articleSection\":[\"Webdevelopment\"],\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/\",\"url\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/\",\"name\":\"Wat is er nieuw in PHP 8.1? Features & Verbeteringen - Kinsta\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png\",\"datePublished\":\"2021-09-16T07:28:38+00:00\",\"dateModified\":\"2023-05-22T12:20:19+00:00\",\"description\":\"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png\",\"contentUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png\",\"width\":1460,\"height\":730,\"caption\":\"Wat is er nieuw in PHP 8.1\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/nl\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PHP updates\",\"item\":\"https:\/\/kinsta.com\/nl\/onderwerpen\/php-updates\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Wat is er nieuw in PHP 8.1: features, veranderingen, verbeteringen en meer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/nl\/#website\",\"url\":\"https:\/\/kinsta.com\/nl\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Snelle, veilige, premium hostingoplossingen\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/nl\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/nl\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/nl\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/\",\"https:\/\/x.com\/Kinsta_NL\",\"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\/nl\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987\",\"name\":\"Salman Ravoof\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\/\/kinsta.com\/nl\/#\/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\/nl\/blog\/author\/salmanravoof\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Wat is er nieuw in PHP 8.1? Features & Verbeteringen - Kinsta","description":"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!","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\/nl\/blog\/php-8-1\/","og_locale":"nl_NL","og_type":"article","og_title":"Wat is er nieuw in PHP 8.1: features, veranderingen, verbeteringen en meer","og_description":"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!","og_url":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/","article_published_time":"2021-09-16T07:28:38+00:00","article_modified_time":"2023-05-22T12:20:19+00:00","og_image":[{"width":1460,"height":730,"url":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png","type":"image\/png"}],"author":"Salman Ravoof","twitter_card":"summary_large_image","twitter_description":"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!","twitter_image":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png","twitter_creator":"@salmanravoof","twitter_site":"@Kinsta_NL","twitter_misc":{"Geschreven door":"Salman Ravoof","Geschatte leestijd":"36 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/"},"author":{"name":"Salman Ravoof","@id":"https:\/\/kinsta.com\/nl\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987"},"headline":"Wat is er nieuw in PHP 8.1: features, veranderingen, verbeteringen en meer","datePublished":"2021-09-16T07:28:38+00:00","dateModified":"2023-05-22T12:20:19+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/"},"wordCount":7224,"commentCount":0,"publisher":{"@id":"https:\/\/kinsta.com\/nl\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png","keywords":["php","php 8.1"],"articleSection":["Webdevelopment"],"inLanguage":"nl-NL","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/","url":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/","name":"Wat is er nieuw in PHP 8.1? Features & Verbeteringen - Kinsta","isPartOf":{"@id":"https:\/\/kinsta.com\/nl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png","datePublished":"2021-09-16T07:28:38+00:00","dateModified":"2023-05-22T12:20:19+00:00","description":"Ontdek wat er nieuw is in PHP 8.1. Van de nieuwe features en prestatieverbeteringen van PHP 8.1 tot wijzigingen en afschrijvingen, we beschrijven ze allemaal!","breadcrumb":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/nl\/blog\/php-8-1\/"]}]},{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#primaryimage","url":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png","contentUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2021\/09\/php-8.1.png","width":1460,"height":730,"caption":"Wat is er nieuw in PHP 8.1"},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/nl\/blog\/php-8-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/nl\/"},{"@type":"ListItem","position":2,"name":"PHP updates","item":"https:\/\/kinsta.com\/nl\/onderwerpen\/php-updates\/"},{"@type":"ListItem","position":3,"name":"Wat is er nieuw in PHP 8.1: features, veranderingen, verbeteringen en meer"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/nl\/#website","url":"https:\/\/kinsta.com\/nl\/","name":"Kinsta\u00ae","description":"Snelle, veilige, premium hostingoplossingen","publisher":{"@id":"https:\/\/kinsta.com\/nl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/nl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/nl\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/nl\/","logo":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/","https:\/\/x.com\/Kinsta_NL","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\/nl\/#\/schema\/person\/9cafd2eedd617e640eeea4cf3a5fd987","name":"Salman Ravoof","image":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/kinsta.com\/nl\/#\/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\/nl\/blog\/author\/salmanravoof\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts\/40052","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/users\/117"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/comments?post=40052"}],"version-history":[{"count":8,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts\/40052\/revisions"}],"predecessor-version":[{"id":41130,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts\/40052\/revisions\/41130"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/translations\/en"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/translations\/fr"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/translations\/it"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/translations\/es"},{"embeddable":true,"hreflang":"pt","title":"Portuguese","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/translations\/pt"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/translations\/de"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/translations\/nl"},{"href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/40052\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/media\/40056"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/media?parent=40052"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/tags?post=40052"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/topic?post=40052"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}