Будьте осторожны с PHP empty при ее использовании в шорткодах Wordpress

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

Особенности работы функции empty(), о которых нужно знать

Согласно мануалу на php.net, эта функция проверяет пуста ли переменная.

Если переменная не существует, то empty() не выдаст ошибку. Например, пусть переменная $foo не установлена:

if( empty($foo) ){ echo "variable is empty"; } //выведет "variable is empty"

Следовательно нужна дополнительная проверка функцией isset():

$foo = 1;
if( isset($foo) && !empty($foo) ){ echo "variable = ".$foo; } // выведет "variable = 1"

Значения, которые PHP empty() считает пустыми, это:

  • "" (строки - strlen('') == 0 );
  • 0 (целые числа - (int)0 );
  • 0.0 (числа с плавающей точкой - (float)0.0 );
  • "0" (строки - strlen("0") == 1 );
  • NULL;
  • FALSE;
  • array() ( пустые массивы - count( array( ) ) == 0 ).
$string_1 = '';
echo strlen($string_1); //выведет 0
if( empty( $string_1 ) ){ echo 'string_1 is empty'; } // выведет "string_1 is empty"

$string_2 = '0';
echo strlen($string_2); //выведет 1
if( empty( $string_2 ) ){ echo 'string_2 is empty'; } // выведет "string_2 is empty"

Строку ($string_2) длиной в один символ со строчным нулем ('0') функция empty() тоже считает пустой.

Но строку с одним пробелом не считает пустой:

$string_3 = ' ';
echo strlen($string_3); //выведет 1
if( empty( $string_3 ) ){ echo 'string_3 is empty'; } // ничего не выведет

Давайте рассмотрим практическое применение PHP empty и увидим, как эта функция может привести к неожиданному результату.

Применение функции empty() для проверки атрибутов шорткода в плагинах Wordpress

Например, вы разрабатываете плагин для Wordpress, в котором с помощью шорткодов будут выводится статьи разных авторов. На странице аккаунта каждого автора будут показаны его собственные статьи ("self") и статьи других авторов ("another") за последний месяц. С помощью шорткода можно управлять количеством вывода статей. По умолчанию, если атрибуты "self" и "another" не установлены, будем выводить, например, 25 собственных постов и 15 постов других авторов.

[author_posts]

Чтобы поменять значение, добавим другие количества в атрибуты шорткода:

[author_posts self="10" another="5" ]

Посмотрим, что в коде плагина:

<?php
/**
 * @package author_posts
 */
/*
 * Plugin Name: Author posts
 * Description: Author posts
 * Version: 1.0.0
 * Author: V.Taran
 */
function posts_shortcode( $atts ) {

	$atts = shortcode_atts(
		array(
			'self' => '',
			'another' => '',
		),
		$atts,
		'author_posts'
	);
	if(!empty($atts['self'])){ 
		echo $atts['self']." post(s)"; 
	}else{ 
		echo "25 self posts"; }
	if(!empty($atts['another'])){ 
		echo $atts['another']." post(s)"; 
	}else{ 
		echo "15 posts of another authors";
	}
}
add_shortcode( 'author_posts', 'posts_shortcode' );

Здесь мы просто выводим на печать данные, которые пользователь передал через шорткод. В результате мы увидим 10 собственных постов и 5 - других авторов.

Вывод с шорткода Wordpress

Если мы не хотим видеть, например, посты других авторов, то напишем в шорткод "another=0", и посты других авторов отображаться не будут. Но нет! Функция PHP empty() считает строчный "0" как пустое значение, и вместо "0" постов других авторов, отобразит значение по умолчанию, т.е. 15 записей вместо нуля.

Иными словами, эти две записи аналогичны:

[author_posts another="0" ]
[author_posts ]

Чтобы шорткод работал правильно, изменим условие:

$is_null = (int)(-1);

'another' => $is_null,

if($atts['another'] > -1 ){ 
	echo $atts['another']." post(s)"; 
}else{ 
	echo "15 posts of another authors";
}

Если атрибут "another" не задан, то по умолчанию пусть он будет равен (-1). Тогда в условии будем считать, что атрибут задан, если он больше (-1).

Таким образом, этот шорткод:

[author_posts another="0" ]

теперь все правильно нам отображает, т.е. по умолчанию 25 статей автора (т.к. атрибут "self" не указан) и ни одной статьи других авторов.

Особенности php empty, которые необходимо учитывать в шорткодах Wordpress

Весь код:

<?php
/**
 * @package author_posts
 */
/*
 * Plugin Name: Author posts
 * Description: Author posts
 * Version: 1.0.0
 * Author: V.Taran
 */
function posts_shortcode( $atts ) {
	
	$is_null = (int)(-1);
	
	$atts = shortcode_atts(
		array(
			'self' => '',
			'another' => $is_null,
		),
		$atts,
		'author_posts'
	);
	if(!empty($atts['self'])){ 
		echo $atts['self']." post(s)<br>"; 
	}else{ 
		echo "25 self posts<br>"; }
	if($atts['another'] > -1 ){ 
		echo $atts['another']." post(s)<br>"; 
	}else{ 
		echo "15 posts of another authors<br>";
	}
}
add_shortcode( 'author_posts', 'posts_shortcode' );

Вы можете придумать свое условие, важно, что вы увидели особенности работы функции empty() и в дальнейшем не допустите ошибку при ее использовании. Поместите этот файл в папку Wordpress "/wp_content/plugins/" и активируйте плагин в панели администратора, он будет работать.

Варианты замены empty() на другие функции PHP

Чтобы понять, чем заменить empty(), нужно знать, что мы имеем, например:

  • если это массив (array()), то лучше проверять его функциями count или sizeof;
  • если переменная может быть равна false, то используйте if( false == $var );
  • если переменная не установлена, то с помощью isset или is_null();
  • числам подойдет is_numeric().

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

Мы выяснили, что empty PHP - функция, которая проверяет пуста ли переменная. Нужно помнить, какие значения переменной определяются как нулевые, если используете ее в своем коде, чтобы потом не искать, почему программа работает неправильно.

Статья закончилась. Вопросы остались?
Комментарии 0
Подписаться
Я хочу получать
Правила публикации
Редактирование комментария возможно в течении пяти минут после его создания, либо до момента появления ответа на данный комментарий.