Menu

Классы и объекты PHP: свойства, методы и $this

Класс PHP это шаблон, объявленный через class Name { }, а new Name() создаёт по нему объект. Свойства, методы, $this, public/private/protected, типизированные и readonly-свойства, __toString и почему присваивание объекта его не копирует.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Класс PHP объявляется через class Name { ... } и содержит свойства (переменные) и методы (функции). new Name() создаёт по нему объект, а -> читает свойство или вызывает метод: $user->name, $user->greet().

Класс это чертёж, объект это одна вещь, собранная по нему. Из одного класса можно создать сколько угодно объектов, и у каждого свои значения свойств.

Свойства и методы

Свойство объявляется с ключевым словом видимости, необязательным типом и необязательным значением по умолчанию. Метод это функция внутри класса. Внутри метода $this это объект, для которого вызван метод, поэтому $this->balance читает баланс этого объекта.

Каждый объект хранит свой $balance: пополнение $a не трогает $b. Задавать свойства по одному после new утомительно; конструктор принимает начальные значения аргументами.

public, private и protected

Видимость определяет, кто может обращаться к свойству или вызывать метод:

Ключевое словоДоступно из
publicоткуда угодно
protectedсамого класса и классов, которые его наследуют
privateтолько класса, который его объявил

Сделать свойство private и открыть методы это способ, которым класс защищает собственные правила. Здесь баланс меняется только через deposit() и withdraw(), которые отклоняют неверные суммы:

Чтение закрытого свойства снаружи класса это не предупреждение, а Error:

Типизированные свойства и неинициализированные значения

Типизированное свойство без значения по умолчанию начинается как неинициализированное, а это не то же самое, что null. Чтение до первого присваивания выбрасывает Error. Либо задайте значение по умолчанию, либо присвойте его в конструкторе, либо сделайте свойство nullable через ?Type и = null.

Типы проверяются при присваивании. В режиме по умолчанию (нестрогом) $p->stock = '7' приводит числовую строку к 7, а $p->stock = 'many' выбрасывает TypeError.

readonly-свойства

Свойство readonly (PHP 8.1) можно записать один раз изнутри класса, и больше никогда. Это обычный способ строить объекты-значения, например денежные суммы или ID. В PHP 8.2 появился readonly class, который делает readonly все свойства.

У readonly-свойства должен быть тип, и значения по умолчанию у него быть не может. Если нужна изменённая копия, создайте новый объект (new Order('B-2002')), а не редактируйте старый.

Вывод объекта через __toString

echo $object работает, только если класс определяет __toString(). Метод возвращает строку, которую PHP использует всякий раз, когда объект трактуется как текст: в echo, при конкатенации строк, в "{$object}".

Без __toString echo $object выбрасывает Error ("Object of class Money could not be converted to string"). Для отладки print_r() и var_dump() работают с любым объектом и показывают и закрытые свойства; смотрите var_dump и print_r.

Присваивание объекта его не копирует

На этой ошибке спотыкается большинство тех, кто привык к массивам. Присваивание массива копирует его. Присваивание объекта копирует только дескриптор: обе переменные после этого указывают на один и тот же объект.

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

Часто задаваемые вопросы

Как создать объект класса в PHP?

Используйте new с именем класса: $user = new User();. Если у класса есть конструктор, передайте его аргументы в скобках, как в new User('Ada'). Затем вызывайте методы и читайте свойства через стрелку: $user->name, $user->greet().

Что означает $this в PHP?

$this это объект, для которого вызван текущий метод. Внутри $ada->greet() $this это $ada, поэтому $this->name читает имя Ada. $this существует только внутри нестатических методов.

Чем отличаются public, private и protected в PHP?

public члены доступны отовсюду, private только внутри класса, который их объявил, а protected в этом классе и его дочерних классах. Чтение закрытого свойства снаружи выбрасывает Error: Cannot access private property.

Передаются ли объекты в PHP по ссылке?

Переменная хранит дескриптор объекта, а не сам объект. $b = $a; копирует дескриптор, поэтому обе переменные указывают на один объект, и изменение через $b видно в $a. Используйте $b = clone $a;, чтобы получить независимую копию.

Что такое readonly-свойство в PHP?

Свойство, объявленное как public readonly string $id; (PHP 8.1+), можно задать один раз изнутри класса, и потом оно никогда не меняется. Повторная запись выбрасывает Error: Cannot modify readonly property.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ