Урок 4. Курс по ООП PHP. Методы __construct и __destruct


Содержание материала:

Объектное программирование

Объектно-ориентированное программирование (ООП) на PHP

Объект — это набор специальных переменных — свойств и специальных функций — методов. То, что в процедурном программировании называлось переменной — в ООП называется свойство. То, что в процедурном программировании называлось функцией — в ООП называется методом класса. Созданные на основе класса объекты называются экземплярами класса или просто объекты.

Обращение из метода к свойствам только через служебное слово $this: $this->name; (обратите внимание на отсутствие знака доллара перед name) Обращение внутри метода к другому методу тоже через $this: $this->foo(); Для доступа к свойствам и методам объекта служит оператор «->»: $this->name; (обратите внимание на отсутствие знака доллара перед name)
Обращение внутри метода к другому методу тоже через $this: $this->foo(); . Объект создается с помощью оператора new на основании шаблона, называемого классом. Класс определяется ключевым словом class.

Пример 1

Модификаторы доступа в ООП:

  • public — позволяет иметь доступ к свойствам и методам из любого места (глобальная область)
  • protected — доступ к родительскому и наследуемому классу (область класса наследника)
  • private — доступ только из класса, в котором объявлен сам элемент (область самого класса)

Метод по умолчанию — public. У свойств значения модификатора по умолчанию нет.

Константы класса в ООП

this и self

Внутри класса использована специальная переменная this. Это указатель, с помощью которого объект может ссылаться на самого себя.

Для обращения к статическим методам используется self::

Методу Пока передан аргумент точно так же, как и обычной функции. При вызове этого метода объект меняет свое свойство имя.

Маша! Привет!

Миша! Привет!

Яша! Пока!

Яша! Привет!

Конструктор — это метод, который автоматически вызывается при создании нового объекта: public function __construct()<> . При инициализации6 объекта через служебную конструкцию new, PHP ищет __construct и если он есть, то вызывается.

Также можно создать метод, имя которого совпадает с именем класса, — такой метод также будет считаться конструктором. Конструктор может принимать аргументы, что значительно упрощает работу с классами.

Пример 2

Кто-то там! Привет!

Миша! Привет!

Маша! Привет!

Сложив все, изложенное выше, можно создать более осмысленный класс. Например, класс, который будет располагать данные в виде таблицы с поименнованными столбцами.

Урок 4. Курс по ООП PHP. Методы __construct и __destruct

Новая объектно-ориентированная модель в PHP5

Когда Зив Сераски (Zeev Suraski) добавил объектно-ориентированный (ОО) синтаксис в PHP 3, это можно было рассматривать как «синтаксический подсластитель для поддержки классов» («syntactic sugar for accessing collections»). Объектно-ориентированная модель получила поддержку наследования и позволяла классу (и объекту) объединять методы и свойства, но не более того. Когда Зив и Анди переписали движок для PHP 4, это был полностью новый движок, работающий намного быстрее, намного стабильнее и с еще многими другими возможностями. Однако, изменения практически не затронули ОО модель, первоначально введенную еще в РНР 3.

Хотя объектная модель имела серьезные ограничения, она широко использовалась, часто в очень больших приложениях, написанных на PHP. Это победное шествование парадигмы ООП, даже такой ограниченной в РНР 4, привело к тому, что изменения объектной модели стали центральными в новом релизе РНР — PHP5.

Какие были ограничения в PHP 3 и 4? Самым большим ограничением (которое и приводило ко всем остальным ограничениям) был тот факт, что семантика экземпляра объекта была такой же, что и для родных типов. Как это фактически отражалось на разработчиках? Когда вы присваивали переменную (которая указывает на объект) другой переменной, то создавалась копия объекта. Мало того, что это влияло на производительность, но и это обычно приводило к ошибкам в приложении, потому что многие разработчики думали, что обе переменные будут указывать на тот же самый объект. А они указывали на разные копии того же самого объекта, поэтому, изменяя один объект, мы не меняли другой. Вот пример:

class Person <
var $name ;
function getName () <
return $this -> name ;
>
function setName ( $name ) <
$this -> name = $name ;
>
function Person ( $name ) <
$this -> setName ( $name );
>
>

function changeName ( $person , $name ) <
$person -> setName ( $name );
>

$person = new Person ( «Andi» );
changeName ( $person , «Stig» );
print $person -> getName ();
?>

В РНР 4 этот код выведет «Andi». Причина кроется в том, что мы передаем объект $person в функцию changeName() по значению, а не по ссылке, таким образом, объект $person будет скопирован, и changeName() будет работать уже с копией объекта $person.

Такое поведение не является интуитивно понятным. Действительно, многие разработчики ожидали Java-подобного поведения. В Java, переменные фактически являются указателями на объект, и поэтому при дублировании будет скопирован указатель, а не сам объект.

Было два вида разработчиков: те, кто знал об этой проблеме, и те, кто не знал. Последние, обычно, не сталкивались с этой проблемой, потому что их код был написан так, что было безразлично, существует ли такая проблема или нет. Конечно, некоторые из этих разработчиков проводили бессонные ночи в «увлекательных» поисках «сверхъестественных» ошибок. Первая группа также имела проблему, поскольку приходилось вручную определять передачу объекта по ссылке, запрещая движку копировать объекты, и код был испещрен многочисленными знаками ‘&‘.

Старая объектная модель приводит не только к вышеупомянутым проблемам, но также вскрывает более фундаментальные проблемы, которые на существующей объектной модели не позволяли осуществлять другие возможности.

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

Обратите внимание: явная передача и присваивание по ссылке также поддерживается, на тот случай, если вы хотите изменить содержимое переменной или объекта.

Новый объектно-ориентированный подход в PHP5

Новые возможности объектной модели являются слишком многочисленными. Приведем обзор главных изменений:


    public/private/protected — модификаторы доступа для методов и свойств

Позволяют управлять доступом к методам и свойствам. Теперь видимость свойств и методов может быть определена ключевыми словами: public, private, protected. Модификатор public позволяет обращаться к свойствам и методам отовсюду. Модификатор private позволяет обращаться к свойствам и методам только внутри текущего класса. Модификатор protected позволяет обращаться к свойствам и методам только текущего класса и класса, который наследует свойства и методы текущего класса.

/**
* Define MyClass
*/
class MyClass
<
public $public = ‘Public’ ;
protected $protected = ‘Protected’ ;
private $private = ‘Private’ ;

function printHello ()
<
echo $this -> public ;
echo $this -> protected ;
echo $this -> private ;
>
>

$obj = new MyClass ();
echo $obj -> public ; // Works
echo $obj -> protected ; // Fatal Error
echo $obj -> private ; // Fatal Error
$obj -> printHello (); // Shows Public, Protected and Private

/**
* Define MyClass2
*/
class MyClass2 extends MyClass
<
// We can redeclare the public and protected method, but not private
protected $protected = ‘Protected2’ ;

function printHello ()
<
echo $this -> public ;
echo $this -> protected ;
echo $this -> private ;
>
>

$obj2 = new MyClass2 ();
echo $obj -> public ; // Works
echo $obj2 -> private ; // Undefined
echo $obj2 -> protected ; // Fatal Error
$obj2 -> printHello (); // Shows Public, Protected2, not Private

Унифицированный конструктор __construct()

PHP 5 позволяет объявлять методы-конструкторы. Классы, в которых объявлен метод-констуктор, будут вызывать этот метод при каждом создании нового объекта, так что это может оказаться полезным, чтобы, например, инициализировать какое-либо состояние объекта перед его использованием. Конструктор, ранее совпадавший с названием класса, теперь необходимо объявлять как __construct(), что позволит легче перемещать классы в иерархиях. Конструкторы в классах-родителях не вызываются автоматически. Чтобы вызвать конструктор, объявленный в родительском классе, следует обратиться к методу parent::__construct() .

class BaseClass <
function __construct () <
print «Конструктор класса BaseClass\n» ;
>
>

class SubClass extends BaseClass <
function __construct () <
parent :: __construct ();
print «Конструктор класса SubClass\n» ;
>
>

$obj = new BaseClass ();
$obj = new SubClass ();
?>

Если PHP 5 не может обнаружить объявленный метод __construct() , вызов конструктора произойдет по прежней схеме, через обращение к методу, имя которого соответствует имени класса. Может возникнуть только одна проблема совместимости старого кода, если в нём присутствуют классы с методами __construct() .

Поддержка деструктора для класса, определяемого как метод __destructor()

PHP 5 предоставляет концепцию деструкторов, сходную с теми, что применяются в других ОО языках, таких, как Java: когда освобождается последняя ссылка на объект, перед высвобождением памяти, занимаемой этим объектом, вызывается метод __destruct() , не принимающий параметров.

class MyDestructableClass <
function __construct () <
print «Конструктор\n» ;
$this -> name = «MyDestructableClass» ;
>

function __destruct () <
print «Уничтожается » . $this -> name . «\n» ;
>
>

$obj = new MyDestructableClass ();
?>

Как и в случае с конструкторами, деструкторы, объявленные в родительском классе, не будут вызваны автоматически. Для вызова деструктора, объявленном в классе-родителе, следует обратиться к методу parent::__destruct() .

Конструктор PHP

Конструктор класса вызывается автоматически всякий раз, когда создаются экземпляры класса и объекты из класса. В PHP ООП конструктор используется для инициализации свойств во время создания объекта. Конструктор выглядит как обычный метод PHP , разница заключается только в том, что он начинается с __ ( двух символов подчеркивания ).

Конструктор класса PHP может содержать столько аргументов или параметров, сколько необходимо. Также можно определить конструктор вообще без параметров.

Важно отметить, что PHP-конструктор вызывается только один раз. И мы не можем вызвать конструктор явно, он вызывается автоматически при создании объекта.

Чтобы создать экземпляр класса, мы используем ключевое слово new, и в этот момент вызывается конструктор. В PHP родительский конструктор вызывается явно, если определен конструктор производного класса. Если требуется конструктор суперкласса, в производном классе нужен вызов parent::__construct() . Конструктор суперкласса может наследоваться, если производный класс не определяет конструктор сам. Наследуется конструктор так же, как и любой другой метод класса, если в суперклассе он не был объявлен как privat .

В PHP4 и ниже при определении конструктора использовался метод с таким же именем, что и класс ( как в C++ и Java ). PHP5 ООП для определения конструктора любого класса содержит специальную функцию __construct() . Конструктор может содержать аргументы в соответствии с конкретными требованиями. Все объекты могут иметь встроенную функцию-конструктор, которая инициализирует при создании объекта его свойства. PHP позволяет создать только один конструктор для каждого класса, и мы не можем перегрузить конструктор.

Если существует несколько объявленных конструкторов, PHP будет вызывать первый и игнорировать остальные. Конструктор должен быть объявлен как public и может использоваться вне класса. Если конструктор объявлен как private , он может быть использован только с классом, в котором он определен. В случае если необходимо объявить его как private , нам нужно будет использовать вызов статической функции.

Так как конструктор является магическим методом, он будет иметь отличительную метку магических методов — два подчеркивания в начале. Для определения конструктора мы используем ключевое слово construct :

Пример PHP-конструктора

Давайте предположим, что у нас есть класс PHP Human , и он содержит переменную name . Исходный код будет выглядеть следующим образом:

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

Создаем объекты этого класса с помощью ключевого слова new :

В этом ООП PHP примере мы создали объекты и инициализировали переменную $name . Первый объект будет хранить в переменной $name значение « Joseph «, а второй — « Taylor «. Мы присвоили объектам значения во время создания, чтобы избежать путаницы. Если бы для класса Human конструктор не был определен, то объекты создавались бы следующим образом:

PHP-конструктор с несколькими аргументами

Мы добавим новую переменную age в класс Human :

Сейчас наш класс содержит две переменные для хранения данных каждого объекта. Name и age представлены переменными $name и $age . Определяем конструктор еще раз, но на этот раз с двумя аргументами, один — чтобы установить экземпляр Name , а второй — age :

Мы создали два объекта, и они содержат начальные значения двух переменных-членов. Следует отметить, что согласно основам PHP ООП конструктор нельзя вызвать более одного раза, но мы можем изменять значения переменных-членов.

Поэтому в классе Human мы создадим два метода, один устанавливает возраст, а второй — имя. Конструктор используется, только чтобы задать начальные значения любой переменной. В дальнейшем, если нужно изменить это значение, мы будем использовать эти функции.

Тот же класс с двумя дополнительными методами:

Мы можем вызывать два новых метода, чтобы изменить имя или возраст. Добавим в пример еще два метода, чтобы вывести имя и возраст:

Полный пример использования конструктора класса PHP ООП с четырьмя функциями:

Еще один пример PHP-конструктора

Сначала мы определяем конструктор для класса bookinfo . Когда будут созданы объекты, мы передадим в конструктор значения для соответствующих экземпляров.

Давайте посмотрим, как используется конструктор. Сначала создаем простой класс с одним свойством и одной функцией:

Это простой класс, который содержит одну переменную данных, название машины, и метод вывода этого названия.

Теперь добавим конструктор, который будет задавать значение name в момент создания объекта. В ООП PHP код конструктора будет выглядеть следующим образом:

Теперь создаем из класса объект:

Выводим значение данных переменной через вызов метода get_carname() :

Результат будет следующим:

Это простой пример создания конструктора с инициализацией значения членов объекта. Это значение не фиксированное. Мы можем изменить его при необходимости. Тем не менее, это отличный способ инициализации объектов.

Используем конструктор в примере объекта PHP ООП , который мы рассматривали ранее. В классе bookinfo мы добавляем следующий код:

В примере после добавления этого кода инициализируются экземпляры класса, чтобы создать объекты. Тот же функционал достигается с помощью конструктора:

Теперь объекты созданы и инициализированы с названиями и ценами на момент создания объекта, это достигается с помощью конструктора.

Давайте получим доступ к методам get , чтобы вывести цены и названия книг. Используем те же методы, что и ранее:

Этот PHP-код дает следующий результат:

Up to date astrology
Up to date PHP
Up to date DB
25
36
17

Мы видим, что полученный результат тот же самый, но он достигнут с помощью конструктора.

ООП PHP пример базы данных, в котором используется конструктор класса PHP :

Данная публикация представляет собой перевод статьи « PHP Constructor » , подготовленной дружной командой проекта Интернет-технологии.ру

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

Так получилось что в ООП функции называют — методами а переменные — свойствами. В PHP5 существует несколько полезных методов несущих в себе «магический» функционал о них сейчас и пойдет речь.

Все методы начинающиеся с __ PHP считает «магическими».

__construct() — метод конструктор, если он объявлен в классе то он будет вызываться при каждом создании объекта. Может принимать одно или несколько свойств.

__destruct() — деструктор вызывается при освобождении всех ссылок на объект в котором он находится или по завершению работы скрипта. Не может принимать свойства.

__get() — будет выполнен при чтении данных из недоступных свойств.

__set() — будет выполнен при записи данных в недоступные свойства.

__isset() будет выполнен при использовании isset() или empty() на недоступных свойствах.

__unset() будет выполнен при вызове unset() на недоступном свойстве.

__toString() — позволяет написать реакцию класса при возведении его в строку.

__invoke() — вызывается когда скрипт выполняет объект как функцию.

__clone() — клонирует объект.

Смотрим все на примере

name=$name;
return 1;
>
public function __set($name,$value) <
# Ловим несуществующее свойство и его значение и отправляем их в массив
$this->colors[$name]=$value;
return 1;
>
public function __get($name) <
# Достаем ранее записанное методом __set() в массив несуществующее свойство
return $this->colors[$name];
>
public function __toString() <
# Обязательное условие — должна выводится именно строка
return $this->name;
>
public function __invoke($x) <
# Обрабатываем значение переданное объекту как функции
echo «Число состоит из «.strlen($x).»-х символов\n»;
>
public function __destruct() <
# Перед уничтожением класса из памяти он может дать о себе знать
print ‘Привет я класс ‘.__class__.’ примерно через 0.00001 секунды я буду уничтожен’;
>
>

# Создаем объект значение свойства будет переданно в метод __construct()
$obj=new Test(‘AndreRoux’);
echo $obj->name.»\n»;

# Выводим сам объект если метод __toString() не контролирует это действие то мы получаем E_RECOVERABLE_ERROR
echo $obj.»\n»;

# Обращаемся к объекту как к функции
$obj(2134);

# Даем значение несуществующему свойству, далее если оно действительно
# не существует за его обработку принимается функция __set()
$obj->color=’red’;
# Выводим несуществующее свойство
echo $obj->color.»\n»;

Действительно магия, не правда-ли?
Более подробно о «магических» методах читаем на сайте PHP.
Уверен что кому-нибудь эта информация будет полезна.

Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.

Урок 13: Объектно-ориентированное программирование #1

Об уроке

Первое занятие по объектно-ориентированному программированию.

ООП — это один из наиболее популярных подходов к программированию на данный момент. Именно благодаря этой концепции область веб-разработки совершила существенный прорыв за последние годы. В центре идеи находятся такие понятия как классы и объекты. В этом занятии мы начнем их изучать.

Материалы всех уроков по ООП достаточно сложные и содержат большое количество новой информации. Потому длительность видеозаписей составляет около 30 минут. Не пытайтесь пройти все занятия как можно быстрее. Внимательно (!) отрабатывайте каждую подтему.

ООП в PHP: продвинутый курс

Изучаем объектно-ориентированное программирование
Первые 5 уроков бесплатно!

Что Вы получите в продвинутом курсе ООП в PHP

В данном курсе вы научитесь программировать на PHP в объектно-ориентированном стиле. Данное умение просто необходимо для разработки проектов, в которых участвует более одного человека – то есть на настоящей работе.

В ходе курса вы ознакомитесь с принципами ООП. Узнаете что такое классы и объекты. Далее мы изучим такие понятия как инкапсуляция, наследование и полиморфизм – это три кита, на которых стоит всё ООП.

Кроме того, вы познакомитесь с архитектурным паттерном MVC, который является фундаментальным для построения подавляющего большинства всех веб-приложений.

Разумеется, что это за продвинутый курс, если в нём не будет уроков о работе с базой данных. Здесь вы узнаете, как правильно работать с MySQL, используя технологию ORM и паттерн ActiveRecord.

Ну и конечно, всё это было бы неинтересно и непонятно без хороших примеров. Поэтому в ходе прохождения курса мы с вами самостоятельно напишем мини-фреймворк, на основе которого сделаем настоящий блог!

Отзывы учеников

Сертификат

Преимущества

Проверка домашек

К урокам есть домашние задания, которые я ежедневно проверяю. По факту вы платите не столько за уроки, сколько за мою работу.

Быстрая помощь

Все ученики имеют доступ к общему Telegram-чату, в котором можно задать вопросы и получить ответ в течение 10 минут.

Честная цена

Не, ну Вы видели эти цены на курсы в десятки тысяч рублей?
У меня Вы пройдёте обучение по цене, сравнимой с покупкой книги.

Гарантия

Если Вас что-то не устроит — просто напишите мне любым удобным способом. И я верну Вам деньги в тот же день.

Об авторе курса

Привет! Меня зовут Артём Ивашкевич. Я работаю веб-разработчиком более трёх лет. Сейчас я работаю в компании Зарплата.ру — это крупный проект, над которым трудятся более 50 разработчиков, его ежемесячная посещаемость более 4 млн человек.

В свободное время я обучаю программированию других людей, потому что мне это просто нравится. Если Вам интересно узнать, как я к этому пришёл, прочитайте историю как я стал программистом.

Привет! Меня зовут Артём Ивашкевич. Я работаю веб-разработчиком более двух с половиной лет. Сейчас я работаю в компании Зарплата.ру — это крупный проект, над которым трудятся более 50 разработчиков, его ежемесячная посещаемость более 4 млн человек.

В свободное время я обучаю программированию других людей, потому что мне это просто нравится. Если Вам интересно узнать, как я к этому пришёл, прочитайте историю как я стал программистом.

Программа курса

Уровень 1. Основы ООП

  • 1. Классы и объекты в PHP как основа ООП
  • 2. Инкапсуляция в PHP
  • 3. Наследование в PHP
  • 4. Интерфейсы в PHP
  • 5. Трейты в PHP
  • 6. Полиморфизм в PHP
  • 7. Изучаем абстрактные классы в PHP
  • 8. Статические методы и свойства в PHP
  • 9. Объектно-ориентированный подход в PHP

Уровень 2. Архитектура приложения

  • 10. Неймспейсы и автозагрузка в PHP
  • 11. Архитектура MVC — Model, View, Controller
  • 12. Controller в MVC
  • 13. Фронт-контроллер и роутинг в PHP
  • 14. View в MVC
  • 15. Создаём базу данных для будущего блога
  • 16. Класс для работы с базой данных
  • 17. Делаем вывод статей на сайте из базы данных
  • 18. ORM — Object Relational Mapping
  • 19. Реализуем Active Record в PHP
  • 20. Паттерн Singleton в PHP
  • 21. PHP Reflection API
  • 22. Обновление с помощью Active Record
  • 23. Вставка с помощью Active Record
  • 24. Удаление в Active Record
  • 25. CRUD-операции
  • 26. M в MVC
  • 27. Работа с исключениями в PHP

Уровень 3. Пишем блог на PHP

  • 28. Пишем регистрацию на сайте на PHP
  • 29. Система активации пользователей по email на PHP
  • 30. Пишем систему авторизации на PHP
  • 31. Добавляем статьи в блог на PHP
  • 32. Редактируем статьи в блоге на PHP
  • 33. Задание для самостоятельной работы – доводим блог до ума
  • 34. Пишем свой фреймворк на PHP

Уровень 4. Заключение

Для чего нужен продвинутый курс ООП в PHP

Программирование является довольно сложным делом, освоение которого требует особой внимательности и терпения. Особенно часто при изучении программирования возникает проблема отсутствия направления движения и не совсем четкое понимание конечной цели.

Курс ООП в PHP позволяет обучить лучшим практикам и современным инструментам программирования. Также здесь можно научиться разрабатывать сложный работающий проект. Для осуществления веб-программирования на достойном уровне и понимания процесса разработки сайтов важно также получить необходимое количество актуальной информации по данному вопросу.

Этот продвинутый курс PHP предназначается для людей, которые имеют некоторый опыт полупрофессиональной разработки сайтов. На этих занятиях будет уделяться особое внимание разработке правильной и продуманной архитектуры сайта. Это позволит легко изменить и расширить проект при необходимости.

Для обучения созданию современной архитектуры сайтов невозможно обойтись без объектно-ориентированного программирования или ООП. Вначале у многих разработчиков веб-приложений объектно-ориентированный подход вызывает небольшое недоумение, ведь более привычным для них является процедурный подход. Но курс ООП в PHP поможет быстро справиться с данными трудностями. На занятиях будут рассмотрены теоретические аспекты ООП, после чего пройдет подробное обучение их применению на практике. В течение всего периода курсов последовательно будут изучаться основы ООП, что позволит создавать приложения в объектно-ориентированном стиле.

Пройдя подобный продвинутый курс, можно легко разобраться в довольно сложном объектно-ориентированном программировании. Слушатели познакомятся также с такими понятиями, как классы, объекты и узнают об отличиях между ними. Кроме того, на курсах их познакомят со свойствами, методами и константами класса. Данная обучающая программа позволяет использовать наследование классов для того, чтобы создаваемые веб-приложения были более удобными и подчинялись строгой логике.

Также каждый продвинутый курс создает все условия для получения разветвленных иерархий классов, переопределения методов и расширения их функционала. В результате этого появляется возможность легко создавать абстрактные классы. Обучение на данных курсах является уникальным решением для использования интерфейсов во всех необходимых случаях и более точного понимания их смысла. Также на курсах большое внимание уделяется автозагрузке классов, что исключает образование длинных списков файлов при их подключении. Наш продвинутый курс дает полное представление о функциях автозагрузки и использовании пакетного менеджера Composer для решения подобных задач.

Какие возможности получают ученики после курсов?

Для разработки многих современных сайтов и web приложений полностью или частично используются готовые решения на основе классов, объектов или пакетов. Они соответствуют определённым международным стандартам. При владении основными общими принципами программирования из объектно-ориентированного PHP разработчик может легко и быстро переходить из одной системы в другую. Также важно иметь знания проектирования пакетов и платформ.

Продвинутый курс PHP предназначен для тех, кто имеет знания основного курса и стремится к повышению своего профессионализма в разработке до уровня junior PHP developer. Кроме того, обучение позволит приобрести необходимые навыки работы в команде.

__destruct in __construct?

I’ve encountered with a situation in which I need to call __destruct if a condition is true in __construct !

how to call destructor in constructor?

is there a way for that?

I can do this with a trick, but I need to do it inside my class, the goal is to destruct a class if does not meet my criteria.

EDIT :

In constructor I check for user permissions, If a user who is trying for deleting a post is someone other than admin, then the object of the class should not be instantiated, or in other word should be destructed.

4 Answers 4

Avoid doing actual work in your constructors. Constructors should essentially build an instance of the object. It doesn’t make sense to call __destruct() from the constructor, because the instance is not owned by the method of the class, but by the function that called the new operator.

Ask yourself what should be returned by the new operator at the call site in the case the object can’t be constructed?

What should be assigned to $obj if the object cannot be properly constructed? NULL ? Or perhaps the code doesn’t make sense at all?

You have a few options:

Remove any non-construction code from the constructor, so that the constructor cannot fail at all. Put whatever code that fails in another method. Example:

If a failure in the constructor should be signaled to caller, use a static factory method that tests whether it is valid to instantiate the class, and returns either null or the new instance appropriately.

If the code doesn’t make sense at all if the class cannot be constructed, perhaps you should throw an exception.

PHP 5

В PHP 5 введены конструкторы и деструкторы .

Метод-конструктор вызывается автоматически при каждом создании объекта. И хотя конструктор появился в PHP давно (эту роль выполнял метод, названный именем класса), но в PHP 5 была изменена схема именования конструктора — метод __construct() является теперь конструктором класса.

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

__construct() <
echo «Запущен конструктор»;
>
function __destruct() <
echo «Запущен деструктор»;
>
>
$obj = new MyClass(); // Выводит «Запущен конструктор»
unset($obj); // Выводит «Запущен деструктор»
?>

Если же необходимо вызвать конструктор или деструктор базового класса, то необходимо это делать явно, через указатель parent.

__construct() <
echo «Запущен конструктор базового класса»;
>
function __destruct() <
echo «Запущен деструктор базового класса»;
>
>
class MyClass1 extends MyClass <
function __construct() <
parent::__construct() ;
>
function __destruct() <
parent::__destruct() ;
>
>
$obj = new MyClass1(); // Выводит «Запущен конструктор
// базового класса»
unset($obj); // Выводит «Запущен деструктор базового класса»
?>

Для целей совместимости с предыдущей версией PHP 5 поступает следующем образом: если при создании объекта в классе не найдет конструктор __construct(), то PHP пытается выполнить метод, имя которого совпадает с именем класса . Т.о. конструкторы PHP 4 будут работать с PHP 5 без каких-либо изменений кода.

Дата публикации: 11.07.04
Последнее обновление: —
Просмотров: 80372

Copyright © PHP World — Леонид Лукин, 2004-2008.

Урок — Конструкторы и деструкторы

↑ PHP5, Объектно-ориентированное программирование
Урок — Конструкторы и деструкторы
← Предыдущий урок

Конструктор

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

Замечание: Конструкторы в классах-родителях не вызываются автоматически, если класс-потомок определяет собственный конструктор. Чтобы вызвать конструктор, объявленный в родительском классе, следует обратиться к методу parent::__construct() внутри конструктора класса-потомка.

Пример #1 Использование унифицированных конструкторов

class BaseClass <
function __construct () <
print «Конструктор класса BaseClass\n» ;
>
>

class SubClass extends BaseClass <
function __construct () <
parent :: __construct ();
print «Конструктор класса SubClass\n» ;
>
>

$obj = new BaseClass ();
$obj = new SubClass ();
?>

В целях обратной совместимости, если PHP 5 не может обнаружить объявленный метод __construct(), вызов конструктора произойдет по прежней схеме, через обращение к методу, имя которого соответствует имени класса. Может возникнуть только одна проблема совместимости старого кода, если в нём присутствуют классы с методами __construct(), использующиеся для других целей.

В отличие от других методов, PHP не будет генерировать ошибку уровня E_STRICT , если __construct() будет перекрыт методом с другими параметрами, отличными от тех, которые находятся в родительском __construct().

Начиная с версии PHP 5.3.3, методы с именами, совпадающими с последним элемeнтом имени класса, находящимся в пространстве имен, больше не будут считаться конструкторами. Это изменение не влияет на классы, не находящиеся в пространстве имен.

Пример #2 Конструкторы в классах, находящихся в пространстве имен

Деструкторы

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

Пример #3 Пример использования деструктора

class MyDestructableClass <
function __construct () <
print «Конструктор\n» ;
$this -> name = «MyDestructableClass» ;
>

function __destruct () <
print «Уничтожается » . $this -> name . «\n» ;
>
>

$obj = new MyDestructableClass ();
?>

Как и в случае с конструкторами, деструкторы, объявленные в родительском классе, не будут вызваны автоматически. Для вызова деструктора, объявленном в классе-родителе, следует обратиться к методу parent::__destruct() в теле деструктора-потомка.

Деструктор будет вызван даже в том случае, если скрипт был остановлен с помощью функции exit() . Вызов exit() в деструкторе предотвратит запуск всех последующих функций завершения.

Деструкторы, вызываемые при завершении скрипта, вызываются после отправки HTTP-заголовков. Рабочая директория во время фазы завершения скрипта может отличаться в некоторых SAPI (например, в Apache).

Попытка бросить исключение в деструкторе (вызванного во время завершения скрипта) влечет за собой фатальную ошибку.

Урок 4. Курс по ООП PHP. Методы __construct и __destruct

Новая объектно-ориентированная модель в PHP5

Когда Зив Сераски (Zeev Suraski) добавил объектно-ориентированный (ОО) синтаксис в PHP 3, это можно было рассматривать как «синтаксический подсластитель для поддержки классов» («syntactic sugar for accessing collections»). Объектно-ориентированная модель получила поддержку наследования и позволяла классу (и объекту) объединять методы и свойства, но не более того. Когда Зив и Анди переписали движок для PHP 4, это был полностью новый движок, работающий намного быстрее, намного стабильнее и с еще многими другими возможностями. Однако, изменения практически не затронули ОО модель, первоначально введенную еще в РНР 3.

Хотя объектная модель имела серьезные ограничения, она широко использовалась, часто в очень больших приложениях, написанных на PHP. Это победное шествование парадигмы ООП, даже такой ограниченной в РНР 4, привело к тому, что изменения объектной модели стали центральными в новом релизе РНР — PHP5.

Какие были ограничения в PHP 3 и 4? Самым большим ограничением (которое и приводило ко всем остальным ограничениям) был тот факт, что семантика экземпляра объекта была такой же, что и для родных типов. Как это фактически отражалось на разработчиках? Когда вы присваивали переменную (которая указывает на объект) другой переменной, то создавалась копия объекта. Мало того, что это влияло на производительность, но и это обычно приводило к ошибкам в приложении, потому что многие разработчики думали, что обе переменные будут указывать на тот же самый объект. А они указывали на разные копии того же самого объекта, поэтому, изменяя один объект, мы не меняли другой. Вот пример:

class Person <
var $name ;
function getName () <
return $this -> name ;
>
function setName ( $name ) <
$this -> name = $name ;
>
function Person ( $name ) <
$this -> setName ( $name );
>
>

function changeName ( $person , $name ) <
$person -> setName ( $name );
>

$person = new Person ( «Andi» );
changeName ( $person , «Stig» );
print $person -> getName ();
?>

В РНР 4 этот код выведет «Andi». Причина кроется в том, что мы передаем объект $person в функцию changeName() по значению, а не по ссылке, таким образом, объект $person будет скопирован, и changeName() будет работать уже с копией объекта $person.

Такое поведение не является интуитивно понятным. Действительно, многие разработчики ожидали Java-подобного поведения. В Java, переменные фактически являются указателями на объект, и поэтому при дублировании будет скопирован указатель, а не сам объект.

Было два вида разработчиков: те, кто знал об этой проблеме, и те, кто не знал. Последние, обычно, не сталкивались с этой проблемой, потому что их код был написан так, что было безразлично, существует ли такая проблема или нет. Конечно, некоторые из этих разработчиков проводили бессонные ночи в «увлекательных» поисках «сверхъестественных» ошибок. Первая группа также имела проблему, поскольку приходилось вручную определять передачу объекта по ссылке, запрещая движку копировать объекты, и код был испещрен многочисленными знаками ‘&‘.

Старая объектная модель приводит не только к вышеупомянутым проблемам, но также вскрывает более фундаментальные проблемы, которые на существующей объектной модели не позволяли осуществлять другие возможности.

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

Обратите внимание: явная передача и присваивание по ссылке также поддерживается, на тот случай, если вы хотите изменить содержимое переменной или объекта.

Новый объектно-ориентированный подход в PHP5

Новые возможности объектной модели являются слишком многочисленными. Приведем обзор главных изменений:


    public/private/protected — модификаторы доступа для методов и свойств

Позволяют управлять доступом к методам и свойствам. Теперь видимость свойств и методов может быть определена ключевыми словами: public, private, protected. Модификатор public позволяет обращаться к свойствам и методам отовсюду. Модификатор private позволяет обращаться к свойствам и методам только внутри текущего класса. Модификатор protected позволяет обращаться к свойствам и методам только текущего класса и класса, который наследует свойства и методы текущего класса.

/**
* Define MyClass
*/
class MyClass
<
public $public = ‘Public’ ;
protected $protected = ‘Protected’ ;
private $private = ‘Private’ ;

function printHello ()
<
echo $this -> public ;
echo $this -> protected ;
echo $this -> private ;
>
>

$obj = new MyClass ();
echo $obj -> public ; // Works
echo $obj -> protected ; // Fatal Error
echo $obj -> private ; // Fatal Error
$obj -> printHello (); // Shows Public, Protected and Private

/**
* Define MyClass2
*/
class MyClass2 extends MyClass
<
// We can redeclare the public and protected method, but not private
protected $protected = ‘Protected2’ ;

function printHello ()
<
echo $this -> public ;
echo $this -> protected ;
echo $this -> private ;
>
>

$obj2 = new MyClass2 ();
echo $obj -> public ; // Works
echo $obj2 -> private ; // Undefined
echo $obj2 -> protected ; // Fatal Error
$obj2 -> printHello (); // Shows Public, Protected2, not Private

Унифицированный конструктор __construct()

PHP 5 позволяет объявлять методы-конструкторы. Классы, в которых объявлен метод-констуктор, будут вызывать этот метод при каждом создании нового объекта, так что это может оказаться полезным, чтобы, например, инициализировать какое-либо состояние объекта перед его использованием. Конструктор, ранее совпадавший с названием класса, теперь необходимо объявлять как __construct(), что позволит легче перемещать классы в иерархиях. Конструкторы в классах-родителях не вызываются автоматически. Чтобы вызвать конструктор, объявленный в родительском классе, следует обратиться к методу parent::__construct() .

class BaseClass <
function __construct () <
print «Конструктор класса BaseClass\n» ;
>
>

class SubClass extends BaseClass <
function __construct () <
parent :: __construct ();
print «Конструктор класса SubClass\n» ;
>
>

$obj = new BaseClass ();
$obj = new SubClass ();
?>

Если PHP 5 не может обнаружить объявленный метод __construct() , вызов конструктора произойдет по прежней схеме, через обращение к методу, имя которого соответствует имени класса. Может возникнуть только одна проблема совместимости старого кода, если в нём присутствуют классы с методами __construct() .

Поддержка деструктора для класса, определяемого как метод __destructor()

PHP 5 предоставляет концепцию деструкторов, сходную с теми, что применяются в других ОО языках, таких, как Java: когда освобождается последняя ссылка на объект, перед высвобождением памяти, занимаемой этим объектом, вызывается метод __destruct() , не принимающий параметров.

class MyDestructableClass <
function __construct () <
print «Конструктор\n» ;
$this -> name = «MyDestructableClass» ;
>

function __destruct () <
print «Уничтожается » . $this -> name . «\n» ;
>
>

$obj = new MyDestructableClass ();
?>

Как и в случае с конструкторами, деструкторы, объявленные в родительском классе, не будут вызваны автоматически. Для вызова деструктора, объявленном в классе-родителе, следует обратиться к методу parent::__destruct() .

Топ-пост этого месяца:  Что такое лендинг пейдж
Добавить комментарий