Весь класс — только для чтения:
#[\AllowDynamicProperties] // без этого — ошибка при динамических свойствах
readonly class User {
public function __construct(
public int $id,
public string $name
) {}
}
→ Все свойства автоматически readonly,
→ Нельзя добавлять динамические свойства (если не разрешено явно через #[AllowDynamicProperties]),
→ Запрещено наследование (final неявно).
Комбинация union + intersection:
function process((HasId&HasName)|null $entity): void { ... }
// вместо: HasId&HasName|null — раньше не парсилось
→ Позволяет писать сложные типы без ошибок парсинга.
🔒 SensitiveParameter attribute
Скрывает значение в stack trace:
function login(
string $user,
#[\SensitiveParameter] string $password
) {
// При ошибке $password не попадёт в логи/отладку
}
Работает в debug_print_backtrace(), Throwable::getTrace(), var_dump().
🧪 true, false, null как standalone types
function isEnabled(): true { return true; }
function getFlag(): bool|true { ... } // избыточно, но валидно
→ В основном для генераторов кода и статического анализа.
Динамические свойства запрещены по умолчанию (требуется #[AllowDynamicProperties]),
${var} внутри строк — deprecated (используй {$var}),
utf8_encode()/utf8_decode() — deprecated (используй mb_convert_encoding()).