PHP 8.5 wyjdzie prawdopodobnie w listopadzie 2025. Proces RFC jest otwarty i kilka interesujących propozycji jest już w dyskusji lub głosowaniu. Przeglądam co ma realną szansę wejść, co jest wciąż dyskutowane i czego PHP developerzy najbardziej oczekują. Żadnych fake predictions – tylko to co widać w Internals liście i wiki.php.net.
Jak działa proces RFC w PHP
Każda zmiana w PHP przechodzi przez formalny RFC (Request for Comments) na wiki.php.net. RFC wymaga dyskusji przez minimum 2 tygodnie a następnie głosowania – 2/3 głosów „za” żeby przeszło. Core PHP Internals to ~20 aktywnych developerów którzy mają prawo głosu. Śledzę listę mailingową php-internals@lists.php.net i wiki.php.net/rfc jako podstawowe źródła.
Pipe Operator |> – po raz kolejny w dyskusji
Pipe operator to jedna z najbardziej pożądanych funkcji PHP – i jedna z najdłużej dyskutowanych bez finału. Po kolejnym RFC w 2024 jest szansa że 2025 będzie rokiem przełomu:
<?php
declare(strict_types=1);
// Bez pipe operator - zagnieżdżone wywołania lub zmienne tymczasowe
$result = array_filter(
array_map(
fn($item) => strtolower(trim($item)),
explode(',', $input)
),
fn($item) => strlen($item) > 2
);
// Lub z tymczasowymi zmiennymi - czytelniej ale verbose
$items = explode(',', $input);
$trimmed = array_map(fn($i) => strtolower(trim($i)), $items);
$filtered = array_filter($trimmed, fn($i) => strlen($i) > 2);
// Z pipe operator (jeśli przejdzie RFC) - sekwencyjny, czytelny
$result = $input
|> explode(',', $$)
|> array_map(fn($i) => strtolower(trim($i)), $$)
|> array_filter($$, fn($i) => strlen($i) > 2);
// Realny przykład w kontekście przetwarzania danych produktów
$processedSkus = $rawInput
|> trim($$)
|> strtoupper($$)
|> preg_replace('/[^A-Z0-9\-]/', '', $$)
|> array_filter([$$], fn($s) => strlen($s) >= 3)[0] ?? null;
Aktualny status: RFC jest w fazie discussion, nie voting. Główna przeszkoda to składnia – różne frakcje preferują różne formy (|> vs ->> vs partial application). Ostrożny optymizm na 2025.
Readonly klasy z dziedziczeniem – potencjalna zmiana
<?php
declare(strict_types=1);
// Aktualnie (PHP 8.2-8.4): readonly class nie może dziedziczyć po niereadonly
readonly class Address
{
public function __construct(
public string $street,
public string $city,
public string $postcode
) {}
}
// To jest BŁĄD w PHP 8.4:
class ExtendedAddress extends Address // Fatal Error!
{
public function __construct(
string $street,
string $city,
string $postcode,
public string $country = 'PL' // dodatkowe pole
) {
parent::__construct($street, $city, $postcode);
}
}
// RFC proponuje: readonly extends readonly - ok
readonly class InternationalAddress extends Address
{
public function __construct(
string $street,
string $city,
string $postcode,
public readonly string $country = 'PL'
) {
parent::__construct($street, $city, $postcode);
}
}
// Jeśli RFC przejdzie - Value Object hierarchie staną się możliwe
Named Arguments w define() i stałych
<?php // Mniejszy RFC ale przydatny - named arguments w większej liczbie kontekstów // Aktualnie niektóre wbudowane funkcje nie obsługują named args // Proponowane rozszerzenie zasięgu named arguments na: // - wszystkie funkcje wbudowane uniformly // - stałe wyrażenia (const contexts) // Przykład który działa dziś: $filtered = array_filter($items, callback: fn($i) => $i > 0); // Przykład który może nie działać (zależy od funkcji): // $formatted = number_format(num: 1234567.89, decimals: 2, decimal_separator: ',', thousands_separator: ' '); // Ta funkcja ma stare nazwy parametrów które PHP 8.4 już poprawia
Typed Constants in Interfaces – rozszerzenie z PHP 8.3
<?php
declare(strict_types=1);
// PHP 8.3 dodało typed constants w klasach
// RFC na 8.5 proponuje rozszerzenia:
// 1. Typed constants w Enum (aktualnie brak)
enum Status: string
{
// Aktualnie enum nie może mieć typed constants obok case'ów
// RFC proponuje:
const string DEFAULT = self::Active->value; // możliwe w 8.5?
case Active = 'active';
case Inactive = 'inactive';
}
// 2. Readonly typed constants (immutable after definition)
class Config
{
const readonly string VERSION = '2.4.8'; // RFC: readonly modifier dla stałych?
// W PHP 8.3 stałe są już de facto readonly - to bardziej explicit marker
}
Czego developerzy oczekują najbardziej – ankieta społeczności
JetBrains coroczna ankieta „State of Developer Ecosystem” i dyskusje na reddit/r/PHP pokazują spójny obraz oczekiwań:
| Feature | Szansa na PHP 8.5 | Komentarz |
|---|---|---|
| Pipe operator |> | Średnia | Wieloletnia dyskusja, może w końcu przejść |
| Generics / Templates | Niska | Brak RFC który zebrałby konsensus |
| Readonly class dziedziczenie | Wysoka | Logiczne uzupełnienie PHP 8.2 feature |
| First-class callable syntax poprawki | Wysoka | Drobne ale użyteczne usprawnienia |
| Pattern matching | Niska | match() już jest, pełny pattern matching to duże RFC |
| Async/await natywnie | Brak | Fibers to foundation, ale natywny async to lata pracy |
Generics – dlaczego PHP ich nie ma i czy kiedyś będzie
Generics to najczęściej wymieniana brakująca funkcja PHP. PHPStan i Psalm symulują je przez docblock (@template T), ale to nie jest wsparcie na poziomie języka. Problem jest fundamentalny:
<?php
// Generics przez PHPStan templates - działa dla statycznej analizy
/**
* @template T
*/
class Collection
{
/** @var T[] */
private array $items = [];
/**
* @param T $item
*/
public function add(mixed $item): void
{
$this->items[] = $item;
}
/**
* @return T|null
*/
public function first(): mixed
{
return $this->items[0] ?? null;
}
}
// PHPStan wie że to Collection
/** @var Collection $products */
$products = new Collection();
$products->add(new Product()); // ok
$products->add(new Order()); // PHPStan error!
$product = $products->first(); // PHPStan wie że to Product
// Problem: PHP engine nie weryfikuje typów w runtime
// Implementacja natywnych generics wymagałaby zmian w samym engine
// i jest technicznie znacznie trudniejsza niż dodanie nowej składni
Nikita Popov (jeden z głównych architektów PHP 8.x) napisał szczegółowo dlaczego generics w PHP są trudne technicznie. Krótko: reified generics (jak w Java) wymagają zmian w engine, erased generics (jak TypeScript) dają korzyści tylko przy statycznej analizie. PHP ma już drugie przez PHPStan/Psalm bez zmian w engine. Stąd niski priorytet.
Co obserwuję w php-internals
Kilka RFC które są w aktywnej dyskusji na początku 2025 i mają szansę na głosowanie przed Feature Freeze (jesień 2025):
- Deprecated dynamic properties cleanup – usunięcie AllowDynamicProperties behavior w PHP 9.0, ale deprecation w 8.5
- Array unpacking z string keys – rozszerzenie spread operatora
- Closure::bind improvements – drobne ergonomiczne poprawki
- Intersection types w więcej kontekstach – rozszerzenie PHP 8.1 feature
Podsumowanie
PHP 8.5 będzie ewolucją, nie rewolucją – jak przystało na wersję minor w dojrzałym języku. Pipe operator byłby największą zmianą jeśli przejdzie RFC. Readonly inheritance uzupełni logikę z 8.2. Generics pozostają marzeniem na papierze. Śledzę php-internals na bieżąco – zaktualizowany przegląd pojawi się gdy Feature Freeze zbliży się jesienią.
