Typově bezpečný přístup k polím v PHP: 4násobné zrychlení bez újmy na čitelnosti
Knihovna sbwerewolf/language-specific ve verzi 10.4.5 dosáhla 4násobného zrychlení oproti verzi 8.4.1. Zpoždění oproti knihovně wplake/typed (verze 1.2.2) se snížilo na 2×. První přístup používá řetězcové cesty, druhý využívá řetězení metod pro navigaci v datové struktuře.
Příklad s wplake/typed:
use Wplake\Typed\Typed;
$response = file_get_contents(
'https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json'
);
$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);
$path = 'response.GeoObjectCollection.featureMember.0.GeoObject.metaDataProperty.GeocoderMetaData.Address.formatted';
// hodnota s fallbackem
$val = Typed::string($object, $path, 'Adresa nenalezena');
var_dump($val);
/*
string(77)
"1, Mohammed Bin Rashid Boulevard, Downtown Dubai, Dubai, United Arab Emirates"
*/
$isReal = Typed::stringOrNull($object, $path) !== null;
var_dump($isReal);
/* bool(true) */
Obdobná funkcionalita v sbwerewolf/language-specific:
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;
$response = file_get_contents('https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json');
$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);
$data = new AdvancedArrayFactory()->makeAdvancedArray($object);
$formatted = $data
->pull("response")
->pull("GeoObjectCollection")
->pull("featureMember")
->pull()
->pull("GeoObject")
->pull("metaDataProperty")
->pull("GeocoderMetaData")
->pull("Address")
->get("formatted")
->default("Adresa nenalezena");
$val = $formatted->str();
var_dump($val);
/*
string(77)
"1, Mohammed Bin Rashid Boulevard, Downtown Dubai, Dubai, United Arab Emirates"
*/
$isReal = $formatted->isReal();
var_dump($isReal);
/* bool(true) */
Benchmarky výkonu
Testování probíhalo na reálných scénářích: parsování JSON v happy path, chybějící cesta, kontrola existence prvku, typování hodnot.
| Scénář | 8.4.1 (původně) | 10.4.5 (nyní) | 1.2.2 (wplake/typed) |
|--------|------------------|----------------|-----------------------|
| Parsování JSON – happy path | 29,210 µs/op | 6,467 µs/op | 3,013 µs/op |
| Parsování JSON – chybějící cesta | 18,716 µs/op | 5,987 µs/op | 1,766 µs/op |
| Existuje prvek? | 27,237 µs/op | 6,277 µs/op | 2,863 µs/op |
| Získat typ hodnoty | 28,581 µs/op | 6,740 µs/op | 2,966 µs/op |
| Získat hodnotu jako takovou | 30,395 µs/op | 6,558 µs/op | 3,015 µs/op |
| Získat všechny skalární hodnoty | 5,897 µs/op | 1,878 µs/op | nepodporováno |
| Získat všechny pole | 7,136 µs/op | 2,431 µs/op | nepodporováno |
Novinky ve verzi 10.4.5: extrakce všech skalárních hodnot a polí – funkce, kterou wplake/typed neumožňuje.
Klíčové architektonické změny
- Neměnnost
CommonValue: třída je nyní neměnná – po nastavení výchozí hodnoty již nedochází k mutacím. - Deterministické
pull(): při extrakci prvku z pole je vždy vrácen první prvek – odstraněna nejednoznačnost. - Zjednodušení API: pomocné třídy byly odstraněny, veškerá logika běží v jediném toku.
Zpětná kompatibilita je formálně porušena kvůli major verzi (8.4.1 → 10.4.5), avšak veřejné API zůstalo beze změny. Kód konzumentů nevyžaduje úpravy.
Nové metody a možnosti
Kompletní seznam metod řetězení:
pull(string $key)– extrahuje vnořený prvekpull()– první prvek pole (deterministicky)get(string $key)– získá hodnotu s kontrolou existencedefault(mixed $fallback)– výchozí hodnota při chybějící položcestr()– převede na řetězecisReal()– ověří, zda hodnota existuje
Příklad komplexního použití pro zpracování odpovědí API s nestabilní strukturou.
Co je důležité
- 4násobné zrychlení oproti základní verzi, zpoždění za lídrem je jen 2×.
- Zachována čitelnost řetězení metod místo nepřehledných řetězcových cest.
- Přidané unikátní funkce: sběr všech skalárů a polí.
- Neměnnost a determinismus zvyšují spolehlivost kódu.
- Ideální pro middle a senior vývojáře: typová bezpečnost kombinovaná s vysokým výkonem.
— Editorial Team
Zatím žádné komentáře.