Ассоциативный массив хранит данные книги, но не гарантирует, что у каждой записи есть нужные ключи. Класс позволяет описать форму записи и действия, которые с ней связаны. В результате объект нельзя создать без обязательных данных, если конструктор этого не допускает.

Класс — описание, объект — конкретная книга

Класс Book задаёт общую модель, а объект $book — одну книгу с её значениями. Создайте файл src/Book.php в пространстве имён App:

<?php
declare(strict_types=1);

namespace App;

final class Book
{
    public function __construct(
        private string $title,
        private string $author,
        private int $year,
    ) {
        if (trim($title) === '') {
            throw new \InvalidArgumentException('У книги должно быть название.');
        }
    }

    public function title(): string
    {
        return $this->title;
    }

    public function label(): string
    {
        return $this->title . ' — ' . $this->author . ' (' . $this->year . ')';
    }
}

Промоутинг свойств в конструкторе (синтаксис PHP 8) создаёт свойства из параметров. private не позволяет внешнему коду менять поля напрямую. Публичные методы дают понятный интерфейс: спросить заголовок или получить готовую подпись.

Не прячьте поведение без причины

Инкапсуляция означает, что объект сам отвечает за свои правила. В нашем примере объект не разрешает пустое название. Если позже нужно добавить проверку года, разместите её в конструкторе или отдельном именованном методе создания.

Создайте экземпляр в другом файле:

use App\Book;

$book = new Book(
    title: 'Дюна',
    author: 'Фрэнк Герберт',
    year: 1965,
);

echo $book->label();

Именованные аргументы (PHP 8+) упрощают чтение вызова и помогают избежать путаницы между несколькими строками. Метод label() собирает подпись по одному правилу, а другие части программы не обязаны знать, как именно она устроена.

Когда массив всё ещё лучше

Не каждую временную структуру нужно превращать в класс. Для пары значений, которые используются один раз внутри небольшого алгоритма, массив проще. Класс становится полезным, когда есть правила допустимых значений, несколько операций или объект передаётся между разными слоями приложения.

Наследование не обязательно

Ключевое слово final запрещает наследоваться от класса. В нашем мини-проекте это помогает оставить модель простой: книга — не «базовый класс для всех вещей», а конкретная сущность с заданными данными. Когда появится дополнительная логика, сначала попробуйте отдельный объект или функцию, а не сложную цепочку наследования.

Следующий шаг — сделать статус книги ограниченным набором вариантов и объявить неизменяемые объекты. Для этого в современном PHP есть перечисления и readonly-классы.

Часть 7 из 16.

← Часть 6: Composer и пространства имён PHP: подключаем классы · Часть 8: Enum и readonly в PHP: надёжный статус книги →

Документация