Основы объектно-ориентированного программирования для WordPress-разработчиков

demist

Если вы только начинаете свой путь как разработчик и изучаете 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

Блог про WordPress
Комментарии: 8
  1. Волшебник

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

    1. Дмитрий (автор)

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

      1. Victor

        Но увы… ООП и к вордпрессу подтянулся) Уже много есть плагинов использующих эти принципы, на тот же Woocommerce если взгянуть :)

        1. Дмитрий (автор)

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

  2. Михаил

    Это плагин Debug Bar Console. только для WordPress??

    1. Дмитрий (автор)

      Да, это только под WP.

      1. Victor

        Я думаю тут скорее вопрос совместимости плагинов, которых просто море.

        Если взглянуть на историю вордпресса, который был создан в 2003 году — тогда ООП был очень спорной практикой программирования, А учитывая что в PHP ООП был слабо развит — то тут уже без вариантов. За это время столько кода в вордпрессе перелопатили, что на перевод всего этого в ООП уйдет много времени и конечно-же плагины — которых море…

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

        1. Дмитрий (автор)

          Да, это тоже имеет место. Возможно, что даже основная причина.

Добавить комментарий для Дмитрий Отменить ответ

Получать новые комментарии по электронной почте.