Reg.ru: домены и хостинг

Крупнейший регистратор и хостинг-провайдер в России.

Более 2 миллионов доменных имен на обслуживании.

Продвижение, почта для домена, решения для бизнеса.

Более 700 тыс. клиентов по всему миру уже сделали свой выбор.

Перейти на сайт->

Бесплатный Курс "Практика HTML5 и CSS3"

Освойте бесплатно пошаговый видеокурс

по основам адаптивной верстки

на HTML5 и CSS3 с полного нуля.

Начать->

Фреймворк Bootstrap: быстрая адаптивная вёрстка

Пошаговый видеокурс по основам адаптивной верстки в фреймворке Bootstrap.

Научитесь верстать просто, быстро и качественно, используя мощный и практичный инструмент.

Верстайте на заказ и получайте деньги.

Получить в подарок->

Бесплатный курс "Сайт на WordPress"

Хотите освоить CMS WordPress?

Получите уроки по дизайну и верстке сайта на WordPress.

Научитесь работать с темами и нарезать макет.

Бесплатный видеокурс по рисованию дизайна сайта, его верстке и установке на CMS WordPress!

Получить в подарок->

*Наведите курсор мыши для приостановки прокрутки.


Объектно-ориентированный подход в PHP для начинающих. Часть 2

Этот материал - продолжение статьи Объектно-ориентированный подход в PHP для начинающих. Часть 1.

В этой статье будут рассмотрены вопросы использования конструкторов, деструкторов и других магических методов в PHP. Кроме того, Вы узнаете о наследовании классов, а также перегрузке методов и свойств.

Магические методы в ООП

Чтобы упростить использование объектов, PHP также предоставляет некоторое количество магических методов (или специальных методов), которые вызываются, когда в пределах объекта происходят определенные действия. Это позволяет разработчикам выполнять некоторые полезные операции с большей легкостью.

Использование Конструкторов и Деструкторов

Когда мы создаем новый объект, часто бывает желательно сразу произвести определенные действия. Для того, чтобы осуществить это, PHP предлагает магический метод __construct(), который вызывается автоматически всякий раз, когда создается новый экземпляр класса.

Для иллюстрации работы конструктора добавьте в класс MyClass конструктор, который будет выводить на экран сообщение всякий раз при создании нового экземпляра класса:

Хостинг

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Создаем новый объект
$obj = new MyClass;

// Получаем значение свойства $prop1
echo $obj->getProperty();

// Выводим сообщение в конце файла
echo "Конец файла.<br />";

?>

Замечание:
__CLASS__ - это константа, которая возвращает имя класса, в котором она была вызвана, одна из так называемых магических констант, подробнее о которых можно почитать в руководстве по PHP.

Перезагрузите страницу в браузере и Вы увидите такой результат:

Класс MyClass был инстанцирован! (Был создан экземпляр класса)
Я - свойство класса!
Конец файла.

Для того, чтобы выполнить определенные действия, когда объект уничтожается, нужно воспользоваться методом __destruct(). Это бывает полезно для очистки класса (например, для закрытия соединения с базой данных).

Давайте выведем соответствующее сообщение об уничтожении объекта с помощью данного метода:

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function __destruct()
    {
       echo 'Объект уничтожен.<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Создаем новый объект
$obj = new MyClass;

// Получаем значение свойства $prop1
echo $obj->getProperty();

// Выводим сообщение в конце файла
echo "Конец файла.<br />";

?>

При использовании деструктора после перезагрузки страницы мы получим следующий результат:

Класс MyClass был инстанцирован! (Был создан экземпляр класса)
Я - свойство класса!
Конец файла.
Объект уничтожен.


"Когда достигнут конец файла, PHP автоматически освобождает все ресурсы"


Чтобы явно вызвать деструктор, Вы можете уничтожить объект с помощью функции unset():

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function __destruct()
    {
       echo 'Объект уничтожен.<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Создаем новый объект
$obj = new MyClass;

echo $obj->getProperty();

// Уничтожаем объект
unset($obj);

// Выводим сообщение в конце файла
echo "Конец файла.<br />";
?>

При обновлении страницы в браузере Вы увидите следующую картину:

Класс MyClass был инстанцирован! (Был создан экземпляр класса)
Я - свойство класса!
Объект уничтожен.
Конец файла.

Обратите внимание, что вывод фразы "Объект уничтожен" теперь происходит раньше вывода фразы "Конец файла", т.к. в первом случае функция-деструктор срабатывала только после того, как в файле заканчивался весь код, а теперь мы явно уничтожаем объект раньше, что приводит к более раннему вызову деструктора.

Преобразование в Строку

Для того, чтобы избежать ошибки при попытке вывести объект как строку, следует использовать еще один магический метод - __toString().

Без его использования такая попытка приведет к фатальной ошибке:

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function __destruct()
    {
       echo 'Объект уничтожен.<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Создаем новый объект
$obj = new MyClass;

// Выводим объект как строку
echo $obj;

// Уничтожаем объект
unset($obj);

// Выводим сообщение в конце файла
echo "Конец файла.<br />";

?>

Выполнение этого кода приведет к следующему:

Класс MyClass был инстанцирован! (Был создан экземпляр класса)
Catchable fatal error: Object of class MyClass could not be converted to string in... on line...

Для того, чтобы избежать этой ошибки воспользуемся методом __toString():

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function __destruct()
    {
       echo 'Объект уничтожен.<br />';
    }

    public function __toString()
    {
        echo "Используем метод __toString(): ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Создаем новый объект
$obj = new MyClass;

// Выводим объект как строку
echo $obj;

// Уничтожаем объект
unset($obj);

// Выводим сообщение в конце файла
echo "Конец файла.<br />";

?>

В этом случае, попытка вывести объект как строку ведет к обращению к методу getProperty().

Следует помнить о том, что метод __toString() вызывается только, если объект встречается напрямую в echo() или print().

Хостинг

Обновив страницу, Вы увидите:

Класс MyClass был инстанцирован! (Был создан экземпляр класса)
Используем метод __toString(): Я - свойство класса!
Объект уничтожен.
Конец файла.

Примечание:
Помимо тех магических методов, которые мы рассмотрели, существуют и другие. Для того, чтобы увидеть весь список этих методов, обратитесь к руководству по PHP

Наследование Классов

Классы могут наследовать методы и свойства других классов благодаря использованию ключевого слова extends. Например, для того, чтобы создать второй класс, который наследует класс MyClass и который имеет внутри себя метод, нужно поступить следующим образом:

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function __destruct()
    {
       echo 'Объект уничтожен.<br />';
    }

    public function __toString()
    {
        echo "Используем метод __toString(): ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}


class MyOtherClass extends MyClass
{
    public function newMethod()
    {
        echo "Из нового метода в классе " . __CLASS__ . ".<br />";
    }
}

// Создаем новый объект
$newobj = new MyOtherClass;

// Выводим объект как строку
echo $newobj->newMethod();

// Используем метод из родительского класса MyClass
echo $newobj->getProperty();

?>

Перезагрузите страницу и Вы увидите следующее:

Класс MyClass был инстанцирован! (Был создан экземпляр класса)
Из нового метода в классе MyOtherClass.
Я - свойство класса!
Объект уничтожен.

Именно наследование приводит к тому, что при создании экземпляра класса MyOtherClass мы можем обращаться как к методам родительского класса MyClass, так и к методам самого класса MyOtherClass (который является дочерним по отношению к MyClass).

Перезапись (перегрузка) унаследованных Свойств и Методов

Для того, чтобы изменить значение или поведение существующего свойства или метода в новом классе, Вы можете просто перезаписать (перегрузить) его, объявив его в новом классе:

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function __destruct()
    {
       echo 'Объект уничтожен.<br />';
    }

    public function __toString()
    {
        echo "Используем метод __toString(): ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}


class MyOtherClass extends MyClass
{
    public function __construct()
    {
        echo "Новый конструктор из класса " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "Из нового метода в классе " . __CLASS__ . ".<br />";
    }
}

// Создаем новый объект
$newobj = new MyOtherClass;

// Выводим объект как строку
echo $newobj->newMethod();

// Используем метод из родительского класса MyClass
echo $newobj->getProperty();

?>

Это приведет к следующим изменениям на странице:

Новый конструктор из класса MyOtherClass.
Из нового метода в классе MyOtherClass.
Я - свойство класса!
Объект уничтожен.

Здесь, как Вы можете видеть, в классе MyOtherClass мы перегрузили метод __construct(), что привело к выводу нового сообщения.

Сохранение исходной функциональности Метода при его перегрузке

Чтобы добавить новые функциональные возможности к унаследованному методу, сохраняя при этом оригинальный метод нетронутым, используйте ключевое слово parent с оператором (::). Рассмотрим это на примере функции-конструктора в классе MyOtherClass:

<?php

class MyClass
{
    public $prop1 = "Я - свойство класса!";

    public function __construct()
    {
        echo 'Класс ' . __CLASS__ . ' был инстанцирован! (Был создан экземпляр класса)<br />';
    }

    public function __destruct()
    {
       echo 'Объект уничтожен.<br />';
    }

    public function __toString()
    {
        echo "Используем метод __toString(): ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}


class MyOtherClass extends MyClass
{
    public function __construct()
    {
        parent::__construct(); // Вызываем конструктор родительского класса (MyClass)
        echo "Новый конструктор из класса " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "Из нового метода в классе " . __CLASS__ . ".<br />";
    }
}

// Создаем новый объект
$newobj = new MyOtherClass;

// Выводим объект как строку
echo $newobj->newMethod();

// Используем метод из родительского класса MyClass
echo $newobj->getProperty();

?>

Такой подход приведет к тому, что на экран будут выведены результаты выполнения как конструктра родительского класса MyClass, так и дочернего класса MyOtherClass:


Класс MyClass был инстанцирован! (Был создан экземпляр класса)
Новый конструктор из класса MyOtherClass.
Из нового метода в классе MyOtherClass.
Я - свойство класса!
Объект уничтожен.

По материалам net.tutsplus.com
Перевод - Дмитрий Науменко.

P.S. Хотите двигаться дальше в освоении PHP и ООП? Обратите внимание на премиум-уроки по различным аспектам сайтостроения, включая программирование на PHP, а также на бесплатный курс по созданию своей CMS-системы на PHP с нуля с использованием ООП:

Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!


Смотрите также:

PHP: Получение информации об объекте или классе, методах, свойствах и наследовании

PHP: Получение информации об объекте или классе, методах, свойствах и наследовании

CodeIgniter: жив или мертв?

CodeIgniter: жив или мертв?

Функции обратного вызова, анонимные функции и механизм замыканий

Функции обратного вызова, анонимные функции и механизм замыканий

Применение функции к каждому элементу массива

Применение функции к каждому элементу массива

Слияние массивов. Преобразование массива в строку

Слияние массивов. Преобразование массива в строку

Деструктор и копирование объектов с помощью метода __clone()

Деструктор и копирование объектов с помощью метода __clone()

Эволюция веб-разработчика или Почему фреймворк - это хорошо?

Эволюция веб-разработчика или Почему фреймворк - это хорошо?

Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.)

Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.)

PHP: Удаление элементов массива

PHP: Удаление элементов массива

Ключевое слово final (завершенные классы и методы в PHP)

Ключевое слово final (завершенные классы и методы в PHP)

50 классных сервисов, программ и сайтов для веб-разработчиков

50 классных сервисов, программ и сайтов для веб-разработчиков

Наверх