для чего используется конструктор в классах php
Конструктор PHP
Конструкторы — это действительно важная часть объектно-ориентированного программирования на основе классов. С помощью конструкторов вновь созданные объекты автоматически инициализируют свои свойства, прежде чем их можно будет использовать.
Что такое конструктор PHP?
Функции-конструкторы — это особый тип функций (принадлежащие к группе методов, известных как магические методы), которые, в отличие от других функций, вызываются автоматически при создании объекта.
Имена магических методов всегда начинаются с двух подчеркиваний, и магический метод __construct() не является исключением. Объявление функции-конструктора начинается с двух знаков подчеркивания (__) и имени __construct :
Согласно основам PHP ООП конструктор нельзя вызвать более одного раза, но мы можем изменять значения переменных-членов.
Конструктор позволяет нам сразу инициализировать свойства объекта при при его создании.
Пример
Результат выполнения кода:
Почему вышеприведённый сценарий был остановлен и выдал фатальную ошибку?
Пример
Результат выполнения кода:
PHP-конструктор с несколькими парамерами
В конструктор можно передавать сразу несколько параметров:
Пример
Результат выполнения кода:
Как правильно написать метод конструктора?
Когда мы пытаемся создать объект, у которого есть метод-конструктор, мы рискуем сломать наш код, если не передадим значение конструктору. Чтобы избежать этого, мы можем определить значение по умолчанию для свойств, которые мы хотели бы установить через конструктор. Значение по умолчанию может быть наиболее разумным выбором для свойства: ноль, пустая строка или даже null.
Если мы используем null в качестве значения по умолчанию, мы можем использовать условие, чтобы оценить, было ли передано значение, и затем, если значение передано, присвоить значение свойству.
Пример
Результат выполнения кода:
С другой стороны, давайте посмотрим, что произойдет, когда мы определим model после создания объекта. В следующем примере мы присваиваем значение «Merceds» в $model сразу при создании объекта $car1:
Пример
Результат выполнения кода:
Магические константы
В дополнение к магическим методам язык PHP предлагает несколько магических констант.
Например, мы можем использовать магическую константу __CLASS__ (магические константы записываются прописными буквами с префиксом и суффиксом с двумя подчеркиваниями), чтобы получить имя класса, в котором он находится.
Пример
Результат выполнения кода:
Другие магические константы, которые могут пригодиться при разработке приложений:
__LINE__ — получить номер строки, в которой используется константа.
__FILE__ — получить полный путь или имя файла, в котором используется константа.
__METHOD__ — получить имя метода, в котором используется константа.
Заключение
В этом руководстве мы узнали о магических методах и константах, а также о том, как использовать конструкторы для установки значений свойств сразу же как только мы создаем объекты вне классов. Кликните здесь, чтобы попрактиковаться в этой теме.
Конструкторы и деструкторы
Конструктор
PHP 5 позволяет объявлять методы-конструкторы. Классы, в которых объявлен метод-конструктор, будут вызывать этот метод при каждом создании нового объекта, так что это может оказаться полезным, например, для инициализации какого-либо состояния объекта перед его использованием.
Замечание: Конструкторы в классах-родителях не вызываются автоматически, если класс-потомок определяет собственный конструктор. Чтобы вызвать конструктор, объявленный в родительском классе, следует обратиться к методу parent::__construct() внутри конструктора класса-потомка. Если в классе-потомке не определен конструктор, то он может наследоваться от родительского класса как обычный метод (если он не определен как приватный).
Пример #1 Использование унифицированных конструкторов
class BaseClass <
function __construct () <
print «Конструктор класса BaseClass\n» ;
>
>
class SubClass extends BaseClass <
function __construct () <
parent :: __construct ();
print «Конструктор класса SubClass\n» ;
>
>
class OtherSubClass extends BaseClass <
// inherits BaseClass’s constructor
>
// In BaseClass constructor
$obj = new BaseClass ();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass ();
// In BaseClass constructor
$obj = new OtherSubClass ();
?>
В целях обратной совместимости, если PHP 5 не может обнаружить объявленный метод __construct() и этот метод не наследуется от родительских классов, то вызов конструктора произойдет по устаревшей схеме, через обращение к методу, имя которого соответствует имени класса. Может возникнуть только одна проблема совместимости старого кода, если в нём присутствуют классы с методами __construct(), использующиеся для других целей.
Начиная с версии PHP 5.3.3, методы с именами, совпадающими с последним элементом имени класса, находящимся в пространстве имен, больше не будут считаться конструкторами. Это изменение не влияет на классы, не находящиеся в пространстве имен.
Пример #2 Конструкторы в классах, находящихся в пространстве имен
Деструкторы
PHP 5 предоставляет концепцию деструкторов, сходную с теми, что применяются в других ОО языках, таких, как C++. Деструктор будет вызван при освобождении всех ссылок на определенный объект или при завершении скрипта (порядок выполнения деструкторов не гарантируется).
Пример #3 Пример использования деструктора
$obj = new MyDestructableClass ();
?>
Как и в случае с конструкторами, деструкторы, объявленные в родительском классе, не будут вызваны автоматически. Для вызова деструктора, объявленном в классе-родителе, следует обратиться к методу parent::__destruct() в теле деструктора-потомка. Также класс-потомок может унаследовать деструктор из родительского класса, если он не определен в нем.
Деструкторы, вызываемые при завершении скрипта, вызываются после отправки HTTP-заголовков. Рабочая директория во время фазы завершения скрипта может отличаться в некоторых SAPI (например, в Apache).
Попытка бросить исключение в деструкторе (вызванного во время завершения скрипта) влечет за собой фатальную ошибку.
Конструктор PHP
Конструктор класса PHP может содержать столько аргументов или параметров, сколько необходимо. Также можно определить конструктор вообще без параметров.
Важно отметить, что PHP-конструктор вызывается только один раз. И мы не можем вызвать конструктор явно, он вызывается автоматически при создании объекта.
Так как конструктор является магическим методом, он будет иметь отличительную метку магических методов — два подчеркивания в начале. Для определения конструктора мы используем ключевое слово construct :
Пример PHP-конструктора
Теперь мы добавим конструктор в этот класс. Помните, что в ООП PHP конструкторы — это магические методы, следовательно, они начинаются с двух символов подчеркивания и ключевого слова construct :
Создаем объекты этого класса с помощью ключевого слова new :
PHP-конструктор с несколькими аргументами
Мы добавим новую переменную age в класс Human :
Мы создали два объекта, и они содержат начальные значения двух переменных-членов. Следует отметить, что согласно основам PHP ООП конструктор нельзя вызвать более одного раза, но мы можем изменять значения переменных-членов.
Поэтому в классе Human мы создадим два метода, один устанавливает возраст, а второй — имя. Конструктор используется, только чтобы задать начальные значения любой переменной. В дальнейшем, если нужно изменить это значение, мы будем использовать эти функции.
Тот же класс с двумя дополнительными методами:
Мы можем вызывать два новых метода, чтобы изменить имя или возраст. Добавим в пример еще два метода, чтобы вывести имя и возраст:
Полный пример использования конструктора класса PHP ООП с четырьмя функциями:
Еще один пример PHP-конструктора
Давайте посмотрим, как используется конструктор. Сначала создаем простой класс с одним свойством и одной функцией:
Это простой класс, который содержит одну переменную данных, название машины, и метод вывода этого названия.
Теперь добавим конструктор, который будет задавать значение name в момент создания объекта. В ООП PHP код конструктора будет выглядеть следующим образом:
Теперь создаем из класса объект:
Выводим значение данных переменной через вызов метода get_carname() :
Результат будет следующим:
Это простой пример создания конструктора с инициализацией значения членов объекта. Это значение не фиксированное. Мы можем изменить его при необходимости. Тем не менее, это отличный способ инициализации объектов.
В примере после добавления этого кода инициализируются экземпляры класса, чтобы создать объекты. Тот же функционал достигается с помощью конструктора:
Теперь объекты созданы и инициализированы с названиями и ценами на момент создания объекта, это достигается с помощью конструктора.
Этот PHP-код дает следующий результат:
Up to date astrology
Up to date PHP
Up to date DB
25
36
17
Мы видим, что полученный результат тот же самый, но он достигнут с помощью конструктора.
ООП PHP пример базы данных, в котором используется конструктор класса PHP :
Объектно-ориентированный PHP: подробнее о методах и полях класса
Добро пожаловать во второй урок из серии, посвященной ООП. В первой статье вы ознакомились с основами ООП в PHP, включая понятия классов, методов, полей и объектов. Также вы узнали, как создать простенький класс и реализовать его.
В данной статье вы узнаете еще больше о методах и полях класса. Это даст вам хорошую основу, для того чтобы приступить к изучению более профессиональных техник, таких как наследование.
Вот список того, о чем я расскажу вам в этой статье:
Вы готовы? Тогда вперед!
Конструкторы и деструкторы
Иногда возникает необходимость выполнять какие-то действия одновременно с созданием объекта. Например, вам может понадобиться задать значения полям объекта сразу по его созданию, или же инициализировать их значениями из базы данных.
Подобно этому, вам также может понадобиться выполнять определенные действия по удалению объекта из памяти, например, удаление объектов, зависящих от удаляемого, закрытие соединения с базой данных или файлов.
В PHP есть два специальных метода, которые можно применять для совершения определенных действий по созданию и удалению объектов:
Работа с конструкторами
Применяйте конструкторы, чтобы задать действия, которые будут выполняться по созданию объекта класса. Эти действия могут включать инициализацию полей класса, открытие файлов, чтение данных.
Вот пример конструктора:
Данный скрипт отобразит на странице следующее:
Затем в коде создается объект класса Member, в который мы передаем 3 значения «fred», «Chicago», и «http://example.com/», так как конструктор принимает именно 3 параметра. Конструктор записывает эти значения в поля созданного объекта. В завершение, вызывается метод showProfile() для созданного объекта, чтобы отобразить полученные значения.
Работа с деструкторами
Применяйте деструктор, когда объект удаляется из памяти. Вам может понадобиться сохранить объект в базе данных, закрыть открытые файлы, которые взаимодействовали с объектом. Чтобы создать деструктор, добавьте в класс метод __destruct(). Он вызовется как раз перед удалением объекта автоматически. Вот простой пример:
На заметку: в отличие от конструкторов, в деструкторы нельзя передавать никакие параметры.
Деструктор также вызывается при выходе из скрипта, так как все объекты и переменные при выходе из метода удаляются. Так, следующий код также вызовет деструктор:
Также, если работа скрипта прекратится из-за возникшей ошибки, деструктор тоже вызовется.
На заметку: при создании объектов класса-наследника, конструкторы класса-родителя не вызываются автоматически. Вызывается только конструктор самого наследника. Тем не менее вы можете вызвать конструктор родителя из класса-наследника таким образом:
parent::__construct(). То же самое касается деструкторов. Вызвать деструктор родителя можно так: parent:__destruct(). Я расскажу вам о классах-родителях и наследниках в следующем уроке, посвященном наследованию.
Статические поля класса
Мы рассмотрели статические переменные в статье PHP Variable Scope: All You Need to Know. Как обычная локальная переменная, статическая переменная доступна только в пределах функции. Тем не менее, в отличие от обычных локальных, статические переменные сохраняют значения между вызовами функции.
Статические поля класса работают по такому же принципу. Статическое поле класса связано со своим классом, однако оно сохраняет свое значение на протяжении всей работы скрипта. Сравните это с обычными полями: они связаны с определенным объектом, и они теряются при удалении этого объекта.
Статические поля полезны в случаях, когда вам нужно хранить определенное значение, относящееся ко всему классу, а не к отдельному объекту. Они похожи на глобальные переменные класса.
Чтобы создать статическую переменную, добавьте ключевое слово static в ее задании:
Вот пример того, как работают статические переменные:
Есть несколько интересных вещей, так что давайте разберем данный скрипт:
Статические методы
Наряду со статическими полями класса, вы также можете создавать статические методы. Статические методы, так же как и поля, связаны с классом, но нет необходимости создавать объект класса, чтобы вызвать статический метод. Это делает такие методы полезными в случае, если вам нужен класс, который не оперирует реальными объектами.
Чтобы создать статический метод, нужно добавить в его объявлении ключевое слово static:
Константы класса
Константы позволяют задать глобальное значение для всего вашего кода. Это значение фиксированное, оно не может быть изменено. Константы класса схожи с обычными константами. Основное их отличие заключается в том, что помимо того, что классовая константа глобальна, к ней можно получить доступ из класса, в котором она определена. Классовые константы полезны в случаях, когда вам нужно хранить определенные значения, которые относятся к определенному классу.
Определить классовую константу можно с помощью ключевого слова const. Например:
На заметку: как и в случае со статическими полями и методами, вы можете обратиться к константе через ключевое слово self.
Давайте рассмотрим классовые константы на примере. Добавим в класс Member константы, в которых будут храниться значения их роли (участник, модератор или администратор). Применив константы вместо обычных численных значений, мы сделали код более читабельным. Вот скрипт:
Скрипт создает несколько объектов с разными ролями. Для задания объектам ролей используются именно классовые константы, а не простые численные значения. Затем идут вызовы методов getUsername() и getLevel() для каждого объекта, и результаты отображаются на странице.
Явное указание типов аргументов функций
В PHP можно не задавать типы данных, так что можно не переживать о том, какие аргументы вы передаете в методы. Например, вы можете спокойно передать в функцию strlen(), считающую длину строки, численное значение. PHP сперва переведет число в строку, а затем вернет ее длину:
Иногда явное указание типа полезно, но оно может привести к багам, с которыми трудно будет справиться, особенно в случае, если вы работаете с такими сложными типами данных, как объекты.
Например
Посмотрите на этот код:
Данный скрипт работает так:
Это все очень хорошо, но.
Давайте сделаем лучше!
Добавим этот фрагмент кода в конце:
Теперь попытаемся вызвать метод getUsername() класса Topic. Этот метод обращается к методу getUsername() класса Widget. И так как в этом классе нет такого метода, мы получаем ошибку:
Проблема в том, что причина ошибки не так легко уяснима. Почему объект Topic ищет метод в классе Widget, а не Member? В сложной иерархии классов будет очень сложно найти выход из такого рода ситуации.
Даем подсказку
Было бы лучше ограничить конструктор класса Topic на прием аргументов так, чтобы он мог принимать в качестве первого параметра объекты только класса Member, тем самым предостеречься от фатальных ошибок.
Это как раз то, чем занимается явное указание типов. Чтобы явно указать тип параметра, вставьте имя класса перед названием аргумента в объявлении метода:
Давайте подкорректируем конструктор класса Topic так, чтобы он принимал только Member:
Теперь снова попытаемся создать объект Topic, передав ему Widget:
На этот раз PHP отобразит конкретную ошибку:
Инициализация и чтение значений полей класса при помощи __get() и __set()
Как вы уже знаете, классы обычно содержат поля:
Чтобы создать такие “виртуальные” поля, нужно добавить в класс парочку волшебных методов:
“Невидимый” в данном контексте значит, что на данном участке кода нельзя прямо получить доступ к данным полям. Например, если такого поля вообще нет в классе, или если оно существует, но оно частное, и за пределами класса нет доступа к такому полю.
Вот, как это работает:
Перегрузка методов с помощью __call()
Геттеры и сеттеры используются для запрета на доступ к частным переменным. В этом же направлении используется метод __call() для запрета доступа к частным методам. Как только из кода вызывается метод класса, который либо не существует, либо он недоступен, автоматически вызывается метод __call(). Вот общий синтаксис метода:
Метод __call() полезен в ситуациях, когда вам нужно передать некую функциональность класса другому классу. Вот простой пример:
На заметку: в PHP есть и другие методы, касающиеся перегрузки, например, __isset(), __unset(), и __callStatic().
Заключение
В этом уроке вы углубили свои знания по ООП в PHP, рассмотрев более детально поля и методы. Вы изучили:
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.elated.com/articles/object-oriented-php-delving-deeper-into-properties-and-methods/
Перевел: Станислав Протасевич
Урок создан: 27 Июня 2011
Просмотров: 107184
Правила перепечатки
5 последних уроков рубрики «PHP»
Фильтрация данных с помощью zend-filter
Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.
Контекстное экранирование с помощью zend-escaper
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
Подключение Zend модулей к Expressive
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
Совет: отправка информации в Google Analytics через API
Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.
Для чего используется конструктор в классах php
PHP позволяет объявлять методы-конструкторы. Классы, в которых объявлен метод-конструктор, будут вызывать этот метод при каждом создании нового объекта, так что это может оказаться полезным, например, для инициализации какого-либо состояния объекта перед его использованием.
Замечание: Конструкторы, определённые в классах-родителях, не вызываются автоматически, если дочерний класс определяет собственный конструктор. Чтобы вызвать конструктор, объявленный в родительском классе, требуется вызвать parent::__construct() внутри конструктора дочернего класса. Если в дочернем классе не определён конструктор, то он может быть унаследован от родительского класса как обычный метод (если он не был определён как приватный).
Пример #1 Конструкторы при наследовании
class BaseClass <
function __construct () <
print «Конструктор класса BaseClass\n» ;
>
>
class SubClass extends BaseClass <
function __construct () <
parent :: __construct ();
print «Конструктор класса SubClass\n» ;
>
>
class OtherSubClass extends BaseClass <
// наследует конструктор BaseClass
>
// Конструктор класса BaseClass
$obj = new BaseClass ();
// Конструктор класса BaseClass
// Конструктор класса SubClass
$obj = new SubClass ();
// Конструктор класса BaseClass
$obj = new OtherSubClass ();
?>
В отличие от других методов, __construct() освобождается от обычных правил совместимости сигнатуры при наследовании.
Пример #2 Использование аргументов в конструкторах
Если у класса нет конструктора, или его конструктор не имеет обязательных параметров, скобки после имени класса можно не писать.
Конструкторы в старом стиле
Для классов, находящихся в собственном пространстве имён и для всех классов, начиная с PHP 8.0.0, метод, названный по имени класса, будет игнорироваться.
В новом коде всегда используйте __construct().
Определение свойств объекта в конструкторе
Начиная с PHP 8.0.0, параметры конструктора можно использовать для задания соответствующих свойств объекта. Это довольно распространённая практика — присваивать свойствам объекта параметры, переданные в конструктор, не производя никаких дополнительных преобразований. Определение свойств класса в конструкторе позволяет значительно сократить количество шаблонного кода для такого случая. Пример выше можно будет переписать следующим образом:
Пример #3 Использование определения свойств в конструкторе
Если декларация аргумента конструктора включает модификатор видимости, PHP интерпретирует его одновременно и как аргумент конструктора, и как свойство объекта и автоматически присвоит свойству значение, переданное в конструктор. При этом, если не предполагается какой-либо дополнительной логики, тело конструктора можно оставить пустым. Код конструктора выполнится после того, как все аргументы присвоятся всем соответствующим свойствам.
Не все передаваемые в конструктор аргументы должны быть свойствами объекта. В конструкторе можно задавать как обычные, так и являющиеся свойствами объекта аргументы в любом порядке. Аргументы-свойства никак не влияют на код, исполняемый в конструкторе.
Атрибуты, заданные для таких аргументов, будут применены как для них самих, так и для соответствующих свойств.
Статические методы создания объекта
Пример #4 Использование статических методов для создания объектов
Конструктор можно сделать скрытым или защищённым для предотвращения его прямого вызова. В таком случае объект класса можно будет создать только с помощью статических методов. Так как это методы того же класса, они имеют доступ ко всем его скрытым методам, даже если они относятся к разным экземплярам класса. Скрытый конструктор опционален и может присутствовать или отсутствовать по необходимости.
В примере выше три публичных статических метода демонстрируют различные способы создания экземпляра объекта.
Деструкторы
PHP предоставляет концепцию деструктора, аналогичную с той, которая применяется в других ОО-языках, таких как C++. Деструктор будет вызван при освобождении всех ссылок на определённый объект или при завершении скрипта (порядок выполнения деструкторов не гарантируется).
Пример #5 Пример использования деструктора
class MyDestructableClass
<
function __construct () <
print «Конструктор\n» ;
>
$obj = new MyDestructableClass ();
Как и в случае с конструкторами, деструкторы, объявленные в родительском классе, не будут вызываться автоматически. Для вызова деструктора родительского класса, требуется вызвать parent::__destruct() в теле деструктора дочернего класса. Подобно конструкторам, дочерний класс может унаследовать деструктор из родительского класса, если он не определён в нем.
Деструкторы, вызываемые при завершении скрипта, вызываются после отправки HTTP-заголовков. Рабочая директория во время фазы завершения скрипта может отличаться в некоторых SAPI (например, в Apache).
Попытка выбросить исключение из деструктора (вызываемого во время завершения скрипта) вызывает фатальную ошибку.
User Contributed Notes 12 notes
Consider the following example:
// create two Foo objects:
$foo = new Foo ( ‘Foo 1’ );
$bar = new Foo ( ‘Foo 2’ );
// destroy the global references to them
$foo = null ;
$bar = null ;
// we now have no way to access Foo 1 or Foo 2, so they OUGHT to be __destruct()ed
// but they are not, so we get a memory leak as they are still in memory.
//
// Uncomment the next line to see the difference when explicitly calling the GC:
// gc_collect_cycles();
//
// see also: http://www.php.net/manual/en/features.gc.php
//
// destroy the global references to them
$foo = null ;
$bar = null ;
// we now have no way to access Foo 3 or Foo 4 and as there are no more references
// to them anywhere, their __destruct() methods are automatically called here,
// BEFORE the next line is executed:
Destroying: Foo 3
Destroying: Foo 4
End of script
Destroying: Foo 1
Destroying: Foo 2
But if we uncomment the gc_collect_cycles(); function call in the middle of the script, we get:
Destroying: Foo 2
Destroying: Foo 1
Destroying: Foo 3
Destroying: Foo 4
End of script
NOTE: calling gc_collect_cycles() does have a speed overhead, so only use it if you feel you need to.