PHP

PHP 8.6: Výchozí hodnoty u readonly vlastností

// obsah 2
  1. 01 K čemu je to dobré?
  2. 02 Na co si dát bacha?

Readonly vlastnosti měly od začátku jedno nenápadné omezení: nesměly mít výchozí hodnotu. PHP 8.6 ho ruší.

Když jsem tu před lety psal o readonly vlastnostech v PHP 8.1, tenhle kód skončil kompilační chybou (a v 8.5 pořád ještě skončí):

<?php

final readonly class ExportFaktur
{
    public string $nazev = 'export-faktur';
}

// Fatal error: Readonly property ExportFaktur::$nazev cannot have default value

Původní RFC to zakázalo s tím, že taková vlastnost je vlastně konstanta, takže je zbytečná. Technická překážka v tom nikdy nebyla a mezitím se ukázalo, že využití existuje.

K čemu je to dobré?

Hlavní důvod jsou interface s vlastnostmi, které přišly s property hooks v PHP 8.4. Konstantou takový kontrakt nesplníte, vlastností ano:

<?php

interface Migrace
{
    public string $nazev { get; }
}

final readonly class VytvorTabulkuUzivatelu implements Migrace
{
    public string $nazev = '2026_01_01_vytvor_tabulku_uzivatelu';
}

Dřív se musel napsat konstruktor, který nedělá nic jiného, než že do vlastnosti nasype napevno danou hodnotu:

<?php

final readonly class VytvorTabulkuUzivatelu implements Migrace
{
    public string $nazev;

    public function __construct()
    {
        $this->nazev = '2026_01_01_vytvor_tabulku_uzivatelu';
    }
}

Na co si dát bacha?

Výchozí hodnota se počítá jako první a zároveň poslední přiřazení. Vlastnost je inicializovaná ještě před během konstruktoru, takže v něm už ji přepsat nejde:

<?php

final readonly class ExportFaktur
{
    public string $nazev = 'export-faktur';

    public function __construct(string $nazev)
    {
        $this->nazev = $nazev; // Error: Cannot modify readonly property
    }
}

Z toho plynou dvě další věci. Takovou vlastnost nejde unset(), na rozdíl od neinicializované readonly vlastnosti. A splňuje jen kontrakt { get; }, ne { get; set; }.

RFC prošlo v poměru 24 : 0 (a 5 se zdrželo). Malá změna, ale ubyde konstruktorů, které existují jenom proto, že to jinak nešlo.

Zdroj: https://wiki.php.net/rfc/readonly_property_defaults

Michal Katuščák
Michal Katuščák

Navrhuji a vyvíjím aplikace nad Symfony a Reactem, zajímám se architekturu softwaru. Žiju v Českých Budějovicích.