7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Code
  2. Back-End

Объектно ориентированный PHP для начинающих

Scroll to top
Read Time: 26 mins

Russian (Pусский) translation by Sergey Zhuk (you can also view the original English article)

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

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

Объектно-ориентированное программирование - это стиль кодирования, который позволяет разработчикам группировать схожие задачи в классы. Это помогает сохранить код в соответствии с принципом «не повторяйся» (DRY) и простым в обслуживании.

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

Одним из основных преимуществ программирования по принципу DRY является то, что если в вашей программе изменяется часть информации, обычно требуется только одно изменение для обновления кода. Одним из самых больших кошмаров для разработчиков является поддержание кода, в котором данные объявляются снова и снова, а это означает, что любые изменения в программе становятся похожими на бесконечную игру Where's Waldo

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

Понимание объекты и классы

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

Узнаем различия между объектами и классами

Фотографии от Instant Jefferson и John Wardell

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

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

Класс, например, это как проект для дома. Он определяет форму дома на бумаге, при этом отношения между различными частями дома так же четко определены и спланированы, хотя дома еще не существует.

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

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

Структурирование классов

Синтаксис для создания класса довольно прост: объявить класс с помощью ключевого слова class, за которым следует имя класса и набор фигурных скобок ({}):

После создания класса новый экземпляр может быть создан и сохранен в переменной с использованием ключевого слова new:

Чтобы увидеть содержимое класса, используйте var_dump ():

Попробуйте выполнить этот процесс, разместив весь предыдущий код в новом файле test.php в [локальной] папке для тестирования:

Загрузите страницу в браузере по адресу http: //localhost/test.php, и на экране должно появиться следующее:

В своей простейшей форме вы только что завершили свой первый ООП-скрипт.

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

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

Чтобы добавить свойство в MyClass, добавьте следующий код в свой скрипт:

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

Чтобы прочитать это свойство и вывести его в браузер, укажите объект, с которого следует читать, и свойство, которое нужно прочитать:

Поскольку могут существовать несколько экземпляров класса, если отдельный объект не ссылается, то сценарий не сможет определить, с какого объекта следует читать свойство. Использование стрелки (->) является конструкцией ООП, которая обращается к содержащимся в нем свойствам и методам данного объекта.

Измените скрипт в test.php, чтобы считать свойство, вместо того, чтобы выводить весь класс, изменив код, как показано ниже:

Теперь перезагрузка вашего браузера выводит следующее:

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

Методы являются специфичными для класса функциями. Отдельные действия, которые объект сможет выполнить, определены внутри класса как методы.

Например, чтобы создать методы, которые будут устанавливать и получать значение свойства класса $prop1, добавьте в свой код следующее:

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

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

Перезагрузите браузер, и вы увидите следующее:

"Сила ООП становится очевидной при использовании нескольких экземпляров
одного класса."

Когда вы загружаете результаты в свой браузер, они отобразят следующее:

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

Волшебные методы в ООП

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

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

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

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

Примечание. __CLASS__ возвращает имя класса, в котором оно вызывается; Это то, что известно как волшебная константа. Существует несколько доступных магических констант, о которых вы можете прочитать в руководстве по PHP.

Перезагрузка файла в вашем браузере приведет к следующему результату:

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

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

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

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

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

Теперь при загрузке в вашем браузере результат будет выглядеть следующим образом:

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

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

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

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

Чтобы избежать этой ошибки, добавим метод __toString():

В этом случае попытка преобразовать объект в строку приведет к вызову метода getProperty(). Загрузите тестовый скрипт в свой браузер, чтобы увидеть результат:

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

Использование наследования

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

После перезагрузки тестового файла в вашем браузере выводится следующее:

Перезапись унаследованных свойств и методов

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

Это изменяет вывод в браузере на:

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

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

Это выведет результат как родительского конструктора, так и конструктора нового класса:

Указание видимости свойств и методов

Для дополнительного контроля над объектами методам и свойствам можно указать видимость. Это определяет, как и откуда можно получить доступ к свойствам и методам. Существует три ключевых слова: public, protected и private. В дополнение к своей видимости метод или свойство могут быть объявлены static, что позволяет им получать доступ без экземпляра класса.

«Для дополнительного контроля над объектами методам и свойствам указывается их видимость."

Примечание. Видимость - новая функция в PHP, начиная с версии 5. Информацию о совместимости ООП с PHP 4 смотрите на странице руководства PHP.

Публичные свойства и методы

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

Защищенные свойства и методы

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

Объявите метод getProperty() как защищенный в MyClass и попытайтесь получить к нему доступ непосредственно извне класса:

При попытке запустить этот сценарий появляется следующая ошибка:

Теперь создайте новый метод в MyOtherClass для вызова метода getProperty():

Это приведет к желаемому результату:

Приватные свойства и методы

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

Чтобы продемонстрировать это, объявите getProperty() как private в MyClass и попытайтесь вызвать callProtected() из
MyOtherClass:

Перезагрузите браузер, и появится следующая ошибка:

Статические свойства и методы

Доступ к методу или свойству, объявленному static, возможен без создания экземпляра класса; Вы просто указываете имя класса, оператор разрешения области и имя свойства или метода.

«Одним из основных преимуществ использования статических свойств является то, что они сохраняют свои значения в течение всего срока действия скрипта».

Чтобы продемонстрировать это, добавьте статическое свойство $count и статический метод с именем plusOne() в MyClass. Затем установите цикл do ... while для вывода приращенного значения $count, пока значение меньше 10:

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

Когда вы загружаете этот скрипт в своем браузере, выдается следующее:

Комментирование с помощью DocBlocks

Стиль комментирования DocBlock является широко распространенным
методом документирования классов".

Хотя это не официальная часть ООП, стиль комментирования DocBlock является широко распространенным методом документирования классов. Помимо предоставления стандарта для
разработчиков, используемым при написании кода, он также был принят многими из самых популярных наборов разработчика программного обеспечения (SDK), таких как Eclipse и NetBeans, и будет использоваться ими для генерации подсказок кода.

DocBlock определяется с помощью комментария блока, который начинается с дополнительной звездочки:

Реальная сила DocBlocks проявляется с возможностью использовать теги, которые начинаются с символа at (@), за которым сразу следует имя тега и значение тега. Теги DocBlock позволяют разработчикам определять авторов файла, лицензию на класс, информацию о свойствах или методах и другую полезную информацию.

Наиболее часто используемые теги:

  • @author: автор текущего элемента (который может быть классом, файлом, методом или любым битом кода) указан в этом теге. Несколько тегов автора могут использоваться в одном и том же DocBlock, если нужно указать несколько авторов. Формат имени автора - John Doe john.doe@email.com.
  • @copyright: это означает год и имя хозяина авторских прав для текущего элемента. Формат такой: 2010 Copyright Holder.
  • @license: Ссылка на лицензию для текущего элемента. Формат информации о лицензии:
    http://www.example.com/path/to/license.txt License Name.
  • @var: содержит тип и описание свойства переменной или класса. Формат: type element description.
  • @param: Этот тег показывает тип и описание параметра функции или метода. Формат: type $element_name element description.
  • @return: тип и описание возвращаемого значения функции или метода приведены в этом теге. Формат type return element description.

Пример класса, прокомментированного с помощью DocBlocks, может выглядеть так:

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

Сравнение объектно-ориентированного и процедурного кода

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

Причина 1: Простота внедрения

«Хотя вначале это может быть непростой задачей, ООП действительно обеспечивает более простой подход к работе с данными».

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

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

Процедурный подход

Вот процедурный подход к нашему примеру:

При выполнении код выводит следующее:

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

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

Вот как раз где ООП приходит и помогает нам очистить код.

ООП подход

Вот подход ООП к нашему примеру:

В браузере выводится следующее:

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

«ООП подход значительно сократит вашу рабочую нагрузку, если он будет реализован должным образом».

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

Совет. Не все должно быть объектно-ориентированным. Быстрая функция, которая обрабатывает что-то маленькое в одном месте внутри приложения, необязательно должна быть обернута в класc. Используйте свои умения и знания при выборе между объектно-ориентированным и процедурным подходами.

Причина 2: лучшая организация

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

Предположим, у вас есть приложение с 150 классами, которые динамически вызываются файлом контроллера в корневой области файловой системы приложения. Все 150 классов следуют классу соглашений об именах class.classname.inc.php и находятся в папке inc вашего приложения.

Контроллер может реализовать функцию PHP __autoload() для динамического подтягивания только тех классов, которые ему нужны, как они вызываются, вместо того, чтобы включать все 150 в файл контроллера на всякий случай или придумать какой-нибудь умный способ включения файлов в свой собственный код :

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

Причина 3: Простота в обслуживании

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

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

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

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

Резюме

Теперь вы уже должны чувствовать себя комфортно в стиле объектно-ориентированного программирования. Изучение ООП - отличный способ перенести свое программирование на следующий уровень. При правильном внедрении ООП поможет вам создать легко читаемый и простой в обслуживании переносимый код, который сэкономит вам (и разработчикам, работающим с вами) часы дополнительной работы. Вы зациклились на чем-то, что не было рассмотрено в этой статье? Вы уже используете ООП и имеете несколько советов для новичков? Поделитесь ими в комментариях!

Примечание автора. Эта статья была отрывком из книги Pro PHP и jQuery (Apress, 2010).

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.