Стандарты написания кода в WordPress

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

1. Имена

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

Теперь более конкретно.

1.1 Классы

Названия классов в WordPress должны следовать следующим правилами:

  • Слова разделяться знаком нижнего подчеркивания _.
  • Каждое слово в классе должно начинаться с большой буквы.
  • Сокращения (WC = WooCommerce, WP = WordPress) должны быть только из больших букв.

Несложно же? Примеры: WC_Order, WC_Truemisha_Gateway, WP_Object_Cache, My_Class.

1.2 Функции и переменные

Только маленькие буквы, слова разделены знаком подчеркивания _.

Например: function add_your_shipping_method() или $default_image_sizes.

1.3 Файлы

При создании файлов для, скажем, своей темы или плагина, не забывайте, что:

  • Названия файлов должны быть написаны только маленькими буквами.
  • Слова разделяем знаком дефиса -.
  • Если мы создаём файл для класса, то тут нужно использовать имя класса и в начале добавлять префикс class-, примеры: WC_Order должен быть class-wc-order.php, WC_Truemisha_Gateway должен быть class-wc-truemisha-gateway.php.

1.4 Аргументы функций

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

Плохой пример:

// какой-то класс управления файлом
class Local_File_Manager {
 
	public function manage_file( $filename, true ) {
 
		if ( true ) {
			// открываем файл
		} else {
			// удаляем файл
		}
 
	}
 
}
 
// не особо понятно, верно ведь?
$file_manager = new Local_File_Manager();
$file_manager->manage_file( 'foo.txt', true );

Хороший пример:

class Local_File_Manager {
 
	public function open_file( $filename ) {
		// открываем файл
	}
 
	public function delete_file( $filename ) {
		// удаляем файл
	}
 
}
 
// а вот так уже понятней!
$file_manager = new Local_File_Manager();
$file_manager->open_file( 'foo.txt' );
$file_manager->delete_file( 'foo.txt' );

2. Одинарные и двойные кавычки

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

Я предпочитаю отдавать предпочтение одинарным кавычкам, например:

echo '<a href="' . site_url() . '">Главная</a>'; // а не "<a href='" . site_url() . "'> ...

Даже когда нужно передавать переменные в строку:

echo '<a href="' . site_url() . '" title="' . esc_attr( $title ) . '">Ссылка</a>';

Потому что:

  • Как вы можете заметить, при передаче переменных нам всё равно во многих ситуациях нужно их очищать функциями типо esc_attr(), esc_html() и т.д.
  • К тому же во всех строках с двойными кавычками PHP проводит доп. действия, т.к. сразу обрабатывает в них переменные.

3. Отступы

А вот это боль! 😾

3.1 Табы, а не пробелы!

Прежде всего, забудьте про отступы пробелами!

if( условие ) {
	echo 'hello'; // перед echo стоит таб
}

Когда вы копируете код с некоторых сайтов, или же работаете с чужим кодом, там часто можно встретить пробелы и это так раздражает! В таких ситуациях в своём редакторе кода я выделяю весь код со стрёмными отступами и использую комбинацию Shift + Tab.

Использование комбинации клавиш Shift + Tab в вашем редакторе кода
Тут было всё вперемешку с табами и пробелами, сначала я удалил всё комбинацией Shift + Tab, а потом нормально расставил отступы через Tab.

Исключение – пробелы в середине строки для удобства чтения:

$foo   = 'какое-то значение';
$foo2  = 'какое-то значение2';
$foo34 = 'какое-то значение3';
$foo5  = 'какое-то значение4';

3.2 Ассоциативные массивы

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

$args = array(
	'post_type'   => 'page',
	'post_author' => 123,
	'post_status' => 'publish',
);

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

или, если один элемент:

$args = array( 'post_type' => 'page' );

3.3 Использование пробелов

Есть некоторые рекомендации, где следует добавлять пробелы и, поверьте, после этого ваш код будет выглядеть очень красиво!

  • После запятых,
  • С обеих сторон логических операторов (это ||&&, и !),
if ( ! $echo ) { ...
  • С обеих сторон операторов сравнения ( <>=====, и т д.)
  • С обеих сторон оператора присваивания (а именно =)
  • С обеих сторон открывающихся и закрывающихся скобок условий, циклов:
if ( $terms ) {
 
	foreach ( $terms as $term ) { ...
  • В случае если переменная передаётся в качестве индекса элемента массива:
$arr[ $x ]  = 'foo'; // пробелы только тут
$arr[0]     = 'bar';
$arr['foo'] = 'bar';
  • И конечно, никаких пробелов на концах строк.

3.4 Открывающие и закрывающие PHP теги

При использовании кода PHP вместе с блоком HTML, открывающий и закрывающий теги <?php и ?> должны быть ЛИБО на одной строке:

<?php while( have_posts() ) : the_post(); ?>

ЛИБО единственными на строке:

function foo() {
	?>
		<div>
		<?php
			echo bar(
				$baz,
				$bat
			);
		?>
		</div>
	<?php
}

3.5 Вызов функций

Все аргументы функции при её вызове либо должны все находиться на одной строке, либо каждый аргумент – на новой строке, пример:

$url = add_query_arg( 
	array(
		'param_1' => 'value_1',
		'param_2' => 'val2',
	), 
	admin_url()
);

4. Условия

4.1 Фигурные скобки

Тут легко – используем всегда, даже если они не обязательны.

if( условие ) {
	действие
}

Но это не значит, что мы не можем использовать альтернативный синтаксис записи условий и циклов if/endif, while/endwhile, наоборот он рекомендуется, если у вас в коде присутствует вывод HTML.

<?php while ( have_posts() ) : the_post(); ?>
	<article id="post-<?php the_ID() ?>" class="<?php post_class() ?>">
		<!--  ...  -->
	</article>
<?php endwhile; ?>

4.2 Используйте elseif а не else if

Как раз в том случае, если мы будем использовать альтерантивный синтаксис условий (с двоеточием), то в случае else if, мы получим фатальную ошибку, поэтому – только elseif, всегда.

4.3 Тернарный оператор

Для тех, кто не знаком, тернарный оператор упрощает запись условий if / else. Лучше всего показать на примере:

$is_electric = null;
 
if ( 'tesla' == $car_name ) {
	$is_electric = true;
} else {
	$is_electric = false;
}

Зацените, как сильно упрощается условие:

$is_electric = 'tesla' == $car_name ? true : false;

Тут одно правило – тернарным оператором нужно проверять только правдивое утверждение, за исключением проверок ! empty().

4.4 Условия Йоды (Yoda Conditions)

Если вы взгляните на код чуть выше, то заметите, как «условия я записывал», а именно – сначала значение, а потом переменная. Почему так?

Условие ЙодыОбычное условие
if ( 'tesla' == $car_name ) {if ( $car_name == 'tesla' ) {
if( false !== $echo ) {if( $echo !== false ) {

Например, если в коде выше мы случайно пропустим один знак =, что иногда с вами случалось, со мной уж точно, то вы получите parse error, потому что вы не можете делать присвоение к константам, если же наша запись была в формате ( $car_name = 'tesla' ), то всё было бы ок, оно возвращало бы true, и вы бы пытались какое-то время понять, что же в коде не так.

Условия Йоды применяются к операторам ==, !=, ===, and !==, но не <, >, <= или >=.

4.5 Операторы сравнения

По возможности всегда используем операторы тождественного сравнения, пример:

if ( 0 === strpos( 'WordPress', 'foo' ) ) {
    echo 'Привет WordPress!';
}

4.6 Присвоение внутри условия

Признаюсь вам честно, пока что я фейлю здесь и делаю не правильно, например мне очень нравится такая запись:

if( $post_meta = get_post_meta( get_the_ID(), 'meta_key', true ) ) {
	// делаем что-то с $post_meta
}

Но такую запись не нужно использовать, правильно её переделать вот так:

$post_meta = get_post_meta( get_the_ID(), 'meta_key', true );
if( $post_meta ) {
	// делаем что-то с $post_meta
}

Обещаю исправиться! А вам рекомендую сразу делать правильно 👆

5. Умный код

Никогда не жертвуйте удобством читаемости кода ради того, чтобы он выглядел «по-умному», например если вам хочется сделать такую запись isset( $var ) || $var = some_function(), то вовремя остановитесь, и сделайте по-нормальному:

if ( ! isset( $var ) ) {
	$var = some_function();
}

5.1 Массивы

Массивы пишем вместе со словом array(), не ленимся array( 5, 10, 'привет' ). Не надо их делать как в JavaScript с квадратными скобками.

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

5.2 Не используем короткую запись PHP-тегов

Только <?php и ?>, а не <? и ?>.

А также <?php echo $var; ?> вместо <?= $var ?>

6. Не используем от слова совсем!

Списочек:

  • eval()  и create_function() из-за их небезопасности,
  • Оператор goto,
  • Оператор управления ошибками @,
  • Функцию extract()

7. Хуки

Вообще, про хуки (фильтры и действия) у меня есть отдельный подробный урок.

7.1 Динамические хуки

Бывает, что название хука статично и является строкой: do_action( 'wp_head' ), а иногда может состоять из переменных, например:

do_action( "woocommerce_after_edit_address_form_{$load_address}" );

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

7.2 Анонимные функции

Они появились в версии PHP 7.3 и благодаря им мы можем очень классно записывать сниппеты к хукам WordPress, лишний раз не раздумывая над именем функции к хуку, например:

add_action( 'woocommerce_single_product_summary', function() {
	// выводим тут что-то
}, 25 );

Вообще такая запись это ок, но:

  • нельзя использовать, если пишете это для ядра WordPress,
  • нельзя использовать, если планируется возможность отключения этого хука при помощи remove_action().

8. Запросы к базе данных

Последнее, но пожалуй, самое важное.

  • Избегаем написания прямых запросов к базе данных, если это можно решить, используя API WordPress, такие как WP_Query, get_post_meta(), WP_User_Query и так далее.
  • Экранируем запросы к базе данных при помощи $wpdb->prepare(), подробнее тут.

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

Комментарии — 4

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

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал