Nowości w PHP 8.1 - Enums, Fibers i Readonly Properties
PHP 8.1, wydany 25 listopada 2021 roku, kontynuuje rewolucję rozpoczętą w PHP 8.0. Ta wersja wprowadza długo oczekiwane enumeracje, mechanizm współbieżności Fibers, właściwości tylko do odczytu oraz wiele innych ulepszeń, które czynią PHP jeszcze bardziej nowoczesnym i wydajnym językiem.
Dlaczego PHP 8.1?
PHP 8.1 rozbudowuje fundament stworzony przez PHP 8.0, dodając kolejne zaawansowane funkcje programowania obiektowego i funkcyjnego. Te nowości znacząco poprawiają bezpieczeństwo typu, czytelność kodu i możliwości tworzenia wydajnych aplikacji.
1. Enums - Wyliczenia
Enumeracje to jeden z najważniejszych dodatków do PHP 8.1. Pozwalają na definiowanie zamkniętego zbioru możliwych wartości, co eliminuje błędy związane z używaniem magicznych stringów i liczb.
<?php
// Podstawowy enum
enum Status
{
case Pending;
case Active;
case Suspended;
case Deleted;
}
// Enum z backed values (int/string)
enum OrderStatus: string
{
case Pending = 'pending';
case Processing = 'processing';
case Completed = 'completed';
case Cancelled = 'cancelled';
// Enums mogą mieć metody
public function label(): string
{
return match($this) {
self::Pending => 'Oczekujące',
self::Processing => 'W trakcie',
self::Completed => 'Zakończone',
self::Cancelled => 'Anulowane',
};
}
public function canBeCancelled(): bool
{
return $this === self::Pending || $this === self::Processing;
}
}
// Użycie
class Order
{
public function __construct(
private OrderStatus $status = OrderStatus::Pending
) {}
public function cancel(): void
{
if (!$this->status->canBeCancelled()) {
throw new \Exception('Cannot cancel this order');
}
$this->status = OrderStatus::Cancelled;
}
}
2. Readonly Properties - Właściwości Tylko do Odczytu
Właściwości readonly można ustawić tylko raz - zazwyczaj w konstruktorze. Po inicjalizacji nie można już ich modyfikować, co zapewnia immutability i bezpieczeństwo danych.
<?php
class User
{
public function __construct(
public readonly string $email,
public readonly string $username,
public readonly \DateTimeImmutable $createdAt,
) {}
}
$user = new User(
email: 'jan@example.com',
username: 'jkowalski',
createdAt: new \DateTimeImmutable()
);
// OK - odczyt działa
echo $user->email;
// Error - próba modyfikacji
$user->email = 'new@example.com'; // Fatal error
3. Fibers - "Green Threads"
Fibers to niskopoziomowy mechanizm do zarządzania współbieżnością. Pozwalają na zawieszanie i wznawianie wykonywania kodu, co ułatwia implementację asynchronicznego programowania bez callback hell.
<?php
$fiber = new Fiber(function (): void {
echo "Fiber start\n";
Fiber::suspend('value1');
echo "Fiber resumed\n";
Fiber::suspend('value2');
echo "Fiber end\n";
});
echo "Main start\n";
$value1 = $fiber->start(); // Wyświetla "Fiber start"
echo "Got: $value1\n";
$value2 = $fiber->resume(); // Wyświetla "Fiber resumed"
echo "Got: $value2\n";
$fiber->resume(); // Wyświetla "Fiber end"
echo "Main end\n";
// Output:
// Main start
// Fiber start
// Got: value1
// Fiber resumed
// Got: value2
// Fiber end
// Main end
4. First-class Callable Syntax
Nowa składnia do tworzenia callable z funkcji i metod. Zastępuje nieporęczne `Closure::fromCallable()` i array callables.
<?php
class UserService
{
public function save(User $user): void
{
// implementacja
}
}
$service = new UserService();
// PHP 8.1 - First-class callable
$callable = $service->save(...);
// PHP 8.0 - trzeba było używać
$callable = Closure::fromCallable([$service, 'save']);
$callable = [$service, 'save'];
// Użycie z array_map
$users = array_map($service->save(...), $userDataArray);
5. Intersection Types - Typy Przecięcia
Intersection types pozwalają wymagać, aby wartość implementowała kilka interfejsów jednocześnie. To uzupełnienie union types z PHP 8.0.
<?php
interface Loggable
{
public function log(): void;
}
interface Cacheable
{
public function cache(): void;
}
// Typ przecięcia - obiekt musi implementować oba interfejsy
function process(Loggable&Cacheable $object): void
{
$object->log();
$object->cache();
}
class User implements Loggable, Cacheable
{
public function log(): void { /* ... */ }
public function cache(): void { /* ... */ }
}
process(new User()); // OK
Inne ważne nowości w PHP 8.1
- Never type - typ dla funkcji, które nigdy nie zwracają wartości (zawsze throw lub exit)
- Final class constants - możliwość oznaczenia stałych klas jako final
- New in initializers - użycie new jako wartości domyślnej parametru
- Pure Intersection Types - pełne wsparcie dla typów przecięcia
🎓 Chcesz poznać wszystkie nowości PHP?
Ten wpis to fragment kompleksowego kursu PHP 8.4, w którym szczegółowo omawiam wszystkie wersje PHP 8.x wraz z praktycznymi przykładami z rzeczywistych projektów.