- Писать класс со свойствами и методами и создавать объекты через
new - Применять продвижение свойств в конструкторе,
readonlyи уровни видимости - Использовать статические члены и наследование через
extends
У банковского счёта есть владелец и баланс; на счёт можно положить деньги и проверить баланс. Чтобы хранить данные и функции для работы с ними в одном месте, используют объектно-ориентированное программирование (ООП). Современные PHP-фреймворки, такие как Laravel и Symfony, целиком построены на классах, поэтому эта тема — основа профессиональной работы с PHP.
Класс и объект
Класс — это чертёж объектов: он описывает, какие у них будут свойства (данные) и методы (действия). Объект — конкретный экземпляр класса, созданный через new. Внутри метода $this указывает на текущий объект, а к свойствам и методам обращаются через оператор ->. Метод __construct вызывается автоматически в момент создания объекта.
<?php
class Account
{
public string $owner;
private float $balance = 0.0;
public function __construct(string $owner)
{
$this->owner = $owner;
}
public function deposit(float $amount): void
{
$this->balance += $amount;
}
public function getBalance(): float
{
return $this->balance;
}
}
$acc = new Account("Aysel");
$acc->deposit(50);
$acc->deposit(25.5);
echo $acc->owner, ": ", $acc->getBalance(), " AZN\n";Aysel: 75.5 AZN
| Видимость | Откуда доступно |
|---|---|
public | отовсюду |
protected | из самого класса и его классов-наследников |
private | только из самого класса |
$acc->balance, получишь ошибку Cannot access private property — баланс меняется только через методы.Продвижение свойств и readonly
В классе выше $owner написан трижды: как свойство, как параметр и в присваивании. С продвижением свойств в конструкторе (constructor promotion) из PHP 8 ты пишешь модификатор видимости прямо у параметра конструктора — PHP сам объявит свойство и присвоит значение.
class Product
{
private string $name;
private float $price;
public function __construct(string $name, float $price)
{
$this->name = $name;
$this->price = $price;
}
}class Product
{
public function __construct(
private string $name,
private float $price,
) {}
}Начиная с PHP 8.1 свойство можно объявить **readonly**: значение ему присваивается только один раз, внутри класса. Если потом попытаться его изменить, получишь ошибку Cannot modify readonly property Money::$amount. Такие неизменяемые объекты идеально подходят для денег, дат и координат. Ниже мы храним деньги в гяпиках как целое число (1 манат = 100 гяпиков).
<?php
final class Money
{
public function __construct(
public readonly int $amount,
public readonly string $currency = "AZN",
) {}
public function add(Money $other): Money
{
return new Money($this->amount + $other->amount, $this->currency);
}
public function __toString(): string
{
return number_format($this->amount / 100, 2) . " " . $this->currency;
}
}
$price = new Money(1250);
$total = $price->add(new Money(799));
echo $total, "\n";
echo $total->amount, "\n";20.49 AZN 2049
addне меняет старый объект, а возвращает новый объектMoney— так работают неизменяемые объекты.- Специальный метод
__toStringпревращает объект в строку, поэтому работаетecho $total. finalзапрещает создавать классы-наследники от этого класса.
Статические члены
Статические свойства и методы принадлежат не отдельному объекту, а всему классу. К ним обращаются через ИмяКласса::член, а изнутри класса — через self::. Константы класса (const) читаются так же. Ниже класс считает, сколько объектов-учеников было создано.
<?php
class Student
{
public const MAX_IN_CLASS = 30;
private static int $count = 0;
public function __construct(public string $name)
{
self::$count++;
}
public static function count(): int
{
return self::$count;
}
}
new Student("Leyla");
new Student("Murad");
$s = new Student("Nigar");
echo Student::count(), " of ", Student::MAX_IN_CLASS, "\n";
echo $s->name, "\n";3 of 30 Nigar
Наследование
С помощью ключевого слова extends класс наследует все public- и protected-члены другого класса и может переопределить (override) любые его методы. К методу родителя обращаются через parent::. В PHP у класса может быть только один родитель. Когда один и тот же метод по-разному работает в разных классах, это называют полиморфизмом.
<?php
class Animal
{
public function __construct(protected string $name) {}
public function speak(): string
{
return "{$this->name} makes a sound";
}
}
class Cat extends Animal
{
public function speak(): string
{
return "{$this->name} says Meow";
}
}
class Dog extends Animal
{
public function speak(): string
{
return parent::speak() . ": Woof!";
}
}
$pets = [new Animal("Fish"), new Cat("Mestan"), new Dog("Bobik")];
foreach ($pets as $pet) {
echo $pet->speak(), "\n";
}Fish makes a sound Mestan says Meow Bobik makes a sound: Woof!
Главное
- Класс — чертёж, объект — его экземпляр, созданный через
new;$thisозначает текущий объект, а->— обращение к члену. public,protectedиprivateопределяют, откуда видны члены; храни данныеprivateи изменяй их через методы.- Продвижение свойств (PHP 8) объявляет свойства прямо в параметрах конструктора;
readonly(PHP 8.1) делает свойство неизменяемым. - Статические члены принадлежат классу и читаются через
self::илиИмяКласса::. extendsсоздаёт наследование,parent::вызывает метод родителя, аfinalзапрещает наследование.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.
$this внутри метода?