Nativní Enumy, výraz match a jak funguje PSR-4 v composer.json
Osvojte si string-backed enumy pro bezpečné reprezentace stavů, nahraďte nespolehlivý switch striktním výrazem match a pochopte, jak Composer přes PSR-4 mapuje třídy na soubory.
Nativní Backed Enumy v moderním PHP
Dříve se pevné množiny stavů (např. obtížnost modulu nebo fáze životního cyklu) v PHP řešily pomocí tříd s konstantami:
// Zastaralý přístup:
class OldDifficulty {
public const BEGINNER = 'beginner';
public const ADVANCED = 'advanced';
}
function setDifficulty(string $difficulty) {} // Žádná typová kontrola! Můžete předat 'xyz'.
Od PHP 8.1 máme k dispozici nativní Enumy. Pokud enum reprezentuje skalární hodnotu (např. uloženou v databázi), použijeme Backed Enum:
enum ModuleDifficulty: string
{
case Beginner = 'beginner';
case Intermediate = 'intermediate';
case Advanced = 'advanced';
}
Výhody:
- Typová bezpečnost: Funkce vyžadující
ModuleDifficultyodmítne jakýkoliv neplatný řetězec. - Vlastní metody: Enum v PHP není jen tupý seznam hodnot – může obsahovat metody, rozhraní a bohaté chování.
- Přístup k hodnotě: Hodnotu získáte přes
$enum->value, název konstanty přes$enum->name.
Výraz match: Moderní, striktní náhrada za switch
Tradiční konstrukce switch v PHP trpí několika závažnými problémy:
- Používá slabé porovnávání (
==), což způsobuje bizarní chyby při porovnávání řetězců a čísel. - Vyžaduje klíčové slovo
break, jinak propadává do dalších větví (fall-through). - Nevrací hodnotu přímo jako výraz.
V PHP 8.0 přišel výraz match:
public function label(): string
{
return match ($this) {
self::Beginner => 'Začátečník',
self::Intermediate => 'Pokročilý',
self::Advanced => 'Architekt / Produkce',
};
}
Klíčové vlastnosti výrazu match:
- Striktní porovnání: Vždy používá operátor identity
===. - Návratová hodnota: Je to plnohodnotný výraz (expression), jehož výsledek můžete přímo vrátit (
return match) nebo přiřadit do proměnné. - Exhaustiveness check: Pokud některý stav enumu nepokryjete a neuvedete větev
default, PHP vyhodí výjimkuUnhandledMatchError. To je obrovská výhoda – pokud do enumu přidáte novou hodnotu, PHP engine i statická analýza (Larastan) vás okamžitě upozorní na všechna místa, kde chybí její obsluha.
Jak funguje PSR-4 Autoloading v composer.json
Aby PHP engine věděl, kde na disku najít třídu App\Enums\ModuleDifficulty, využívá standard PSR-4 definovaný v souboru composer.json:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
}
Pravidlo funguje následovně:
- Prefix jmenného prostoru
App\odpovídá kořenové složceapp/. - Každé další zanoření v namespace odpovídá podadresáři se stejným názvem.
- Třída
App\Enums\ModuleDifficultyse proto musí nacházet v souboruapp/Enums/ModuleDifficulty.php.
Při instalaci nebo po spuštění příkazu composer dump-autoload vygeneruje Composer optimalizovanou mapu do složky vendor/composer/autoload_psr4.php. Když kód poprvé použije třídu, registrovaný Composer autoloader bleskově vyhledá a načte příslušný soubor.
<?php
declare(strict_types=1);
namespace App\Enums;
// Ukázka string-backed enumu s výrazem match (app/Enums/LifecyclePhase.php)
enum LifecyclePhase: string
{
case Entry = 'entry';
case Bootstrap = 'bootstrap';
case Container = 'container';
case Routing = 'routing';
case Middleware = 'middleware';
case Controller = 'controller';
case Domain = 'domain';
case Database = 'database';
case View = 'view';
case Testing = 'testing';
case Deployment = 'deployment';
// Elegantní mapování pořadí kroků pomocí striktního výrazu match
public function stepOrder(): int
{
return match ($this) {
self::Entry => 1,
self::Bootstrap => 2,
self::Container => 3,
self::Routing => 4,
self::Middleware => 5,
self::Controller => 6,
self::Domain => 7,
self::Database => 8,
self::View => 9,
self::Testing => 10,
self::Deployment => 11,
};
}
}
🎯 Ověření znalostí z lekce
Kvíz otestuje pochopení architektury a reálného kódu probíraného v této lekci.
Jaký je zásadní rozdíl v porovnávání hodnot mezi výrazem match a konstrukcí switch v PHP?
Jak v PHP získáte podkladovou skalární hodnotu z backed enumu ModuleDifficulty::Beginner?
Co přesně vyjadřuje konfigurace "App\": "app/" v sekci autoload.psr-4 souboru composer.json?
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace App\Enums; |
| 6 | |
| 7 | enum ModuleDifficulty: string |
| 8 | { |
| 9 | case Beginner = 'beginner'; |
| 10 | case Intermediate = 'intermediate'; |
| 11 | case Advanced = 'advanced'; |
| 12 | |
| 13 | public function label(): string |
| 14 | { |
| 15 | return match ($this) { |
| 16 | self::Beginner => 'Začátečník', |
| 17 | self::Intermediate => 'Pokročilý', |
| 18 | self::Advanced => 'Architekt / Produkce', |
| 19 | }; |
| 20 | } |
| 21 | |
| 22 | public function badgeClass(): string |
| 23 | { |
| 24 | return match ($this) { |
| 25 | self::Beginner => 'bg-emerald-500/10 text-emerald-400 ring-1 ring-inset ring-emerald-500/20', |
| 26 | self::Intermediate => 'bg-amber-500/10 text-amber-400 ring-1 ring-inset ring-amber-500/20', |
| 27 | self::Advanced => 'bg-rose-500/10 text-rose-400 ring-1 ring-inset ring-rose-500/20', |
| 28 | }; |
| 29 | } |
| 30 | } |
| 31 | |