PHP 8.5(12.20125)

Встроенный парсер URL

🔗 URI — встроенный парсер URL

				
					$uri = new Uri('https://user:pass@phpdock.ru:8080/path?k=v#frag');
echo $uri->getHost();      // 'phpdock.ru'  
echo $uri->getPort();      // 8080  
echo $uri->getUserInfo();  // 'user:pass'  
echo $uri->withPath('/new')->__toString(); // новый URI, не мутирует оригинал
				
			

→ Реализует WHATWG URL Standard (а не RFC 3986).
→ $uri->getQuery() возвращает без ?, как parse_url().

Pipe operator

🚰 |> — pipe operator

Было:

				
					$result = htmlspecialchars(
    mb_strtolower(
        trim($input)
    )
);
				
			

Стало:

				
					$result = $input |> trim(...) 
                 |> mb_strtolower(...) 
                 |> htmlspecialchars(...);
				
			

→ ... = placeholder аргумента (только один, первым).
→ Можно комбинировать с именованными аргументами:

				
					$arr |> array_map(fn($x) => $x * 2, ...) 
     |> array_filter(..., fn($x) => $x > 5);
				
			

Для readonly-объектов

🧬 clone($obj, [‘prop’ => $val])

				
					readonly class Color {
    public function __construct(
        public int $r,
        public int $g,
        public int $b,
        public ?int $alpha = null
    ) {}
}

$red = new Color(255, 0, 0);
$semiRed = clone($red, ['alpha' => 128]); // ✅
// $red->alpha = 128; // ❌ запрещено
				
			

→ Создаёт новый объект, не мутирует оригинал.
→ Только для public-свойств.

NoDiscard

🚫 #[\NoDiscard]

				
					#[\NoDiscard]
function calculate(): int { return 42; }

calculate(); // ⚠ Warning: Return value discarded
$x = calculate(); // ✅ OK
				
			

→ Работает на уровне opcache (если включён opcache.enable_cli).
→ Полезно для validate(), lock(), transaction().

Замыкания в константах и атрибутах

				
					#[Cache(ttl: fn() => 60 * 5)]
class Service { ... }

const HANDLER = fn(string $s) => strtoupper($s);
// позже: HANDLER('test') → 'TEST'
				
			

→ Замыкания не захватывают окружение — только параметры.
→ Не работают в const класса (только глобальные const).

Новые функции массивов array_first(), array_last()

📌 array_first(), array_last()

				
					array_first([1, 2, 3]);   // 1  
array_last([1, 2, 3]);    // 3  
array_first([]);          // null  
array_first([], 'def');   // 'def'
				
			

→ Безопаснее reset()/end() — не сбрасывает internal pointer.
→ Аналог array_key_first()/array_key_last(), но для значений.

Фича Пример Зачем
URI класс new Uri('https://...') Стандартный парсинг URL (WHATWG), без parse_url()
Pipe |> $str |> trim(...) |> strtolower(...) Цепочка вызовов без вложений
clone($obj, [...]) clone($color, ['alpha' => 128]) Клон + изменение свойств для readonly
#[\NoDiscard] #[\NoDiscard] function f() { ... } Предупреждение при игнорировании возврата
array_first(), array_last() array_last([1,2,3]) // 3 Безопасное получение элементов (null для пустого массива)