Přeskočit na obsah
Tech-Blog Chatujme.cz Chatujme.cz
Programování

Nette Application 3.3.1 převádí parametr z adresy na výčtový typ sám

Balíček nette/application vyšel ve verzi 3.3.1. Parametr akce, renderu, signálu i persistentní vlastnost presenteru smí mít nově typ výčtu s hodnotou: framework údaj z adresy na prvek výčtu převede sám a do odkazu zapíše jeho hodnotu. Starší verze z téhož výčtu udělala v adrese dvojici name a value.

· 1 zhlédnutí

Černý plyšový slon s růžovou hřívou a bílým logem PS na boku
Plyšový elePHPant, maskot PHP, v provedení s logem vývojového prostředí PhpStorm. Foto: Atomic Taco, Flickr (CC BY-SA 2.0)

Autoři Nette vydali balíček nette/application ve verzi 3.3.1. Packagist má u ní čas 5. listopadu 2026 ve 23:18 UTC, tedy krátce po půlnoci středoevropského času. Hlavní novinka zavírá požadavek, který v evidenci projektu ležel od dubna 2023: typ parametru stránky smí být výčet.

Výčet místo řetězce

Presenter dostává hodnoty z adresy dvěma cestami. Buď jako argument metody action…(), render…() nebo obsluhy signálu, anebo jako vlastnost označenou #[Persistent], kterou si framework přenáší z jedné stránky na druhou. Obojí dosud sneslo skalární typ nebo pole. Od verze 3.3.1 tam smí stát i výčtový typ s hodnotou, tedy výčet, jehož každý prvek nese řetězec nebo celé číslo. Samotné výčty umí PHP od verze 8.1; návrh, který je chtěl zavést i do filtrovacího rozšíření, vývojáři jazyka minulý týden v hlasování odmítli.

enum Sort: string
{
    case Asc = 'asc';
    case Desc = 'desc';
}

class TestPresenter extends Nette\Application\UI\Presenter
{
    #[Persistent]
    public Sort $sort = Sort::Asc;

    public function actionOther(Sort $dir = Sort::Asc): void
    {
    }
}

Převod jde oběma směry. Požadavek ?sort=desc naplní vlastnost prvkem Sort::Desc, a když se z presenteru skládá odkaz, zapíše se do adresy zpátky jen hodnota: $this->link('other', ['dir' => Sort::Desc]) i $this->link('other', ['dir' => 'desc']) dají touž adresu ?dir=desc&action=other&presenter=Test. Výchozí hodnota se do adresy nepíše vůbec, takže odkaz s Sort::Asc parametr dir neobsahuje. Všechny tři případy hlídá nová zkouška v repozitáři.

Co dělala starší verze

Hlášení nette/nette#1558 má datum 25. dubna 2023 a jeho název zní „Enum persistent changed to array“. Autor v něm ukázal presenter s persistentní vlastností typu OrderBy a odkaz {link default orderBy: OrderBy::DESC}. Starší Nette skládalo dotazovou část adresy přes metodu Route::objectsToArrays(), která každý objekt rozloží funkcí get_object_vars(). U prvku výčtu z toho vypadne pole se dvěma klíči, name a value, takže v adrese stálo sort[name]=Desc&sort[value]=desc místo sort=desc. Nazpátek se takový údaj na výčet nepřevedl, protože do presenteru dorazilo pole.

Kód, který to řeší, přibyl commitem 8af4b9d z 27. července 2026, hlášení se zavřelo 5. srpna 2026 a vydání přišlo o tři měsíce později. Převod do adresy obstarává LinkGenerator, který si u každého argumentu sáhne na ->value, opačný směr má na starost třída ParameterConverter.

Bezeztrátový převod, jinak 404

Z adresy přijde vždycky řetězec, takže framework dělá dva kroky za sebou. Nejdřív řetězec převede na typ, kterým je výčet podložený, a to jen tehdy, když se při tom nic neztratí. Teprve pak na výsledek zavolá tryFrom(). Když selže kterýkoli z těch kroků, skončí požadavek chybou 404 a u persistentní vlastnosti k tomu hláškou Value passed to persistent parameter 'sort' in presenter Test must be Sort, string given.

Hodnota v adreseTyp parametruVýsledek
ascvýčet nad řetězci, prvek s hodnotou ascprvek výčtu
bogustýž výčet404
1výčet nad čísly, prvek s hodnotou 1prvek výčtu
1.0týž výčet nad čísly404
2týž výčet nad čísly404
pole hodnotkterýkoli výčet404

Řádek s 1.0 je ten zajímavý: celé číslo z textu 1 vznikne beze ztráty, kdežto 1.0 už ne, takže se parametr odmítne, i když by po zaokrouhlení prvku výčtu odpovídal. Čistý výčet bez hodnot se jako typ parametru použít nedá – celý převod stojí na metodě tryFrom(), kterou mají jen výčty s hodnotou.

Co ještě je ve vydání

Mezi verzemi 3.3.0 z konce června a 3.3.1 je 38 commitů. Kromě výčtů přibylo tohle:

  • composer.json nově povoluje PHP 8.3 až 8.6; verze 3.3.0 končila u 8.5. Starší řada 3.2.13 z 2. listopadu 2026 snese PHP 8.1 až 8.6.
  • Konstanty Request::FORWARD, RESTORED a VARYING se píšou Request::Forward, Restored a Varying. Staré názvy dál fungují.
  • Zápis {control menu $items} bez čárky před argumenty hlásí E_USER_DEPRECATED; správně je {control menu, $items}, stejně jako to už dřív chtěly značky {form}, {input} a {label}.
  • Vlastnost s #[Parameter] bez výchozí hodnoty dostane null, pokud je nullable, a prázdné pole, pokud je typovaná jako array. Jinak požadavek skončí chybou 4xx. Dřív zůstala vlastnost neinicializovaná a čtení z ní shodilo stránku chybou 500.
  • Požadavek s vyhrazenou metodou FORWARD aplikace odmítne, protože se jím dalo dosáhnout rovnou na chybový presenter. Nahlásil to Jakub Richtr a oprava je i ve verzi 3.2.13.
  • FileResponse posílá hlavičku Content-Range jen u částečné odpovědi 206 a u odpovědi 416 uvádí velikost souboru, jak žádá RFC 9110. Ze jména souboru v Content-Disposition odstraní uvozovky, zpětná lomítka a řídicí znaky.

Výčty zůstávají jen v řadě 3.3, která chce PHP 8.3 a výš. Kdo zůstává na 3.2, dostal z tohohle vydání opravy, ale převod parametru si musí napsat sám.

Zdroje

Programování

PHP Nette framework routing výčtové typy

← zpět na výpis