При создании программы на PHP и отдельных ее блоков нам вполне может хватить той функциональности, которую представляют функции. Однако PHP имеет и другие возможности по созданию программ, которые представляет объектно-ориентированное программирование. В ряде случаев программы, использующие ООП, проще в понимании, их легче поддерживать и изменять.
Ключевыми понятиями парадигмы ООП являются понятия "класс" и "объект". Описанием объекта является класс, а объект представляет экземпляр этого класса. Можно провести следующую аналогию: например, у каждого человека есть имя, определенный возраст, вес, какие-то другие параметры. То есть некоторый шаблон, который содержит набор параметров человека - этот шаблон можно назвать классом. А реально же существующий человек с конкретным именем, возрастом, весом и т.д. является объектом или экземпляром этого класса.
Для создания класса в PHP используется ключевое слово class, после которого идет название класса и фигурные скобки {} - блок кода класса. Например, новый класс, представляющий пользователя:
class Person
{}
Чтобы создать объект класса Person, применяется ключевое слово new:
<?php
class Person
{ }
$person = new Person();
print_r($person);
?>
В данном случае переменная $person является объектом класса Person. С помощью функции print_r() можно вывести содержимое объекта,
как и в случае с массивами.
При этом неважно, определяется класс до или после создания объекта. Например, мы можем сначала определить переменную класса, а потом определить этот класс:
<?php
$person = new Person();
class Person
{ }
?>
Класс может содержать переменные, которые описывают какие-то признаки объекта, его состояние и которые еще назывют свойствами или атрибутам. И также класс класс может содержать функции, которые еще назвают методами и которые определяют его поведение.
Так, добавим в класс Person несколько свойств и методов:
<?php
class Person
{
public $name, $age;
function hello()
{
echo "Hello!<br>";
}
}
$tom = new Person();
$tom->name = "Tom"; // установка свойства $name
$tom->age = 36; // установка свойства $age
$personName = $tom->name; // получение значения свойства $name
echo "Имя пользователя: " . $personName . "<br>";
$tom->hello(); // вызов метода hello()
print_r($tom);
?>
Здесь класс Person содержит два свойства: $name и $age. Свойства объявляются как обычные переменные, перед которыми стоит
модификатор доступа - в данном случае модификатор public.
Методы представляют обычные функции, которые выполняют определенные действия. Здесь функция hello() просто выводит приветствие.
После создания объекта класса Person:
$tom = new Person();
Мы можем через имя переменной класса обращаться к его свойствам и методам. Чтобы обратиться к свойствам и методам объекта применяется оператор доступа ->. Например, установить значения свойств:
$tom->name = "Tom"; // установка свойства $name $tom->age = 36; // установка свойства $age
Или получить значение (например, присвоить его переменной):
$personName = $tom->name; // получение значения свойства $name
Или вызвать методы объекта:
$tom->hello(); // вызов метода hello()
В итоге мы получим следующий вывод браузера:
Имя пользователя: Tom Hello! Person Object ( [name] => Tom [age] => 36 )
При этом свойствам можно задать в классе некоторые начальные значения:
<?php
class Person
{
public $name = "Undefined", $age = 18;
function hello()
{
echo "Hello!<br>";
}
}
$tom = new Person();
$tom->age = 36; // установка свойства $age
echo "Имя пользователя: " . $tom->name . "<br>";
echo "Возраст пользователя: " . $tom->age . "<br>";
?>
Вывод брузера:
Имя пользователя: Undefined Возраст пользователя: 36
Для обращения к свойствам и методам объекта внутри его класса применяется ключевое слово this. Например, определим в классе метод для вывода информации об объекте:
<?php
class Person
{
public $name = "Undefined", $age = 18;
function displayInfo()
{
echo "Name: " . $this->name ."; Age: " . $this->age . "<br>";
// также можно написать
// echo "Name: $this->name; Age: $this->age<br>";
}
}
$tom = new Person();
$tom -> name = "Tom";
$tom -> displayInfo(); // Name: Tom; Age: 18
?>
Для обращения к полям и методам внутри класса также применяется оператор доступа ->, перед которым идет $this. Причем это $this указывает именно на текущий объект. Что это значит в практическом плане? Например:
<?php
class Person
{
public $name = "Undefined", $age = 18;
function displayInfo()
{
echo "Name: $this->name; Age: $this->age<br>";
}
}
$tom = new Person();
$tom -> name = "Tom";
$tom -> displayInfo();
$bob = new Person();
$bob -> name = "Bob";
$bob -> age = 25;
$bob -> displayInfo();
?>
При вызове
$tom -> displayInfo();
$this фактически будет указывать на переменную $tom. Тогда как при вызове
$bob -> displayInfo();
$this будет указывать на переменную $bob.
Вывод браузера:
Name: Tom; Age: 18 Name: Bob; Age: 25
При сравнении объектов классов следует принимать во внимание ряд особенностей. В частности, при использовании оператора равенства == два объекта считаются равными, если они представляют один и тот же класс и их свойства имеют одинаковые значения.
А при использовании оператора эквивалентности === оба объекта считаются равными, если обе переменных классах указывают на один и тот же экземпляр класса.
Рассмотрим на примере:
<?php
class Person
{
public $name, $age;
function displayInfo()
{
echo "Name: $this->name; Age: $this->age<br>";
}
}
$tom = new Person();
$tom -> name = "Tom";
$tom -> age = 36;
$tomas = new Person();
$tomas -> name = "Tom";
$tomas -> age = 36;
if($tom == $tomas) echo "переменные tom и tomas равны<br>";
else echo "переменные tom и tomas НЕ равны<br>";
if($tom === $tomas) echo "переменные tom и tomas эквивалентны";
else echo "переменные tom и tomas НЕ эквивалентны";
?>
Здесь сравниваются две переменных - $tom и $tomas. Они представляют один и тот же класс Person, и их свойства имеют одни и те же значения.
Однако они представляют разные объекты. Поэтому при сравнении оператор == возвратит true, а
оператор === - false:
переменные tom и tomas равны переменные tom и tomas НЕ эквивалентны
Возьмем другой пример, когда обе переменных представляют один и тот же объект:
$person = new Person(); $tom = $person; $tom -> name = "Tom"; $tom -> age = 36; $tomas = $person; if($tom == $tomas) echo "переменные tom и tomas равны<br>"; else echo "переменные tom и tomas НЕ равны<br>"; if($tom === $tomas) echo "переменные tom и tomas эквивалентны"; else echo "переменные tom и tomas НЕ эквивалентны";
Здесь объект класса Person создается только один раз: $person = new Person();. И затем обе переменных $tom и $tomas будут указывать
на этот объект. При этом не имеет значения, для какой именно переменной мы устанавливаем свойства. Так как в реальности это будет один и тот же объект.
В итоге и оператор ==, и оператор === при сравнении возвратят true
переменные tom и tomas равны переменные tom и tomas эквивалентны