Alleen-lezen-eigenschappen gebruiken in PHP 8.1

0
204

PHP 8.1 voegt ondersteuning toe voor een alleen-lezen modifier op klasse-eigenschappen. Een eigenschap die op deze manier is getagd, kan maar één keer worden ingesteld. Als u probeert de waarde van een alleen-lezen eigenschap te wijzigen na initialisatie, wordt een fout gegenereerd.

“Readonly” is nogal een vage term, met verschillende implicaties in individuele programmeertalen. In deze context is “alleen-lezen” betekent echt “onveranderlijk”—je kunt de waarde van een eigenschap instellen, maar deze kan daarna niet meer worden gewijzigd.

Alleen-lezen-eigenschappen schrijven

Voeg de alleen-lezen modifier toe om een ​​eigenschap alleen-lezen te maken. Het moet tussen de toegangsmodifier van de eigenschap en de typehint worden geplaatst.

class Demo {   openbare tekenreeks $Veranderbaar;   openbare alleen-lezen tekenreeks $Immutable;   publieke functie __construct( tekenreeks $Veranderlijk, tekenreeks $Onveranderlijk) {   $dit -> veranderlijk = $ veranderlijk; $dit -> Onveranderlijk = $ Onveranderlijk; }   }

$Mutable is een regulier openbaar bezit. Je kunt de waarde ervan op elk moment wijzigen, zowel binnen klassenmethoden als van buitenaf:

$demo = nieuwe demo("A", "X"); $demo -> Veranderlijk = "B";

$Onveranderlijk is een beetje anders. Je kunt de waarde nog steeds lezen wanneer je maar wilt, maar eventuele wijzigingen mislukken met een Error:

//Geeft een Error $demo -> Onveranderlijk = "Y"; Advertentie

De alleen-lezen modifier wordt ook ondersteund in gepromote constructoreigenschappen:

class Demo { publieke functie __construct( openbare alleen-lezen string $Immutable="foobar" ) {} }

U kunt de eigenschap nog steeds handmatig instellen in uw constructor wanneer u promotie gebruikt met een standaardwaarde. Het is de functieparameter die de standaardwaarde ontvangt, niet de eigenschapsinstantie. De promotie vervalt met dezelfde code als in het eerdere voorbeeld.

Voorbehouden

Alleen-lezen-eigenschappen zijn een eenvoudige syntaxisverbetering die u op uw gemak kunt toepassen. Er zijn geen gevolgen voor achterwaartse compatibiliteit en het gebruik ervan is volledig optioneel. Als je ze wel begint toe te voegen, zijn er een paar kanttekeningen en beperkingen waar je rekening mee moet houden.

In tegenstelling tot gewone eigenschappen, mogen alleen-lezen eigenschappen geen standaardwaarde in hun definitie hebben:

p> klasse Demo { beveiligde alleen-lezen string $foo = "bar"; }

Deze verklaring definieert en initialiseert $foo. U kunt de waarde na initialisatie niet wijzigen, dus de eigenschap is in feite een constante. Als gevolg hiervan worden standaardwaarden verbannen en moet u in plaats daarvan een echte constante gebruiken:

klasse Demo { const foo = "bar"; }

Als gevolg van deze beperking wordt alleen-lezen alleen ondersteund voor getypte eigenschappen. De volgende eigenschap heeft een illegale definitie:

class Demo { beveiligde alleen-lezen $foo; } Advertentie

Een eigenschap zonder type, zoals $foo hierboven, heeft een impliciete standaardwaarde van null. Als alleen-lezen was toegestaan, zouden de “geen impliciete constanten” regel zou weer opduiken. Getypte eigenschappen maken onderscheid tussen “niet-geïnitialiseerde” en “null” staten, dus ze bestaan ​​zonder enige waarde totdat je er expliciet een instelt.

De alleen-lezen modifier heeft speciale regels wanneer gebruikt als onderdeel van klasse-overerving. Onderliggende klassen kunnen alleen-lezen toevoegen of verwijderen voor eigenschappen die door hun ouders zijn gedefinieerd.

Het alleen-lezen van een beschrijfbare eigenschap zou de bovenliggende klasse breken als de methoden de waarde muteerden. Hoewel het verwijderen van de beperking schijnbaar onschuldig is, beschouwt de RFC alleen-lezen als een “opzettelijke beperking” van mogelijkheden die verloren zouden gaan als overschrijvingen door overerving waren toegestaan. Het is verboden zodat ouderklassen kunnen beweren dat kinderen geen bijwerkingen kunnen veroorzaken door eigenschappen te wijzigen die bedoeld zijn om alleen-lezen te zijn.

Alleen-lezen-eigenschappen kunnen alleen worden ingesteld binnen het bereik waarin ze zijn gedefinieerd. Dit betekent dat openbare eigenschappen niet van buiten een klasse kunnen worden ingesteld, zelfs als ze niet eerder zijn geïnitialiseerd:

klasse Demo { openbare alleen-lezen string $foo; }   $d = nieuwe demo(); $d -> foo = "bar"; //illegale

Initialisatie moet plaatsvinden binnen de klasse die de eigenschap definieert. Als gevolg hiervan liggen alleen-lezen-eigenschappen dichter bij de onveranderlijke velden van andere programmeertalen, in tegenstelling tot reeds bestaande PHP-eigenschappen.

De alleen-lezen-modifier is gelijkelijk van toepassing op alle schrijfbewerkingen. Het maakt geen onderscheid tussen interne en externe toegang. U kunt geen eigenschap hebben die openbaar alleen-lezen is maar binnen de klasse kan worden geschreven, hoewel een toekomstige specificatie-extensie dit zou kunnen toestaan.

Advertentie

Een laatste probleem betreft het kloon-trefwoord. Deze code werkt niet:

class Demo { publieke functie __construct( openbare tekenreeks $foo ) {} }   $d = nieuwe demo("bar"); $d2 = kloon $d; $d2 -> foo = "foobar";

Klonen volgt dezelfde regels als reguliere toegang tot eigendommen. Hoewel de wijziging naar foobar de eerste keer is dat foo wordt geopend op $d2, is de eigenschap al geïnitialiseerd door het kloonproces. Er is een impliciete initialisatie tijdens de kloon.

Wanneer gebruik je Readonly-eigenschappen?

Alleen-lezen-eigenschappen zullen het maken van eenvoudige klassen, die gegevensstructuren vertegenwoordigen, aanzienlijk versnellen. Het is gebruikelijk om wegwerpklassen te schrijven om HTTP-verzoekparameters, gegevensoverdrachtobjecten en responsgegevens te bewaren. Deze zijn doorgaans onveranderlijk, waarbij van eigenschappen niet wordt verwacht dat ze veranderen nadat de klasse is geconstrueerd.

Voorheen had je twee onaantrekkelijke keuzes bij het schrijven van struct-achtige klassen: gebruik openbare eigenschappen, versnel de ontwikkeling maar laat het toe wijziging, of besteed tijd aan het handmatig toevoegen van getter-methoden om beschermde eigenschappen bloot te leggen.

//Niet ideaal – Eigenschappen kunnen extern worden gewijzigd klasse UserCreationRequest { publieke functie __construct( openbare tekenreeks $Gebruikersnaam, openbare tekenreeks $Wachtwoord ) {} }   //Ook niet ideaal – Veel standaard codeklasse UserCreationRequest { publieke functie __construct( beveiligde tekenreeks $Gebruikersnaam, beveiligde tekenreeks $Wachtwoord ) {}   openbare functie getUsername() : tekenreeks { retourneer $this -> gebruikersnaam; }   openbare functie getPassword() : tekenreeks { retourneer $this -> Wachtwoord; } }

Alleen-lezen-eigenschappen maken eindelijk de ideale aanpak mogelijk:

klasse UserCreationRequest { publieke functie __construct( openbare alleen-lezen tekenreeks $Gebruikersnaam, openbare alleen-lezen tekenreeks $Wachtwoord ) {} }

De eigenschappen zijn openbaar toegankelijk maar onveranderlijk. Gecombineerd met de promotie van de constructorproperty, beloven alleen-lezen eigenschappen de boilerplate-code aanzienlijk af te slanken, waardoor u sneller nuttige klassen kunt schrijven.

readonly helpt ook de leesbaarheid van de code en geeft beter uw bedoelingen aan. Iedereen die de klasse UserCreationRequest leest of bewerkt, weet dat de eigenschappen niet bedoeld zijn om te veranderen. In het eerste voorbeeld is het onbekend of andere code in het project de klasse-eigenschappen rechtstreeks wijzigt. Het tweede voorbeeld is iets duidelijker, maar kan een ontwikkelaar er nog steeds toe aanzetten om redundante methoden setUsername() en setPassword() te implementeren.

Conclusie

De alleen-lezen modifier brengt ingebouwde onveranderlijkheidsondersteuning voor PHP-klasse-eigenschappen. Het maakt uw code duidelijker en voorkomt onbedoelde waardeveranderingen door onveranderlijkheid tijdens runtime af te dwingen.

Advertentie

Terugkijkend op de PHP 7-releaseserie, een basisstructuur-achtige klasse creëren die wordt gebruikt om getypte eigenschappen te definiëren, een constructor schrijven die die eigenschappen instelt en vervolgens getter-methoden toevoegen om hun waarden bloot te leggen. Met PHP 8.1 kun je dat allemaal terugbrengen tot een enkele constructorhandtekening door public readonly en propertypromotie te combineren.

Readonly-eigenschappen zijn geïmplementeerd in de nieuwste PHP 8.1-ontwikkelingsbuilds. De productieklare release komt in november 2021 aan.