PHP: Классы и объекты
Поскольку именно классы описывают объекты, мы начнем описание с определения классов.
Определение класса
Класс — это шаблон кода, который используется для создания объектов. Класс определяется с помощью ключевого слова class после которого указывается произвольное имя класса. В имени класса может использоваться любое сочетание букв и цифр, но они не должны начинаться с цифры. Код, связанный с классом должен быть заключен в фигурные скобки, которые указываются после имени. Определение класса описывает, какие элементы будут содержаться в каждом новом экземпляре этого класса. На основе полученных данных давайте посмотрим синтаксис определения класса на примере:
Класс first из приведенного примера — уже полноправный класс, хотя пока и не слишком полезный. Но тем не менее мы сделали нечто очень важное. Мы определили тип, т.е. создали категорию данных, которые мы можем использовать в своих сценариях. Важность этого станет для вас очевидной по мере дальнейшего чтения главы.
Создание объекта
Так как класс — это шаблон для создания объектов, следовательно, объект — это данные, которые создаются и структурируются в соответствии с шаблоном, определенным в классе. Объект также называют экземпляром класса, тип которого определяется классом. Для создания нового экземпляра класса нам понадобится оператор new . Он используется совместно с именем класса следующим образом:
После оператора new указывается имя класса на основе которого будет создан объект. Оператор new создает экземпляр класса и возвращает ссылку на вновь созданный объект. Эта ссылка сохраняется в переменной соответствующего типа. В результате выполнения этого кода будет создано два объект типа first . Хотя функционально они идентичны (т.е. пусты) $obj1 и $obj2 — это два разных объекта одного типа, созданных с помощью одного класса.
Если вам все еще не понятно, давайте приведем аналогию из реальной жизни. Представьте, что класс — это форма для отливки, с помощью которой изготавливаются пластмассовые машинки. Объекты — это и есть машинки. Тип создаваемых объектов определяется формой отливки. Машинки выглядят одинаковыми во всех отношениях, но все-таки это разные предметы. Другими словами, это разные экземпляры одного и того же типа.
Давайте сделаем эти объекты немного интереснее, изменив класс first , добавив в него специальные поля данных, называемые свойства.
Определение свойств
В классе можно определить переменные. Переменные, которые определены в классе называются свойствами (или полями данных). Они определяются с одним из ключевых слов protected, public или private , характеризующих управление доступом. Эти ключевые слова мы рассмотрим подробно в следующей главе. А сейчас давайте определим некоторые свойства с помощью ключевого слова public :
Как видите, мы определили два свойства, присвоив каждому из них значение. Теперь любые объекты, которые мы будем создавать с помощью класса first , будут иметь два свойства с указанными значениями.
Примечание: значения инициализирующие свойства должны быть литералами (константными значениями), инициализировать свойства в классе не обязательно (если значение не указано, по умолчанию это будет NULL ).
К свойствам объекта можно обращаться с помощь символов ‘ -> ‘, указав объект и имя свойства. Поскольку свойства объектов были определены как public , мы можем считывать их значения, а также присваивать им новые значения, заменяя тем самым начальные значения, определенные в классе:
На самом деле в PHP необязательно объявлять все свойства в классе. Свойства можно добавлять к объекту динамически:
Нужно отметить, что этот способ присваивания свойств объектам считается дурным тоном в объектно-ориентированном программировании и почти никогда не используется.
Работа с методами
Методы — это обычные функции, которые определяются внутри класса, они позволяют объектам выполнять различные задачи. Объявление метода напоминает определение обычной функции, за исключением предваряемого одного из ключевых слов protected, public или private . Если в определении метода вы опустите ключевое слово, определяющее видимость, то метод будет объявлен неявно как public . К методам объекта можно обращаться с помощь символов ‘ -> ‘, указав объект и имя метода. При вызове метода, так же как и при вызове функции нужно использовать круглые скобки.
Мы добавили метод getstr() к классу first . Обратите внимание на то, что при определении метода мы не использовали ключевое слово, определяющее область видимости. Это означает, что метод getstr() относится к типу public и его можно вызвать за пределами класса.
В определении метода мы воспользовались специальной псевдопеременной $this . Она используется для обращения к методам или свойствам внутри класса и имеет следующий синтаксис:
Значением переменной $this является ссылка на текущий объект. Чтобы стало понятнее посмотрите на следующий пример:
Примечание: переменной $this нельзя ничего присваивать. Помните, что переменная $this всегда ссылается на текущий объект.
Специальный метод — конструктор
У класса может быть определен специальный метод — конструктор , который вызывается каждый раз при создании нового экземпляра класса (объекта) с целью инициализировать его, например установить значения свойств. Конструктор, как и любой другой метод может иметь параметры. Чтобы определить метод в качестве конструктора его необходимо назвать __construct() . Обратите внимание на то, что имя метода должно начинаться с двух символов подчеркивания. Посмотрим, как это работает:
Метод __construct вызывается, когда создается объект с помощью оператора new . Указанные в скобках аргументы передаются конструктору. В методе конструктора используется псевдопеременная $this для присвоения значений соответствующим свойствам создаваемого объекта.
Указание типа аргумента в методах
По умолчанию метод может принимать аргументы любого типа, но бывают случаи, когда необходимо сделать так, чтобы метод мог принимать в качестве аргумента только экземпляры определенного класса. Для указания типа принимаемого аргумента, просто поместите в определении метода перед именем параметра название класса:
Теперь в качестве аргумента методу getobj() можно передавать только экземпляры типа cat . Поскольку метод getobj() содержит уточнение типа класса, передача ему объекта типа wrong приведет к ошибке.
Указание типа нельзя использовать для определения параметров элементарных типов, таких как строки, числа и т.д. Для этой цели в теле метода следует использовать функции проверки типов, например is_string() . Также есть возможность определить, что передаваемый аргумент является массивом:
И последнее о чем осталось сказать: если параметр метода определяется с указанием определенного класса, разрешается указать значение по умолчанию, на случай, если методу не было передано никакого объекта. В качестве значения по умолчанию может быть использовано только значение NULL :
Если вместо NULL указать какое-либо другое значение по умолчанию, будет выдана ошибка.
Свойства объекта
Свойство объекта — это переменная, описанная в классе .
В папке с уроком создадим папку classes c файлом Car.php:
Файл Car.php
<?php
class Car // создание класса Car
<
>
?>
В классе мы определяем специальную переменную, которая будет называться свойством ( атрибут или поле класса ).
Модификатор доступа
Для того, чтобы определить переменную, используется набор ключевых слов, которые называются модификаторами доступа и характеризуют область видимости того или иного свойства:
— public ( общедоступный ) — этот модификатор разрешает доступ к свойствам и методам класса отовсюду,
— protected ( защищенный ) — этот модификатор разрешает доступ самому классу, наследующим его классам и родительским классам,
— private ( закрытый ) — этот модификатор ограничивает область видимости так, что только класс, где объявлен сам элемент, имеет к нему доступ.
В нашем классе будем использовать модификатор доступа public .
Зададим для нашего класса четыре свойства. При желании можно задать дефолтные (по умолчанию) значения этим свойствам.
Файл Car.php
<?php
class Car // создание класса Car
<
// свойства определяем в теле класса:
// (цвет) — свойство класса (атрибут или поле класса)
public $color ;
// (количество колес — задаем: 4)
public $wheels = 4 ;
// (скорость — задаем: 180)
public $speed = 180 ;
// (марка) — var — перешло из PHP 4 (синоним ключевого слова public)
var $brand ;
>
?>
Cоздадим файл index.php и подключим в нем класс Car.php и создадим объект $car1 — 1-й автомобиль и распечатаем его:
Файл index.php
<?php
// подключение файла Car.php
require_once ‘classes/Car.php’ ;
// функция для удобной распечатки
function debug ( $data )
<
echo ‘<pre>’ . print_r ( $data , 1 ) . ‘</pre>’ ;
>
// создаем объект (1-й автомобиль)
$car1 = new Car ();
// распечатываем объект (1-й автомобиль)
debug ( $car1 );
var_dump ( $car1 );
?>
работа функции debug($data):
Car Object
(
[color] =>
[wheels] => 4
[speed] => 180
[brand] =>
)
Добавление и переопределение значения свойства вне класса
Если свойство определено как public , мы можем добавлять значения вне класса , например:
$car1 -> color = ‘черный’ ; ( знак $ перед color не ставится. )
— где » -> » — оператор, который позволяет получить доступ к свойству или методу класса.
Также мы можем и переопределить уже имеющиеся свойства:
$car1 -> speed = 200 ;
Создадим еще один объект $car2 = new Car() и зададим для него значения свойств.
Еще одна особенность объектов, что мы можем добавлять » на лету » новые свойства, которых в классе нет. Для этого обращаемся к объекту и добавляем новое свойство:
$car1 -> year = 2018 ;
Динамически добавлять свойства не рекомендуется.
Распечатаем переменные $car1 и $car2 .
Файл index.php
<?php
// подключение файла Car.php
require_once ‘classes/Car.php’ ;
// функция для удобной распечатки
function debug ( $data )
<
echo ‘<pre>’ . print_r ( $data , 1 ) . ‘</pre>’ ;
>
// создаем объект (1-й автомобиль)
$car1 = new Car ();
// создаем второй объект (2-й автомобиль)
$car2 = new Car ();
// распечатываем объект (1-й автомобиль)
debug ( $car1 );
var_dump ( $car1 );
// обращение к свойству объекта (определяем цвет (вне класса))
// оператор «->» позволяет получить доступ к свойству или методу класса
$car1 -> color = ‘черный’ ;
$car1 -> brand = ‘volvo’ ;
// переопределяем имеющееся свойство (скорость)
$car1 -> speed = 200 ;
// добавляем на лету (динамически) новое свойство, которого в классе нет (год выпуска)
// динамически добавлять свойства не рекомендуется
$car1 -> year = 2018 ;
// зададим свойства для объекта $car2
$car2 -> color = ‘белый’ ;
$car2 -> brand = ‘bmv’ ;
$car2 -> speed = 220 ;
$car2 -> year = 2017 ;
debug ( $car1 );
debug ( $car2 );
?>
Выведет:
1-й автомобиль со свойствами, заданными в классе:
Car Object
(
[color] =>
[wheels] => 4
[speed] => 180
[brand] =>
)
1-й автомобиль с определенными и переопределенными свойствами вне класса:
Car Object
(
[color] => черный
[wheels] => 4
[speed] => 200
[brand] => volvo
[year] => 2018
)
2-й автомобиль с определенными и переопределенными свойствами вне класса
Car Object
(
[color] => белый
[wheels] => 4
[speed] => 220
[brand] => bmv
[year] => 2017
)
Вывод информации о созданном объекте
Обрабатывать данные в двойных кавычках (в одинарных кавычках переменные обрабатываться не будут) и в фигурных скобках вместо операции конкатенации .
Включаем показ ошибок: error_reporting(-1) — пусть нам показывает PHP все ошибки, которые возникают.
Файл index.php
<?php
// включаем показ ошибок
error_reporting (- 1 );
// подключение файла Car.php
require_once ‘classes/Car.php’ ;
// функция для удобной распечатки
function debug ( $data )
<
echo ‘<pre>’ . print_r ( $data , 1 ) . ‘</pre>’ ;
>
// создаем объект (1-й автомобиль)
$car1 = new Car ();
// создаем вторй объект (2-й автомобиль)
$car2 = new Car ();
// распечатываем объект (1-й автомобиль)
debug ( $car1 );
var_dump ( $car1 );
// обращение к свойству объекта (определяем цвет (вне класса))
// оператор «->» позволяет получить доступ к свойству или методу класса
$car1 -> color = ‘черный’ ;
$car1 -> brand = ‘volvo’ ;
// переопределяем имеющееся свойство (скорость)
$car1 -> speed = 200 ;
// добавляем на лету (динамически) новое свойство, которого в классе нет (год выпуска)
// динамически добавлять свойства не рекомендуется
$car1 -> year = 2018 ;
// зададим свойства для объекта $car2
$car2 -> color = ‘белый’ ;
$car2 -> brand = ‘bmv’ ;
$car2 -> speed = 220 ;
$car2 -> year = 2017 ;
// вывод информации о созданом объекте (автомобиле)
// (обрабатывать в двойных кавычках! и в фигурных скобках)
echo «<h3>О моем авто:</h3>
Марка: < $car1 ->brand > <br>
Цвет: < $car1 ->color > <br>
Кол-во колес: < $car1 ->wheels > <br>
Год выпуска: < $car1 ->year > <br>
Скорость: < $car1 ->speed > <br> » ;
?>
выведет:
О моем авто:
Марка: volvo
Цвет: черный
Кол-во колес: 4
Год выпуска: 2018
Скорость: 200
Возможности с версии PHP 5.6
С версий PHP 5.6 и больше можно присваивать свойству результаты вычислений, использовать оператор конкатенации.
Файл Car.php
<?php
class Car // создание класса Car
<
// свойства определяем в теле класса:
// (цвет) — свойство класса (атрибут или поле класса)
public $color ;
// (количество колес — задаем: 4)
public $wheels = 4 ;
// (скорость — задаем: 180)
public $speed = 180 ;
// (марка) — var — перешло из PHP 4 (синоним ключевого слова public)
var $brand ;
// возможность с версии PHP 5.6
// определение пути к папке test ( использование оператора конкатенации )
public $paht = __DIR__ . ‘/test’ ;
// публичное свойство $test ( присваивание свойству результата вычислений )
public $test = 1 + 2 ;
>
?>
После распечатки в индексном файле выведет:
Car Object
(
[color] =>
[wheels] => 4
[speed] => 180
[brand] =>
[paht] => C:\OSPanel\domains\PHPoop1\02\classes/test — путь к папке test
[test] => 3 — результат выражения 1+2
)
Классы и объекты в PHP
Класс — это шаблон для объектов, а объект — это экземпляр класса.
Представьте, что у нас есть класс Car . Car может иметь такие свойства, как название, цвет, диски и т.д. Мы можем определить переменные класса например, $name , $color и $disk для хранения значений этих свойств.
Если мы создадим отдельные объекты (BMW, Mercedes Benz и т.д.), то они будут наследовать все свойства и поведение класса Car , но каждый объект будет иметь разные значения свойств.
Что такое класс PHP?
Класс определяется с помощью ключевого слова class , за которым следует имя класса и пара фигурных скобок (<>). Все его свойства и методы заключены в фигурные скобки:
Синтаксис
Ключевое слово class используется для определения класса в PHP. Ниже приведены правила создания класса в PHP:
- Пишем название класса с большой буквы.
- Если имя класса содержит более одного слова, мы пишем каждое слово с большой буквы. Это известный стиль верблюда. Например, JapaneseCars, AmericanIdol, EuropeTour и др.
- Имя класса не может быть зарезервированным словом PHP.
- Имя класса не может содержать пробелов.
Как добавить свойства к классу?
Мы вызываем свойства внутри класса. Свойства могут принимать такие значения, как строки, целые числа и логические значения (true/false), как и любые другие переменные. Добавим несколько свойств в класс Car:
Приведем правила создания свойств к классу:
- Мы используем ключевое слово public перед свойством класса.
- Согласно соглашению об именах, имя свойства начинается со строчной буквы.
- Если имя содержит более одного слова, все слова, кроме первого слова, начинаются с заглавной буквы. Например, $color или $hasSunRoof (Верблюжий регистр camelCase).
- Свойство может иметь значение по умолчанию. Например, $color = ‘green’.
- Мы также можем создать свойство без значения по умолчанию. Например, $name.
Объявим класс с именем Car , который будет состоять из двух свойств ( $name и $color ) и двух методов set_name() и get_name() для установки и получения свойства $name :
Пример
Данный код ничего не выведет, поскольку мы создали класс, но не создали пока ни одного объекта.
Примечание: В классе переменные называются свойствами, а функции — методами!
Что такое объект PHP?
Объект — это экземпляр класса. Из класса мы можем создать столько объектов, сколько может понадобиться для проекта. Каждый объект имеет все свойства и методы, определенные в классе, но у них будут разные значения свойств.
Для объявления объекта необходимо использовать ключевое слово new .
Далее создадим из класса Car два объекта — $bmw и $mercedes .
Процесс создания объекта также известен как создание экземпляра.
Объекты, для чего они нужны?
В то время как в процедурном стиле программирования все функции и переменные находятся вместе в глобальной области видимости таким образом, чтобы их можно было использовать, просто вызывая их имя, использование классов делает манипуляции с кодом внутри классов скрытыми от глобальной области. Это происходит потому, что код внутри классов инкапсулируется в пределах класса, вне досягаемости глобальной области. Итак, нам нужен способ, позволяющий коду из глобальной области видимости использовать код внутри класса, и этот способ базируется на создании объектов из класса.
Мы можем создать столько объектов, сколько захотим, из одного и того же класса, и все они будут совместно использовать методы и свойства класса. См. изображение ниже:

Из одного и того же класса Car мы создали три отдельных объекта с названиями: Mercedes , Bmw и Audi .
Хотя все объекты были созданы из одного и того же класса и, следовательно, имеют методы и свойства класса, они все же разные. Это не только потому, что они имеют разные названия, но и потому, что их свойствам могут быть присвоены разные значения. Например, на изображении выше они различаются свойством цвета: Mercedes зеленый, Bmw синий, а Audi оранжевый.
Примечание: Класс содержит методы и свойства, общие для всех созданных из него объектов.
Хотя объекты используют один и тот же код, они могут вести себя по-разному, поскольку им могут быть присвоены разные значения.
Как получить свойства объекта?
Создав объект, мы можем получить его свойства. Например:
Когда объект создан, мы можем получить доступ к свойствам класса с помощью оператора (->) .
Обратите внимание, что имя свойства не начинается со знака $ ; только имя объекта начинается с символа $ .
Пример
Результат выполнения кода:
Свойство color было установлено в классе по умолчанию (green), поэтому все объекты его унаследовали.
Как установить свойства объекту?
Чтобы установить свойство объектe, мы используем аналогичный подход.
Например, установим синий цвет объекту bmw :
Таким же способом установим значение свойства $name для обоих объектов:
Установив значение свойства, мы можем получить его значение. Чтобы получить цвет объекта $bmw , мы используем следующую строку кода:
Обращение к свойствам класса через $this
Пусть теперь наш метод show() выводит нечто полезное — имя пользователя, которое хранится в свойстве name . Для того, чтобы обратиться к свойству класса внутри метода этого класса, вместо имени объекта следует писать специальную переменную $this :
Почему внутри класса нельзя написать так — $user->name ? Потому что это имя переменной снаружи класса и сам класс про это имя ничего не знает (более того, у нас же могут быть несколько объектов одного класса, и у них будут разные имена переменных).
Давайте создадим объект нашего класса и проверим работу метода show() :
Сделайте класс Employee , в котором будут следующие свойства — name , age , salary .
Сделайте в классе Employee метод getName , который будет возвращать имя работника.
Сделайте в классе Employee метод getAge , который будет возвращать возраст работника.
Сделайте в классе Employee метод getSalary , который будет возвращать зарплату работника.
Сделайте в классе Employee метод checkAge , который будет проверять то, что работнику больше 18 лет и возвращать true , если это так, и false , если это не так.
Создайте два объекта класса Employee , запишите в их свойства какие-либо значения. С помощью метода getSalary найдите сумму зарплат созданных работников.
Запись свойств
С помощью $this свойства можно не только прочитывать, но и записывать. Давайте сделаем метод setName() , который параметром будем принимать имя пользователя и записывать его в свойство name :
Сделайте класс User , в котором будут следующие свойства — name и age .
Сделайте метод setAge , который параметром будет принимать новый возраст пользователя.
Создайте объект класса User с именем ‘john’ и возрастом 25 . С помощью метода setAge поменяйте возраст на 30 . Выведите новое значение возраста на экран.
Модифицируйте метод setAge так, чтобы он вначале проверял, что переданный возраст больше или равен 18 . Если это так — пусть метод меняет возраст пользователя, а если не так — то ничего не делает.
Сделайте класс Employee , в котором будут следующие свойства работника — name , salary . Сделайте метод doubleSalary , который текущую зарплату будет увеличивать в 2 раза.
Сделайте класс Rectangle , в котором в свойствах будут записаны ширина и высота прямоугольника.
В классе Rectangle сделайте метод getSquare , который будет возвращать площадь этого прямоугольника.
В классе Rectangle сделайте метод getPerimeter , который будет возвращать периметр этого прямоугольника.