Урок по треку PHP 8 мин

ООП, трейты и интерфейсы в PHP

Классы, абстракции, трейты, позднее статическое связывание, магические методы, clone.

ООП в PHP похоже на Java и C#, но со своими особенностями: трейты, позднее статическое связывание, магические методы. На собесе любят self против static, трейты против интерфейсов и clone.

Классы

final class Order
{
    public function __construct(
        private readonly int $id,
        private OrderStatus $status = OrderStatus::New,
    ) {}

    public function pay(): void
    {
        if ($this->status !== OrderStatus::New) {
            throw new DomainException('Заказ уже оплачен или отменён');
        }
        $this->status = OrderStatus::Paid;
    }
}

Продвижение свойств в конструкторе (8.0), readonly (8.1), видимость public, protected, private. final запрещает наследование класса или переопределение метода (и константы с 8.1).

Абстрактный класс и интерфейс

  • Интерфейс: только сигнатуры публичных методов и константы, класс реализует сколько угодно интерфейсов, интерфейс является типом.
  • Абстрактный класс: состояние, конструктор, реализованные и абстрактные методы, наследуется один.

Трейты

trait HasSlug
{
    abstract protected function title(): string;
    public function slug(): string { return strtolower(str_replace(' ', '-', $this->title())); }
}

class Post { use HasSlug; protected function title(): string { return $this->title; } }

Трейт копирует код в класс. Он не тип (instanceof не работает). Конфликты имён решают insteadof и as. Приоритет: метод класса > метод трейта > унаследованный метод. Трейты хороши для мелкой сквозной функциональности (SoftDeletes), но прячут зависимости, поэтому бизнес-логику лучше выносить в сервисы и внедрять.

self, static, parent

class Model {
    public static function create(): static { return new static(); }
}
class User extends Model {}
User::create(); // объект User, а с new self() был бы Model

self это класс, где написан код, static это класс, через который вызвали (позднее статическое связывание), parent родитель.

Магические методы

__get, __set, __isset, __unset (недоступные свойства), __call, __callStatic (недоступные методы), __toString, __invoke, __clone, __serialize/__unserialize. На них построены модели Eloquent и фасады Laravel. Цена: анализатор и IDE хуже понимают код.

Сравнение и клонирование

  • == для объектов: тот же класс и равные свойства, ===: тот же экземпляр.
  • Присваивание и передача копируют дескриптор: $b = $a это тот же объект.
  • clone поверхностный: вложенные объекты общие. Глубокую копию делают в __clone().

SOLID в PHP

Тонкие контроллеры, логика в сервисах, зависимости через конструктор от интерфейсов, реализацию подставляет контейнер Laravel или Symfony. Интерфейс заводят там, где есть вариативность или граница с внешней системой, а не для каждого класса.

Частые ошибки

  • new self() в базовом классе фабрики.
  • Ожидание глубокой копии от clone.
  • Логика в трейтах вместо композиции.
  • Публичные свойства без инвариантов вместо методов предметной области.

Что спросят на собесе

  • Чем трейт отличается от интерфейса и абстрактного класса?
  • self против static: что такое позднее статическое связывание?
  • Как работает clone и как сделать глубокую копию?
  • Какие магические методы вы знаете и где они используются?
  • Расскажите SOLID на примере PHP-кода.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.