Об'єкти в PHP - це просто ще один тип даних. Об'єкт дає змогу зберігати у змінній набір із властивостей та їхніх значень, а також вбудовані функції. Це робить об'єкти схожими за своєю структурою на асоціативні масиви. Але відмінність від масивів все-таки є, і при цьому досить важлива - об'єкти можуть мати внутрішній стан.
Давайте розберемося, що таке PHP-об'єкт. Як сказано вище, об'єкти схожі на масиви, але зі своїми особливостями. Об'єкти можуть містити окремі значення, кожне під своїм ключем. Ці значення називаються властивостями об'єкта.
Також об'єкти можуть мати всередині себе функції - їх називають методами об'єкта. Методи можуть звертатися до будь-яких властивостей об'єкта, читати і записувати туди дані.
Значення властивості об'єкта може бути будь-якого типу: число, рядок, масив, інший об'єкт. Але, на відміну від масиву, об'єкти не дозволяють додавати в себе нові значення. Тобто об'єкт завжди має кінцеве число своїх властивостей і методів. Змінювати значення наявних властивостей можна, а видаляти і замінювати їх - не можна. Що докорінно відрізняється від поведінки масиву, адже там додавати і видаляти значення можна в будь-який час.
Але найбільша особливість об'єктів - це те, як вони створюються. Якщо масив створюється або порожнім, або відразу з набором значень, то об'єкти влаштовані інакше. Річ у тім, що об'єкти не існують самі по собі. Щоб створити новий об'єкт, вам доведеться спочатку створити його опис - клас. Він описує те, з чого складається об'єкт. Ми розберемося з класами трохи пізніше.
Як же влаштований об'єкт зсередини? Його вміст можна поділити на дві групи: властивості та методи. Властивості можуть бути двох видів: публічні та приховані. До публічних властивостей можна звертатися за межами об'єкта, так само, як ви звертаєтеся до елементів масиву за ключами. Приховані властивості не мають аналогів у масиві. Вони доступні для читання і зміни тільки всередині самого об'єкта - і це можуть робити його методи.
Друга група - це методи об'єкта.
Набір методів також називається поведінкою об'єкта. Як і властивості, методи бувають публічними і прихованими. Публічні методи об'єкта можна викликати із зовнішнього коду, а приховані тільки із самого об'єкта. Методи здатні звертатися до властивостей об'єкта так само просто, як якщо б це були їхні внутрішні змінні або аргументи.
Клас - це шаблон, за яким створюються об'єкти.
Неможливо створити об'єкт "на льоту", як це відбувається з масивами. Об'єкт створюється тільки на основі свого опису - класу. Цим реалізація об'єктів у PHP відрізняється від JavaScript. У JS об'єктам не потрібні класи, вони можуть бути створені та модифіковані коли і як завгодно.
Навіщо потрібні класи, і чому об'єкти не можуть існувати без них?
Аналогія дуже проста: клас - це креслення, максимально докладний опис виробу. Сам по собі клас не є чимось фізичним і відчутним, його не використовують безпосередньо в коді. Клас є схемою, структурою, на основі якої створюють об'єкт.
Будь-яка робота з об'єктами в PHP складається з таких етапів.
Починаємо зі створення класу. У ньому фіксуємо, з яких властивостей і методів складатиметься кожен його екземпляр, задаємо початкові значення для кожної властивості. Маючи клас, можливо створити його екземпляр - об'єкт.
Класи в PHP заведено зберігати в окремих файлах, тому спочатку підключаємо цей сценарій там, де він необхідний. Потім викликаємо процедуру створення нового об'єкта на основі цього класу.
Щоб використовувати об'єкт надалі, його слід призначити змінною. Далі будемо працювати з об'єктом через змінну: викликати методи і звертатися до властивостей.
Опис класу:
class WeatherEntry
{
private $date;
private $comment = "";
private $temperature = 0;
private $isRainy = false;
public function __construct($date, string $comment, int $temperature)
{
$this->date = $date;
$this->comment = $comment;
$this->temperature = $temperature;
}
public function isCold()
{
return $this->temperature < 0;
}
public function setRainStatus($rain_status)
{
$this->isRainy = $rain_status;
}
public function getDayDescription()
{
$dt = strtotime($this->date);
$delta = time() - $dt;
$days = ceil($delta / 86400);
$res = "Це було $days тому. Того дня було";
if ($this->isCold()) {
$res .= "холодно. ";
}
else {
$res .= "досить тепло.";
}
if ($this->isRainy) {
$res .= "Шумів дощ.";
}
else {
$res .= "На небі не було ані хмаринки.";
}
return $res;
}
}
Створення об'єкта на основі класу:
$firstSeptember = new WeatherEntry("2018-09-01", "День знаний", 14);
$firstSeptember->setRainStatus(false);
print($firstSeptember->getDayDescription());
Розбір прикладу
Почнемо з цілей створення цього класу. Його завдання - зберігати в об'єкті дані про погоду за конкретний день, а також надавати зведення за цей день у текстовому вигляді.
У класі визначено чотири приховані властивості. Це означає, що до них не буде доступу за межами об'єкта. Читати і записувати ці властивості можуть тільки внутрішні методи об'єкта. Самі властивості зберігають температурні параметри (температуру, опади), дату і додатковий коментар до запису. Деяким властивостям задано значення за замовчуванням.
Далі йде перерахування методів. І починається все з методу, у якого особливе ім'я і значення - __construct.
Що таке конструктор об'єкта
Методи об'єкта викликаються із зовнішнього коду, при явному зверненні до них із зазначенням імені. Але якщо назвати один метод __construct, то він буде викликатися автоматично в момент створення об'єкта на основі класу.
Конструктори об'єктів використовуються для ініціалізації будь-яких значень і у виконанні інших підготовчих операцій. У нашому прикладі конструктор встановлює вміст прихованих властивостей.
Звернення до властивостей і методів об'єкта
Подивимося, як усередині методу відбувається звернення до властивостей.
По-перше, для цього використовується спеціальна змінна this, яка завжди присутня всередині об'єкта і посилається на нього самого.
По-друге, для звернення до методів і властивостей об'єкта потрібен спеціальний синтаксис: "стрілочка". Така стрілочка відокремлює ім'я властивості або методу від імені об'єкта. Це аналог квадратних дужок при роботі з масивами.
Метод з ім'ям isCold() потрібен, щоб дізнатися, чи було холодно того дня, ґрунтуючись на показаннях температури в градусах.
Метод setRainStatus() встановлює логічне значення, яке показує статус опадів у день спостереження.
Метод getDayDescription() формує текстовий опис погоди на задану дату.
Створення об'єкта на основі класу
Написавши клас, ми виконали більшу частину роботи. Тепер створимо новий об'єкт на основі класу і подивимося, як із ним працювати.
Новий об'єкт створюється за допомогою ключового слова new, після якого йде ім'я його класу. У круглих дужках передаємо всі аргументи в метод __construct, якщо він був написаний. Клас не зобов'язаний містити цей метод, і якщо його немає, то круглі дужки необов'язкові.
У коді передаємо в конструктор майже всі параметри погодних спостережень. Потім для створеного об'єкта викликаються його методи: перший встановлює значення опадів, а другий повертає текстовий опис погоди.