Wat is er nieuw en wat is er veranderd in deze nieuwste release?

ict

[ad_1]

PHP 8.3 is volgens plan uitgebracht op 23 november en bevat veel nieuwe features en verbeteringen sinds de lancering van PHP 8.2. Hoewel het officieel wordt beschouwd als een kleine (minor) release, kunnen sommige wijzigingen in 8.3 direct van invloed zijn op hoe je werkt met PHP – bijvoorbeeld doordat je sneller kan coderen en minder bugs tegenkomt.

Laten we eens kijken naar de grote – en soms minder grote – veranderingen die deze laatste release met zich meebrengt.

Nieuwe features en verbeteringen in PHP 8.3

Laten we beginnen met de PHP 8.3 features die het meest in het oog springen.

Typed class constants

De mogelijkheid om types te declaren voor class properties is al beschikbaar sinds PHP 7.4. Maar ondanks talloze aanpassingen aan PHP typing door de jaren heen, is het niet uitgebreid naar constants – tot nu dan.

Class constants – waaronder interface-, trait- en enum constants – kunnen in PHP 8.3 worden getyped, waardoor het minder waarschijnlijk is dat developers afwijken van de bedoeling achter de oorspronkelijke declaratie van een constant.

Hier is een eenvoudig voorbeeld waarbij een interface wordt gebruikt:

// Legal:
interface ConstTest {
    // Declared type and value are both strings
    const string VERSION = "PHP 8.3";
}

// Illegal:
interface ConstTest {
    // Type and value mismatch in this initial declaration
    const float VERSION = "PHP 8.3";
}

De echte waarde van deze typed class constants wordt duidelijk wanneer je werkt in classes die zijn afgeleid van de basisdeclaraties. Hoewel een child class vaak een nieuwe waarde kan toekennen aan een constant, kan PHP 8.3 helpen voorkomen dat het type per ongeluk wordt gewijzigd zodat het incompatibel wordt met de oorspronkelijke declaratie:

class ConstTest {
    const string VERSION = "PHP 8.2";
}

class MyConstTest extends ConstTest {

    // Legal:
    // It's OK to change the value of VERSION here
    const string VERSION = "PHP 8.3";

    // Illegal:
    // Type must be declared if it was specified in the base class
    const VERSION = "PHP 8.3";

    // Illegal:
    // In this case, we can't change the type declared in the 
    // base class, even if the new type and its value are compatible.
    const float VERSION = 8.3;
}

Houd er rekening mee dat het type dat wordt toegewezen aan een class constant kan variëren als je meerdere types “narrowt” of een anders compatibel type gebruikt:

class ConstTest {
    const string|float VERSION = "PHP 8.2";
}

class MyConstTest extends ConstTest {

    // Legal:
    // Here, it's OK to narrow the type declaration to string or float
    const string VERSION = "PHP 8.3";
    const float VERSION = 8.3;

    // Legal:
    // Value could be an int, but it's compatible with float 
    const float VERSION = 8;

    // Illegal:
    // We can't widen the type options here to include int
    const string|float|int VERSION = 8;
}

Twee types die worden ondersteund voor andere properties bij het valideren van retourwaarden – void en never – worden niet ondersteund als class constant types.

Een nieuwe json_validate() functie

Wanneer je met JSON gecodeerde gegevens werkt, is het prettig om te weten of de payload syntactisch geldig is voordat je er iets mee probeert te doen.

In vorige versies van PHP gebruikten developers de functie json_decode() en controleerden ze op fouten terwijl die functie probeerde JSON gegevens om te zetten in associatieve arrays of objecten. De nieuwe json_validate() functie controleert op fouten zonder al het geheugen te gebruiken dat nodig is om die array- of objectstructuren te bouwen.

In het verleden zou je dus een JSON payload als volgt kunnen valideren:

$obj = json_decode($maybeJSON);

if (json_last_error() === JSON_ERROR_NONE) {
    // Probably do something with $obj   
}

Als je niet meteen iets gaat doen met $obj in het voorbeeld hierboven, dan zijn dat veel resources die verbruikt worden om alleen maar de geldigheid van de oorspronkelijke JSON payload te bevestigen. In PHP 8.3 kun je het volgende doen en wat geheugen besparen:

if (json_validate($maybeJSON)) {
    // Do something with $maybeJSON   
}

Opmerking: Het heeft niet veel zin om json_validate() te gebruiken en dan meteen de gegevens door json_decode() te halen, waarbij toch al de geheugenresources van decode worden gebruikt. Het is waarschijnlijker dat je de nieuwe functie gebruikt om de JSON te valideren voordat je het ergens opslaat of aflevert als respons op een verzoek.

Deep cloning van readonly properties

De mogelijkheid om individuele properties van een class te declarer als readonly verscheen in PHP 8.1. PHP 8.2 introduceerde de mogelijkheid om die property toe te wijzen aan een hele class. Veel developers vonden echter dat de beperkingen die werden opgelegd bij het werken met classes die zulke properties bevatten, nuttig programmeren in de weg stonden.

Een RFC voor het wijzigen van readonly gedrag deed twee voorstellen:

  1. Sta classes die geen readonly zijn toe om classes uit te breiden die dat wel zijn
  2. Sta toe dat readonly properties opnieuw geïnitialiseerd worden bij het klonen

Het is het tweede voorstel dat is opgenomen in PHP 8.3. De nieuwe benadering staat toe dat instanties van een class met readonly properties opnieuw worden geïnitialiseerd binnen de __clone magic methode (inclusief via functies die worden gecallt vanuit __clone).

Dit codevoorbeeld uit de RFC laat zien hoe het werkt:

class Foo {
    public function __construct(
        public readonly DateTime $bar,
        public readonly DateTime $baz
    ) {}
 
    public function __clone() {
        // $bar will get a new DateTime when clone is invoked
        $this->bar = clone $this->bar; 

        // And this function will be called
        $this->cloneBaz();
    }
 
    private function cloneBaz() {
       // This is legal when called from within __clone
        unset($this->baz); 
    }
}
 
$foo = new Foo(new DateTime(), new DateTime());
$foo2 = clone $foo;

Nieuw #[Override] attribuut

Bij het implementeren van interfaces in PHP, voorzien programmeurs gedetailleerde functionaliteit voor methoden die in die interfaces genoemd worden. Bij het maken van een instantie van een class kunnen programmeurs een methode van een parent overschrijven door een alternatieve versie met dezelfde naam en een compatibele handtekening te maken in de child.

Een probleem is dat programmeurs kunnen denken dat ze een interfacemethode implementeren of een parent methode overschrijven terwijl dat niet zo is. Ze maken in plaats daarvan misschien wel een compleet losstaande vanwege een typefout in de naam van de methode van de child class of omdat methoden zijn verwijderd of hernoemd in de code van de parent.

PHP 8.3 introduceert het #[Override] attribuut om programmeurs te helpen duidelijk te maken dat een methode een bepaalde afkomst moet hebben binnen de code.

Hier is een eenvoudig voorbeeld:

class A {
    protected function ovrTest(): void {}
}

// This will work because ovrTest() 
// can be found in the parent class
class B extends A {
    #[Override]
    public function ovrTest(): void {}
}

// This will fail because ovrBest() 
// (probably a typo) is not in the parent
class C extends A {
    #[Override]
    public function ovrBest(): void {}
}

[ad_2]

https://kinsta.com/nl/blog/php-8-3/