Přejít k navigační liště

Zdroják » PHP » Symfony po krůčkách – Paralýza možností? OptionsResolver tě zachrání

Symfony po krůčkách – Paralýza možností? OptionsResolver tě zachrání

Články ‐ ‐ PHP ‐

Abychom podpořili klidnou vánoční náladu, vybrali jsme pro dnešní díl jednu z nejjednodušších Symfony komponent – OptionsResolver. Co to je? `Array_replace` na steroidech. Oproti němu má navíc pár užitečných metod – ty se postarají o to, aby hodnoty byly validní, a zajistí i normalizaci.

Kdy se OptionsResolver hodí?

1.  Jestli jsi někdy navrhoval REST API, možná znáš:

<?php

$options = [
    'page' => isset($input['page']) ? $input['page'] : 1,
    'type' => isset($input['type']) ? $input['type'] : 'product'
];

2. Nebo jsi dělal CLI aplikaci, která má mnoho vstupních hodnot – jako např. PHP_CodeSniffer:

$ php phpcs [-nwlsaepvi] [-d key[=value]] [--colors] [--no-colors] [--report=<report>] [--report-file=<reportFile>] [--report-<report>=<reportFile>] [--report-width=<reportWidth>] [--generator=<generator>] [--tab-width=<tabWidth>] [--severity=<severity>]...

3. A nebo modul se složitějším nastavením – jako např. rozšíření pro Doctrine:

// config.yml / config.neon
doctrine:
    orm:
    database: …
    password: …
    port: …
       entity_manager:
          one:
             ...

Co mají tyto příklady společného?

Mají mnoho vstupních hodnot:

  • ty mohou nabývat různých stavů
  • potřebují validaci typu (např. řetězec, číslo…,) nebo vůči seznamu hodnot (např. buď „ano“ nebo „ne“)
  • vyžadují normalizaci, aby se s nimi dále pracovalo lépe (např. doplnění relativní cesty na absolutní)
  • někdy mají defaultní hodnoty, jindy ne

Takový jednoduchý validátor jistě zvládne napsat každý. Jestli jsi ale v situaci, kdy s kódem pracuje více lidí, hodí se zvolit nějaké ověřené řešení. To by mělo mít dokumentaci a určité normy.

V těchto situacích ti přijde vhod OptionsResolver.

Jak vypadá použití v praxi?

Použití v praxi najdeš u ApiGenu. Pokud ho neznáš, Je to CLI aplikace, která generuje API dokumentaci zdrojového kódu.

Jako vstup má až přes 20 možností různých typů, mezi nimi pole, text nebo bool.

Každá nevalidní hodnota vede k ukončení běhu aplikace. S tím nám OptionsResolver pomůže. Jak? Mrkni na třídu ConfigurationOptionsResolver.

Krátký příklad

Vrátíme se k úvodnímu příkladu s REST API:

$options = [
    'page' => isset($input['page']) ? $input['page'] : 1,
    'type' => isset($input['type']) ? $input['type'] : 'clothes';
];

Na něm si ukážeme 3 hlavní featury této komponenty:

  • nastavení defaultních hodnot
  • validaci
  • normalizaci

Nejdříve si komponentu nainstalujeme přes composer:

$ composer require symfony/options-resolver

Přidáme autoloader a vytvoříme novou instanci OptionsResolveru:

// index.php
require_once __DIR__.'/vendor/autoload.php';

// $input = …;

$optionsResolver = new Symfony\Component\OptionsResolver\OptionsResolver;

1. Nastavení defaultních hodnot

Výše uvedené použití isset() nahradí metoda setDefaults():

$optionsResolver->setDefaults([
    'page' => 1,
    'type' => 'clothes'
]);

$options = $optionsResolver->resolve($input);

Co to udělá se vstupy?

$input = [];
// $options: 'page' => 1, type' => 'clothes'

$input = ['page' => 2];
// $options: 'page' => 2, 'type' => 'clothes'

$input = ['missing’ => 5];
// Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException

Přesně tak, OptionsResolver nám ošetří hodnoty, které nejsou povolené. To nám pomůže k lepší bezpečnosti aplikace.

Pro tip: Jako defaultní hodnotu můžeš použít i callback.

$optionsResolver->setDefault('page', function (Options $options) {
    return ('clothes’ === $options['type']) ? 1 : 2;
});

Pro tip 2: A jestli chceš přidat možnost bez defaultní hodnoty, tak takhle:

$optionsResolver->setDefined('wrapper');

2. Validace

Někde nám chce někdo zadat data, o která zrovna nestojíme. Pojďme si je zvalidovat.

$optionsResolver->setAllowedTypes('page', 'int');

Můžeme přidat i více typů:

$optionsResolver->setAllowedTypes('page', ['int', 'float']);

Povolené hodnoty taxativně vyjmenovat:

$optionsResolver->setAllowedTypes('page', [1, 2, 3, 4, 5]);

Nebo stejné omezení jako výše, ale zapsané pomocí callbacku:

$optionsResolver->setAllowedTypes('page', function ($value) {
     return $value >= 1 && $value <= 5;
));

3. Normalizace

Co to znamená? Normalizace je jakákoliv úprava dat po tom, co byla zvalidována. V našem případě zajistíme, aby se při vyžádání větší než povolené stránky zobrazila 10. strana.

$optionsResolver->setNormalizer('page', function ($options, $value) {
    $maxPage = 10;
    if ($value > 10) {
        return $maxPage;
    }

    return $value;
});

A jsi zase o krok dál…

Dnes jsme si ukázali komponentu, která nám v chaosu mnoha možností pomůže udržet jasný směr.

Teď už víš, že OptionsResolver ti umožní:

  • nastavit defaultní hodnoty
  • validovat vstupy
  • normalizovat hodnoty, pokud potřebují ještě nějaké modifikace
  • a že se hodí při psaní složitější CLI aplikace, REST API nebo nějaké konfigurace

 

Chceš vědět víc?

Potřebuješ poznat OptionsResolver do hloubky? Mrkni na oficiální dokumentaci.

 

Příští pondělí si dáme vánoční volno a pak budeme v seriálu opět pokračovat.

Krásné Vánoce vám všem!

Komentáře

Odebírat
Upozornit na
guest
8 Komentářů
Nejstarší
Nejnovější Nejvíce hlasů
tacoberu

Tohle je dost dobrý. Určitě vyzkouším.

soundczeck

Díky za seriál o Symfony!

radoslavius

Při použítí FOSRestBundle lze použít přes anotace obdobnou funcionalitu param fetcher – http://symfony.com/doc/current/bundles/FOSRestBundle/param_fetcher_listener.html

Diskobolos

… jsi opustil Nette a dal prednost Symfony? Nerypu, jen me zajimaji fakticke argumenty. Diky za odpoved.

Zahoďte knihovny: dropdowny, tooltipy a přechody stránek jen s HTML a CSS

Rozbalovací menu, tooltip, modální okno a plynulý přechod mezi stránkami. Ještě nedávno čtyři důvody, proč do projektu přidat několik knihoven a desítky kilobajtů JavaScriptu. V roce 2026 už to všechno zvládne prohlížeč sám. Ukážeme si, jak na to s Popover API, CSS anchor positioningem a View Transitions, a také kde mají své limity.

Rok po Shai-Hulud: co se změnilo na npm a co musíte udělat do ledna

Před rokem začal registrem npm procházet samošířící červ Shai-Hulud. Od té doby se útoky na dodavatelský řetězec JavaScriptu staly pravidelnou záležitostí a npm postupně přepisuje pravidla publikování. Projdeme, co se za ten rok stalo, jak dnes bezpečně publikovat balíček, co musíte stihnout do ledna 2027 a jak se bránit jako uživatel balíčků.

Vercel zrychlil směrování v CDN. Překvapivě pomohly menší bloky

Vercel zrychlil směrování v CDN tím, že začal načítat víc dat najednou. U velkých webů mu po každém nasazení scházely v cache údaje o mnoha jednotlivých cestách, takže je musel opakovaně dohledávat. U nových bloků metadat Vercel naměřil o 91 % kratší dobu tohoto hledání v 99. percentilu. Cesta k výsledku ale vedla přes nečekané zjištění: příliš velký blok se při vyřizování požadavků nevyplatil.