Объекты и классы в PHP
Объекты в 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 , если он был написан. Класс не обязан содержать этот метод, и если его нет, то круглые скобки необязательны.
В коде передаём в конструктор почти все параметры погодных наблюдений. Затем для созданного объекта вызываются его методы: первый устанавливает значения осадков, а второй возвращает текстовое описание погоды.
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Объекты
Для создания нового объекта, используйте выражение new, создающее в переменной экземпляр класса:
$bar = new foo ;
$bar -> do_foo ();
?>
Полное рассмотрение производится в разделе Классы и Объекты.
Преобразование в объект
Если object преобразуется в object , он не изменяется. Если значение другого типа преобразуется в object , создается новый экземпляр встроенного класса stdClass. Если значение было NULL , новый экземпляр будет пустым. Массивы преобразуются в object с именами полей, названными согласно ключам массива и соответствующими им значениям, за исключением числовых ключей, которые не будут доступны пока не проитерировать объект.
$obj = (object) array( ‘1’ => ‘foo’ );
var_dump (isset( $obj ->< '1' >)); // outputs ‘bool(false)’
var_dump ( key ( $obj )); // outputs ‘int(1)’
?>?php
При преобразовании любого другого значения, оно будет помещено в поле с именем соответствующему типу scalar.
Создание объектов PHP в стиле JS литеральной нотации
Объекты в PHP появились сравнительно поздно и, поэтому для их создания всегда необходим класс. Поддержка анонимных классов была добавлена в PHP 7.
В версиях ниже PHP 7 используеются другой механизм
От ассоциативных массивов к объектам PHP
Создаем ассоциативный массив
"Тяпк", 'power' => 50 );
С помощью привидения типов создаем объект из массива. Массивы преобразуются в object с именами полей, названными согласно ключам массива и соответствующими им значениям, за исключением числовых ключей, которые не будут доступны пока не проитерировать объект.
Если необходимо начать с пустого объекта, то это делается следующими способами:
А затем к пустому объекту добавляются свойства
power = 50;
Методы
В JavaScript можно делать так:
; TyapkObject.say(); // "Привет!"
Начиная с PHP 5.3 в языке появлись замыкания.
А начиная с PHP 7.0 можно делать почти как в JavaScript.
Выражение $tyapk->say() не работает. Всё потому, что методы и свойства класса PHP находятся в разных неймспейсах (можно иметь метод и свойство с одним именем, например say() и say), и когда вы пытаетесь достучать до say(), интерпретатор ничего подходящего среди методов не находит.
Одноко, начиная с PHP 5.4.0, say можно присвоить новой переменной $callSay, которую затем вызвать.
say; echo $callSay();
В отдельных случаях (когда функция обратного вызова не является массивом или строкой) можно воспользоваться магическим методом invoke:
Еще можно так:
Альтернативой являлась реализация шаблона с магическим методом __call. Покажу на примере анонимного класса, но через обычные классы будет работать и в старых версиях PHP. Напрямую присвоить свойству $say callback нельзя, т.к. в PHP 7 это не поддерживатся, поэтому через конструктор.
say = function() < return "Привет из свойства!"; >; > public function __call($name, $args) < return call_user_func_array($this->$name, $args); > >; $tyapk->say(); // "Привет из свойства!";
Статья написана по мотивам JavaScript-style object literals in PHP Здесь же можно прочитать про шаблон с __call и еще несколько хаков.
Отличное актуальное объяснение на счет вызовов замыканий есть на stackoverflow
Классы и объекты в PHP
Класс — это шаблон для объектов, а объект — это экземпляр класса.
Представьте, что у нас есть класс Car . Car может иметь такие свойства, как название, цвет, диски и т.д. Мы можем определить переменные класса например, $name , $color и $disk для хранения значений этих свойств.
Если мы создадим отдельные объекты (BMW, Mercedes Benz и т.д.), то они будут наследовать все свойства и поведение класса Car , но каждый объект будет иметь разные значения свойств.
Что такое класс PHP?
Класс определяется с помощью ключевого слова class , за которым следует имя класса и пара фигурных скобок (<>). Все его свойства и методы заключены в фигурные скобки:
Синтаксис
Ключевое слово class используется для определения класса в PHP. Ниже приведены правила создания класса в PHP:
- Пишем название класса с большой буквы.
- Если имя класса содержит более одного слова, мы пишем каждое слово с большой буквы. Это известный стиль верблюда. Например, JapaneseCars, AmericanIdol, EuropeTour и др.
- Имя класса не может быть зарезервированным словом PHP.
- Имя класса не может содержать пробелов.
Как добавить свойства к классу?
Мы вызываем свойства внутри класса. Свойства могут принимать такие значения, как строки, целые числа и логические значения (true/false), как и любые другие переменные. Добавим несколько свойств в класс Car:
class Car < public $name; public $color = 'green'; public $hasSunRoof = true; >
Приведем правила создания свойств к классу:
- Мы используем ключевое слово public перед свойством класса.
- Согласно соглашению об именах, имя свойства начинается со строчной буквы.
- Если имя содержит более одного слова, все слова, кроме первого слова, начинаются с заглавной буквы. Например, $color или $hasSunRoof (Верблюжий регистр camelCase).
- Свойство может иметь значение по умолчанию. Например, $color = ‘green’.
- Мы также можем создать свойство без значения по умолчанию. Например, $name.
Объявим класс с именем Car , который будет состоять из двух свойств ( $name и $color ) и двух методов set_name() и get_name() для установки и получения свойства $name :
Пример
name = $name; > function get_name() < return $this->name; > > ?>
Данный код ничего не выведет, поскольку мы создали класс, но не создали пока ни одного объекта.
Примечание: В классе переменные называются свойствами, а функции — методами!
Что такое объект PHP?
Объект — это экземпляр класса. Из класса мы можем создать столько объектов, сколько может понадобиться для проекта. Каждый объект имеет все свойства и методы, определенные в классе, но у них будут разные значения свойств.
Для объявления объекта необходимо использовать ключевое слово new .
Далее создадим из класса Car два объекта — $bmw и $mercedes .
$bmw = new Car(); $mercedes = new Car();
Процесс создания объекта также известен как создание экземпляра.
Объекты, для чего они нужны?
В то время как в процедурном стиле программирования все функции и переменные находятся вместе в глобальной области видимости таким образом, чтобы их можно было использовать, просто вызывая их имя, использование классов делает манипуляции с кодом внутри классов скрытыми от глобальной области. Это происходит потому, что код внутри классов инкапсулируется в пределах класса, вне досягаемости глобальной области. Итак, нам нужен способ, позволяющий коду из глобальной области видимости использовать код внутри класса, и этот способ базируется на создании объектов из класса.
Мы можем создать столько объектов, сколько захотим, из одного и того же класса, и все они будут совместно использовать методы и свойства класса. См. изображение ниже:
Из одного и того же класса Car мы создали три отдельных объекта с названиями: Mercedes , Bmw и Audi .
Хотя все объекты были созданы из одного и того же класса и, следовательно, имеют методы и свойства класса, они все же разные. Это не только потому, что они имеют разные названия, но и потому, что их свойствам могут быть присвоены разные значения. Например, на изображении выше они различаются свойством цвета: Mercedes зеленый, Bmw синий, а Audi оранжевый.
Примечание: Класс содержит методы и свойства, общие для всех созданных из него объектов.
Хотя объекты используют один и тот же код, они могут вести себя по-разному, поскольку им могут быть присвоены разные значения.
Как получить свойства объекта?
Создав объект, мы можем получить его свойства. Например:
echo $bmw -> color; echo $mercedes -> color;
Когда объект создан, мы можем получить доступ к свойствам класса с помощью оператора (->) .
Обратите внимание, что имя свойства не начинается со знака $ ; только имя объекта начинается с символа $ .
Пример
// создадим из класса Car два объекта $bmw = new Car(); $mercedes = new Car(); echo $bmw -> color; echo "
"; echo $mercedes -> color; ?>
Результат выполнения кода:
green
green
Свойство color было установлено в классе по умолчанию (green), поэтому все объекты его унаследовали.
Как установить свойства объекту?
Чтобы установить свойство объектe, мы используем аналогичный подход.
Например, установим синий цвет объекту bmw :
$bmw -> color = 'blue';
Таким же способом установим значение свойства $name для обоих объектов:
$bmw ->name = "BMW"; $mercedes ->name = "Mercedes Benz";
Установив значение свойства, мы можем получить его значение. Чтобы получить цвет объекта $bmw , мы используем следующую строку кода:
echo $bmw -> color;
Пример
$bmw = new Car(); $bmw ->name = "BMW"; $bmw -> color = 'blue'; $mercedes = new Car(); $mercedes ->name = "Mercedes Benz"; echo $bmw -> name . ": "; echo $bmw -> color; echo "
"; echo $mercedes -> name . ": "; echo $mercedes -> color; ?>
Результат выполнения кода:
BMW: blue
Mercedes Benz: green
Как добавить методы в класс?
Классы могут содержать различные функции. Функция внутри класса называется методом. Здесь мы добавляем в класс метод hello() с префиксом public :
class Car < public $comp; public $color = 'green'; public $hasSunRoof = true; public function hello() return "beep"; > >
Правила создания методов:
- Прописываем ключевое слово public перед методом.
- Согласно соглашению об именах, имя метода начинается со строчной буквы.
- Если имя содержит более одного слова, то все слова, кроме первого слова, начинаются с заглавной буквы. Например, helloUser() или flyPanAm().
Мы можем подходить к методам так же, как и к свойствам:
Пример
> // Создать экземпляр $bmw = new Car (); $mercedes = new Car (); // Получить значения echo $bmw -> color; // green echo "
"; echo $mercedes -> color; // green echo "
"; // Установите значения $bmw -> color = 'blue'; $bmw -> name = "BMW"; $mercedes -> name = "Mercedes Benz"; // Получить значения echo $bmw -> color; // blue echo "
"; echo $mercedes -> color; // green echo "
"; echo $bmw -> name; // BMW echo "
"; echo $mercedes -> name; // Mercedes Benz echo "
"; // Используем метод, чтобы получить звуковой сигнал echo $bmw -> hello(); // beep echo "
"; echo $mercedes -> hello(); // beep ?>
В приведенном ниже примере создадим два метода set_name() и get_name() для установки и получения свойства $name для объектов $bmw и $mercedes :
Пример
name = $name; > function get_name() < return $this->name; > > $bmw = new Car(); $mercedes = new Car(); $bmw->set_name("BMW"); $mercedes->set_name("Mercedes Benz"); echo $bmw->get_name(); echo "
"; echo $mercedes->get_name(); ?>
Результат выполнения кода:
BMW
Mercedes Benz
Для установки и получения свойства $color , созданных объектов, добавляем в класс Car еще два метода:
Пример
name = $name; > function get_name() < return $this->name; > function set_color($color) < $this->color = $color; > function get_color() < return $this->color; > > $bmw = new Car(); $bmw->set_name("BMW"); $bmw->set_color('blue'); echo "Название: " . $bmw->get_name(); echo "
"; echo "Цвет: " . $bmw->get_color(); ?>
Результат выполнения кода:
Название: BMW
Цвет: blue
Ключевое слово $this в PHP
Ключевое слово $this указывает на то, что мы используем собственные методы и свойства класса, и позволяет нам получить доступ к ним в пределах области видимости класса.
Ключевое слово $this позволяет нам получить доступ к свойствам и методам класса внутри класса, используя следующий синтаксис:
$this -> propertyName; $this -> methodName();
Примечание: Только ключевое слово $this начинается со знака $ , а имена свойств и методов нет.
Ключевое слово $this относится к текущему объекту и доступно только внутри методов.
В следующем примере создан класс Car и объект $bmw.
Пример
$bmw = new Car(); ?>
Перед нами стоит задача изменить свойство $name объекта.
Сделать это можно двумя способами:
1. Изменение свойства внутри класса путём добавления метода set_name() и используя ключевое слово $this :
Пример
name = $name; > > $bmw = new Car(); $bmw->set_name("BMW"); echo $bmw -> name; // BMW ?>
Результат выполнения кода:
2-й способ — это изменение свойства вне класса путем прямого изменения значения $name:
Пример
$bmw = new Car(); $bmw->name = "BMW"; echo $bmw -> name; // BMW ?>
Результат выполнения кода:
Является ли объект экземпляром класса?
Оператор instanceof используется для определения того, является ли текущий объект экземпляром указанного класса:
Пример
Результат выполнения кода:
Оператор instanceof не генерирует никаких ошибок, если проверяемая переменная не является объектом. В этом случае он просто возвращает FALSE .
Итоги
В этом уроке вы сделали свои первые шаги в мир объектно-ориентированного программирования PHP, узнав о классах и об объектах, которые могут быть созданы из них. Кликните здесь, чтобы попрактиковаться в предмете. Сегодня вы также узнали, как использовать ключевое слово $this для получения собственных свойств и методов класса изнутри класса. Закрепите полученные знания о ключевике $this.
