Основы объектно-ориентированного программирования для WordPress-разработчиков
Если вы только начинаете свой путь как разработчик и изучаете PHP через WordPress, идея объектно-ориентированного программирования (ООП) вас может отпугнуть, но в действительности вы, скорее всего, уже сталкивались с таким подходом.
К примеру, вы, наверно, уже получали ID текущей записи:
global $post; $id = $post->ID;
Это и есть объектно-ориентированное программирование. Вы могли не знать терминологию, но то, что вы делали в первой строке – это получали текущий пост как объект стандартного класса. Во второй строке вы получаете значение свойства ID этого класса.
Еще один пример того, где вы могли видеть объектно-ориентированное программирование PHP в действии – это использование WP_Query.
Вот популярный пример использования WP_Query:
$args = array( 'post_type' => 'clothing', 'tag' => 'hat' ); $query = new WP_Query( $args ); if ( $query->have_posts() ) { echo '<ul>'; while ( $query->have_posts() ) { $query->the_post(); echo '<li>' . get_the_title() . '</li>'; } echo '</ul>'; }
Это является достаточно сложным примером использования ООП. Я вернусь к нему после того, как объясню вам несколько аспектов работы ООП.
Перед тем, как начать
В процессе чтения данной статьи очень важно, чтобы вы пробовали на практике разные примеры. Вы всегда можете это сделать в шаблонах темы на тестовом сайте, однако гораздо легче и быстрее использовать для этого консоль отладки, которую можно установить с помощью плагина Debug Bar.
Если вы пока еще не использовали Debug Bar, вы обязательно должны это сделать. Это действительно важный инструмент разработки, который может быть установлен либо отдельно, либо в виде набора плагинов Developer. Debug Bar предлагает массу полезных инструментов, а также несколько дополнений.
Мне нравится Debug Bar Console. Я знаю, что этот плагин давно не обновлялся на WordPress.org, однако поверьте мне, он прекрасно работает со всеми версиями WordPress (включая 4.0).
Debug Bar Console – отличное место для тестирования PHP и MySQL в контексте конфигурации вашего сайта. Если вы еще не установили его, сделайте это – и вы поблагодарите меня за это позже.
Методы vs функции
В функциональном программировании мы привыкли работать с функциями – которые всегда доступны после своего объявления. В ООП функции внутри класса называются методами. Методы доступны только в контексте данного класса.
При использовании не-объектного PHP в темах или плагинах вы вызываете функцию напрямую и добавляете к именам функций префикс в виде уникального слага, чтобы избежать конфликтов с другими плагинами или темами.
Следует иметь в виду, что вы должны задавать префикс и для имен классов, чтобы избежать конфликтов с плагинами и темами. При использовании ООП, методы – или функции внутри классов – не нуждаются в префиксах, поскольку они являются уникальными для данного класса. Однако вы все равно обращаетесь к ним через класс. Чтобы понять это, давайте создадим два класса. Оба будут иметь один и тот же метод – class_name, – который будет выводить имя класса. Ниже приведены два класса, hat и shoe:
class hat { function class_name() { return "hat"; } } class shoe { function class_name() { return "shoe"; } }
Как вы можете видеть, в каждом классе есть метод, названный class_name, который возвращает строку. Эти два методы имеют одно и то же имя. Это не приведет к проблемам, поскольку они находятся в двух разных классах. Чтобы использовать их, мы должны сначала создать экземпляры каждого класса и поместить их в переменную. Мы сделаем это путем задания переменной, равной новому экземпляру класса:
$hat = new hat(); $shoe = new shoe();
Чтобы протестировать это, выведем метод class_name каждого класса:
echo $hat->class_name(); echo $shoe->class_name();
Поиграйтесь в консоли с этими двумя классами. Попробуйте добавлять разные методы к классам. Учтите, что методы всегда должны быть доступными в контексте класса. Если вы хотите получить доступ к методу класса внутри другого метода этого класса, вы должны использовать переменную $this, которую можно расшифровать как «в этом классе».
Вот простой пример класса с двумя методами.
class clothing_post_types { function get_post ( $id ) { $post = get_post( $id ); //check if $post is an object of the stdClass if ( is_object( $post) && is_a( 'stdClass' ) ) { return $post; } } function check_post_type( $id ) { //get post object $post = $this->get_post( $id ); //check that $this->get_post didn't return false (ie invalid post ID was used) if ( $post ) { //get post type $post_type = $post->post_type(); if ( in_array( $post_type ), array( 'hat', 'shoe', 'shirt' ) ) { return true; } } } }
Один получает объект записи и проверяет правильность этого объекта. Второй проверяет, является ли этот объект одним из нескольких типов записей.
Свойства vs переменные
Одно из самых значимых ограничений процедурного программирования (противоположность ООП – без использования классов) – сложность совместного использования переменных в разных функциях. Все это привело к появлению глобальных переменных, которые являются излишеством.
Внутри класса мы всегда можем использовать заданные переменные. Такие переменные класса называются свойствами.
Помните, как в самом начале статьи мы рассматривать глобальный объект записи? В том примере мы работали со свойствами класса. Давайте посмотрим еще раз на объект записи в консоли:
$post = get_post( 1 ); print_r( $post );
Вы должны увидеть объект записи для стандартной записи «Hello World», которая имеется в любом новом WordPress-сайте. Вы увидите, что наряду со свойством ID, которое мы использовали раньше, имеются также свойства для контента записи, типа записи и т.д. Вы можете получить доступ к свойствам следующим образом:
$post->ID;
Использование хуков в классах
Вне класса мы будем придерживаться следующего паттерна для подцепления функции к действию или фильтру WordPress:
add_action( 'hook', 'callback' ); function callback() { //do something }
При сцеплении метода класса с фильтром WordPress или массивом, вы должны задать контекст для функции обратного вызова. Делается это при помощи массива, содержащего экземпляр класса и имя метода. Делается это обычно при помощи «волшебного» метода __construct().
Да, все верно, в ООП имеется ряд волшебных методов. Метод __construct() вызывается всякий раз, когда создается экземпляр класса. Мы можем использовать add_action и add_filter для подцепления методов класса к хукам WordPress. Поскольку все это находится в классе, мы можем использовать переменную $this в качестве объекта класса.
Давайте взглянем на типичный пример использования _construct() в классе:
class add_elements { function __construct() { add_action( 'wp_footer', array( $this, 'inline_script' ) ); add_filter( 'the_content', array( $this, 'end_of_post_message' ) ); } function inline_script() { echo " //add javascript here "; } function end_of_post_method( $content ) { $message = _('Text to output at end of every post'); $content = $content.$message; return $content; } }
Дополнительная работа с __construct()
Как я уже говорил в предыдущем разделе, __construct() выполняется тогда, когда создается экземпляр класса. Это означает, что если вы хотите, чтобы класс выполнял свои методы в определенном порядке, и передавал данные между ними, основываясь на результате работы этих методов, вы можете установить все это в __construct(). Этот метод очень полезен, если вы используете класс для запуска серии функций, которые используют данные друг друга.
Естественно, вы можете передавать некоторые данные в класс, когда вы создаете его экземпляр, так, чтобы объект, создаваемый вами, был основан на определенных данных. Фактически именно это и происходит, когда вы создаете новый объект WP_Query, что было показано в самом начале статьи.
Если вы посмотрите на метод __construct() в WP_Query, вы увидите следующее: первое, что делает класс – это проверяет, что массив аргументов не пуст, после чего передает его другому методу класса. Все это запускает ряд событий, которые задают свойства класса и которые позволяют вам использовать методы класса для доступа к записям на основе заданных вами аргументов.
Основы заложены
Теперь вы знаете, что представляет собой ООП в WordPress. Хотя следует отметить, что мы обратились к самым основам объектно-ориентированного программирования. Будем надеяться, что эта статья послужит для вас стартовой площадкой для дальнейшего изучения ООП в WordPress.
Источник: http://torquemag.io