Skip to main content
NewWebmaster.RU

PHP современные возможности языка

info - статья обновляется по мере выхода новых версий

PHP за последние годы изрядно "прокачался", синтаксис и конструкции языка стали более удобными и приятными.

Этот материал служит "шпаргалкой" по PHP для разработчиков и меня лично

PHP 7.1

Деструктуризация массивов

PHP 7.1 / Дока

Массивы в PHP могут деструктурироваться достаточно удобно, не так идеально как например в JS, но не стоит забывать что и в PHP есть возможности для такого синтаксиса:

// массивы в массиве
$posts = [[1, 2, 3, 4], [5, 6, 7]];
[$publishedPosts, $draftPosts] = $posts;
// или пропускаем первый
[, $draftPosts] = $posts;

// ассоциативные массивы
$post = [
  'title' => 'Современный PHP',
  'description' => 'описание возможностей',
  'status' => 'Опубликовано'
];

['title' => $title, 'description' => $description] = $post;

Пример смены значений с помощью деструктуризации:

<?php

$a = 1;
$b = 2;
[$b, $a] = [$a, $b];
echo $a;    // выведет 2
echo $b;    // выведет 1

PHP 7.4

Разделитель для числовых значений

PHP 7.4

Для написания длинных числовых значений есть возможность использовать подчеркивание _ для разделения

Пример:

$num = 1_000_000;

Поддерживаемые форматы:

1_000_000 // Десятичные

6.62_607_004e-34 // Экспоненциальная запись числа

0.300_000_000_000_000_04 // Значения с плавающей запятой

0b1111_0000_1001_1111_1001_0010_1010_1001 // Двоичные

0123_7264 // Восьмиричные

0xBEEF_BABE // Шестнадцатеричные

Распаковка массива оператором ... (Spread operator)

PHP 7.4

Удобная конструкция для работы с массивами

$a = [1, 2];
$b = [...$a, 3, 4]; // [1, 2, 3, 4]

Стрелочные функции

PHP 7.4

удобный синтаксис для написания анонимных функций(они же замыкания, они же Closure), как в JavaScript =)

$add = fn (int $a, int $b) => $a + $b;

$add(1,2); // 3

PHP 8.0

Именованные аргументы(параметры)

PHP 8.0

До их появления мы писали так:

function calculatePrice(
    $net = 0,
    $raw = 0,
    $taxes = 0
) {}

// а чтобы передать в функцию например только третий аргумент приходилось делать так
calculationPrice(
    null,
    null,
    200
)

С приходом PHP8 передать значение можно по имени аргумента

calculationPrice(taxes: 200);

Объединение типов (Union types)

PHP 8.0

В версии 7.4 мы получили возможность типизации в PHP. С версии PHP 8.0, мы можем объявлять более одного типа для аргументов, возвращаемых типов и свойств класса:

class Example {
    private int|float $foo;
    public function sum(float|int $bar): int|float {
        return $this->foo + $bar;
    }
}

PHP 8.1

Перечисления (Enums)

PHP 8.1

PHP 8.1 вводит поддержку перечислений (enums), что позволяет создавать типы с фиксированным набором допустимых значений. Это особенно полезно для представления состояний, типов и других ограниченных наборов значений.

enum Status
{
    case Draft;
    case Published;
    case Archived;
}

function setStatus(Status $status) {
    // ...
}

setStatus(Status::Published);

Перечисления могут быть скалярными (с backed значениями):

enum Status: string
{
    case Draft = 'draft';
    case Published = 'published';
    case Archived = 'archived';
}

Свойства только для чтения (Readonly Properties)

PHP 8.1

Свойства, помеченные как readonly, могут быть установлены только один раз и не могут быть изменены после этого:

class User
{
    public readonly string $name;
    
    public function __construct(string $name) {
        $this->name = $name; // Это допустимо
    }
}

$user = new User("Иван");
echo $user->name; // "Иван"
// $user->name = "Петр"; // Ошибка!

Синтаксис вызываемых функций первого класса (First-class Callable Syntax)

PHP 8.1

PHP 8.1 упрощает создание замыканий из вызываемых элементов:

// Ранее:
$callable = Closure::fromCallable('strlen');

// Теперь:
$callable = strlen(...);

Это также работает с методами:

$callable = $object->method(...);

Файберы (Fibers)

PHP 8.1

Файберы - это примитивы для реализации легковесной неблокирующей конкурентности. Они позволяют приостанавливать выполнение кода и передавать управление другому коду:

$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('fiber');
    echo $value;
});

$value = $fiber->start();
echo $value; // "fiber"

$fiber->resume('test');
// Выводит "test"

Пересечение типов (Intersection Types)

PHP 8.1

Теперь можно указывать, что параметр или возвращаемое значение должно соответствовать нескольким типам одновременно:

function example(Iterator&Countable $value): Traversable&Stringable {
    // ...
}

PHP 8.2

Классы только для чтения (Readonly Classes)

PHP 8.2

PHP 8.2 позволяет сделать все свойства класса readonly одновременно:

readonly class User
{
    public string $name;
    public string $email;
    
    public function __construct(string $name, string $email) {
        $this->name = $name;
        $this->email = $email;
    }
}

Null, True и False как автономные типы

PHP 8.2

Эти значения теперь могут использоваться как отдельные типы:

function alwaysNull(): null {
    return null;
}

function alwaysTrue(): true {
    return true;
}

function alwaysFalse(): false {
    return false;
}

Новый тип Disjunctive Normal Form (DNF)

PHP 8.2

Позволяет комбинировать пересечения и объединения типов:

function example((A&B)|C $value): void {
    // $value может быть либо C, либо одновременно A и B
}

Удаление динамических свойств

PHP 8.2

Создание динамических свойств в объектах теперь устарело:

class User
{
    public string $name;
}

$user = new User();
// $user->email = "test@example.com"; // Устарело в PHP 8.2

PHP 8.3

Типизированные константы классов (Typed Class Constants)

PHP 8.3

Теперь можно указывать типы для констант классов:

class Config
{
    public const string DB_HOST = 'localhost';
    public const int DB_PORT = 3306;
}

Атрибуты #[Override] и #[SensitiveParameter]

PHP 8.3

Атрибут #[Override] используется для явного указания переопределения методов:

class ParentClass
{
    public function method(): void {}
}

class ChildClass extends ParentClass
{
    #[Override]
    public function method(): void {}
}

Атрибут #[SensitiveParameter] используется для пометки параметров с чувствительными данными:

function login(#[SensitiveParameter] string $password): void {
    // ...
}

Функция json_validate()

PHP 8.3

Позволяет проверить, является ли строка корректным JSON без необходимости парсинга:

if (json_validate($jsonString)) {
    echo "Строка является корректным JSON";
}

Изменения в Random Extension

PHP 8.3

Добавлены новые классы и интерфейсы для генерации случайных чисел:

$randomInt = random_int(1, 100);
$randomBytes = random_bytes(16);

PHP 8.4

Хуки свойств (Property Hooks)

PHP 8.4

Хуки свойств позволяют определять логику, которая выполняется при доступе к свойству или его изменении:

class User
{
    public string $name {
        set(string $value) {
            if (strlen($value) < 2) {
                throw new InvalidArgumentException("Имя должно содержать минимум 2 символа");
            }
            $this->name = $value;
        }
        
        get => ucfirst($this->name);
    }
}

Атрибут #[Lazy]

PHP 8.4

Используется для отложенной инициализации свойств:

class Service
{
    #[Lazy]
    public function getData(): array {
        // Дорогостоящая операция
        return $this->expensiveOperation();
    }
}

PHP 8.5