PHP 8.3 wprowadza szereg nowości, które mogą znacząco ułatwić życie programistom stosującym podejście Domain Driven Development (DDD). Pamiętam, jak kilka lat temu, podczas jednego z projektów, spędziłem godziny na implementacji skomplikowanych mechanizmów, które teraz można zrealizować kilkoma linijkami kodu. W tym artykule przyjrzymy się, jak nowe funkcjonalności PHP 8.3, takie jak ulepszone typowanie, lepsza obsługa błędów i nowe narzędzia do pracy z obiektami, mogą wspierać i upraszczać praktyki DDD. Gotowi na podróż do świata nowoczesnego PHP? Zaczynajmy!
Atrybuty w PHP 8.3
Atrybuty w PHP 8.3 to potężne narzędzie, które pozwala na dodawanie metadanych do klas, metod, funkcji i właściwości. Dzięki nim możemy lepiej organizować i zarządzać kodem, co jest szczególnie ważne w kontekście Domain-Driven Design (DDD). Atrybutów możemy użyć do oznaczania metod, które nadpisują metody z klasy bazowej, ale również do wielu innych celów, takich jak walidacja, autoryzacja czy dokumentacja.
Atrybut #[\Override]
Atrybut #[\Override] pozwala na oznaczanie metod, które nadpisują metody z klasy bazowej lub interfejsu. Dzięki temu, jeśli metoda w klasie bazowej zostanie zmieniona lub usunięta, PHP zgłosi błąd, co pomoże nam uniknąć niezamierzonych błędów w kodzie.
class BaseClass {
    public function foo() {}
}
class DerivedClass extends BaseClass {
    #[Override]
    public function foo() {}
}W powyższym przykładzie, metoda foo() w klasie DerivedClass jest oznaczona atrybutem #[\Override], co zapewnia, że jest zgodna z metodą w klasie bazowej.
Atrybut #[\Deprecated]
Atrybut #[\Deprecated] może być używany do oznaczania metod lub funkcji, które są przestarzałe i nie powinny być już używane. Jest to szczególnie przydatne w dużych projektach, gdzie deprecjonowanie starych metod może pomóc w przejściu na nowsze, bardziej efektywne rozwiązania.
class MyClass {
    #[Deprecated("Use newMethod() instead")]
    public function oldMethod() {
        // Stara implementacja
    }
    public function newMethod() {
        // Nowa implementacja
    }
}W tym przykładzie, metoda oldMethod() jest oznaczona jako przestarzała, a programiści są informowani, aby używali newMethod() zamiast niej.
Atrybut #[\Route]
Atrybut #[\Route] może być używany w kontekście frameworków webowych do oznaczania metod jako obsługujących określone ścieżki URL. Dzięki temu kod staje się bardziej czytelny i łatwiejszy do zarządzania.
class UserController {
    #[Route("/user/{id}", methods: ["GET"])]
    public function getUser(int $id) {
        // Logika pobierania użytkownika
    }
}W powyższym przykładzie, metoda getUser jest oznaczona atrybutem #[\Route], co jasno wskazuje, że obsługuje ona żądania GET dla określonej ścieżki URL.
Znaczenie atrybutów
Atrybuty w PHP 8.3 pozwalają na dodawanie dodatkowych informacji do kodu, co może znacznie ułatwić jego zrozumienie i utrzymanie. Dzięki nim można lepiej organizować kod, zapewniać zgodność z kontraktami i unikać błędów. W kontekście DDD, atrybuty mogą pomóc w jasnym definiowaniu zachowań domenowych, co prowadzi do bardziej spójnych i łatwiejszych do zarządzania aplikacji.
Readonly Classes w Domain-Driven Design (DDD)
Jedną z kluczowych nowości w PHP 8.3 jest możliwość oznaczania klas jako readonly. Oznacza to, że wszystkie właściwości takiej klasy są tylko do odczytu po ich inicjalizacji. W kontekście Domain-Driven Design (DDD), klasy tylko do odczytu mogą być niezwykle przydatne, szczególnie w implementacji komend i zapytań. Dzięki nim możemy zapewnić, że dane domenowe pozostają niezmienione po ich inicjalizacji, co jest kluczowe dla zachowania integralności i spójności modelu domenowego.
Komendy w DDD służą do zmiany stanu systemu. Mogą one reprezentować operacje takie jak tworzenie nowego użytkownika, aktualizowanie danych klienta itp. Używanie klas tylko do odczytu w komendach pomoże nam w zapewnieniu, że dane które przekazujemy do komendy nie zostaną zmienione podczas jej przetwarzania.
readonly class CreateUserCommand {
    public function __construct(
        public string $username,
        public string $email,
        public string $password
    ) {}
}
// Przykład użycia
$command = new CreateUserCommand('john_doe', 'john@example.com', 'securepassword');
// Próba zmiany wartości właściwości spowoduje błąd
// $command->email = 'new_email@example.com'; // Fatal error: Cannot modify readonly propertyW powyższym przykładzie, klasa CreateUserCommand jest tylko do odczytu, co oznacza, że dane przekazywane do komendy są zabezpieczone przed modyfikacją.
Deklaracja Typów Stałych w Klasach
PHP 8.3 wprowadza możliwość jawnego deklarowania typów dla stałych w klasach, interfejsach, traitach oraz enumach. Dzięki temu kod staje się bardziej czytelny i bezpieczny, co jest szczególnie ważne w kontekście DDD, gdzie precyzja i jasność modelu domenowego mają kluczowe znaczenie.
readonly class Foo {
    public const string BAR = 'baz';
}Funkcja json_validate()
Nowa funkcja json_validate() pozwala na sprawdzenie, czy dany ciąg znaków jest poprawnym formatem JSON, bez konieczności jego dekodowania. Jest to bardziej efektywne pod względem zużycia pamięci i czasu w porównaniu do tradycyjnej metody dekodowania i walidacji JSON. W kontekście DDD, może to być przydatne podczas walidacji danych wejściowych w aplikacjach korzystających z API. Już nie musimy kojrzystać z json_encode() i sprawdzać czy rzucił wyjątek/zwrócił null.
$json = '{"name": "John", "age": 30}';
$isValid = json_validate($json);Rozszerzenia Klasy Randomizer
Klasa Randomizer, wprowadzona w PHP 8.2, została rozszerzona o nowe metody, takie jak getFloat() oraz nextFloat(), które umożliwiają generowanie losowych liczb zmiennoprzecinkowych w określonym zakresie. W DDD, może to być użyteczne w kontekście generowania losowych identyfikatorów lub innych wartości, które muszą być unikalne. Na przykład, można użyć tych metod do tworzenia losowych tokenów sesji, które są trudne do przewidzenia i zapewniają dodatkowe bezpieczeństwo. Dodatkowo, w symulacjach lub testach, losowe dane mogą pomóc w sprawdzeniu, jak system zachowuje się w różnych scenariuszach. Metody te mogą również znaleźć zastosowanie w generowaniu losowych współrzędnych geograficznych w aplikacjach mapowych. Dzięki temu, programiści mają większą elastyczność i kontrolę nad generowaniem losowych wartości, co może znacząco poprawić jakość i bezpieczeństwo aplikacji
$randomizer = new Random\Randomizer(); $float = $randomizer->getFloat(0.1, 1.0);
Nowa Funkcja mb_str_pad()
Wprowadzono również funkcję mb_str_pad(), która jest odpowiednikiem str_pad() dla wielobajtowych ciągów znaków. Jest to szczególnie przydatne przy pracy z językami wykorzystującymi kodowania wielobajtowe, takimi jak UTF-8. W DDD, może to być użyteczne w kontekście formatowania danych wyjściowych. Na przykład, gdy pracujemy z danymi w różnych językach, mb_str_pad() zapewnia, że tekst będzie prawidłowo wyrównany niezależnie od używanego alfabetu. Dzięki temu, raporty i interfejsy użytkownika będą wyglądać spójnie i profesjonalnie. Funkcja ta może również pomóc w generowaniu czytelnych logów i komunikatów systemowych, co jest kluczowe dla utrzymania wysokiej jakości aplikacji. Wreszcie, mb_str_pad() ułatwia pracę z danymi wejściowymi i wyjściowymi w aplikacjach wielojęzycznych, co jest coraz bardziej istotne w globalnym środowisku biznesowym.
$padString = mb_str_pad("test", 10, " ", STR_PAD_RIGHT, "UTF-8");Inne Nowości i Poprawki
PHP 8.3 zawiera również szereg innych nowości i poprawek, takich jak:
- Dynamiczne pobieranie stałych klas i członków enum.
 - Nowe metody dla klasy 
DOMElementiIntlCalendar. - Nowe funkcje LDAP i POSIX.
 - Poprawki w obsłudze błędów funkcji 
unserialize(). 
Kompletną listę nowości i poprawek znajdziesz tutaj.
Podsumowanie
PHP 8.3 to kolejny krok naprzód w rozwoju tego popularnego języka programowania. Dzięki nowym funkcjom i ulepszeniom, praca programistów staje się jeszcze bardziej efektywna i przyjemna. W kontekście Domain-Driven Design, nowe możliwości, takie jak klasy tylko do odczytu, jawne deklaracje typów stałych, czy nowe funkcje walidacji JSON, mogą znacznie poprawić jakość i bezpieczeństwo kodu. Jeśli jeszcze nie zaktualizowaliście swojego środowiska do najnowszej wersji, teraz jest na to idealny moment. W końcu, kto by nie chciał, żeby jego kod był tak potężny jak słoń?
Pamiętaj że twój kod jest odzwierciedleniem twojej duszy, więc warto zadbać o statyczna analizę kodu!
