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

14 0 Новини високих технологій

Дуже часто на веб-ресурсах по вивченню і розробці плагінів для 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() теж вважає марною.

<script async="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
<!-- fb_336x280_1 -->

<script> (adsbygoogle = window.adsbygoogle ||[]).push({});

Але рядок з одним пропуском не вважає марною:

  $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 постів інших авторів.

<script async="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
<!-- fb_336x280_2 -->

<script> (adsbygoogle = window.adsbygoogle ||[]).push({});
 [author_posts] 

Щоб змінити значення, додамо інші кількості атрибути шорткода:

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

Подивимося, що в коді плагіна:

   ", 
'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 - інших авторів.


<script type="text/javascript">
var blockSettings2 = {blockId:"R-A-70350-39",renderTo:"yandex_rtb_R-A-70350-39",async:!0};
if(document.cookie.indexOf("abmatch=") >= 0) blockSettings2.statId = 70350;
!function(a,b,c,d,e){a[c]=a[c]||[],a[c].push(function(){Ya.Context.AdvManager.render(blockSettings2)}),e=b.getElementsByTagName("script")[0],d=b.createElement("script"),d.type="text/javascript",d.src="//an.yandex.ru/system/context.js",d.async=!0e.parentNode.insertBefore(d,e)}(this,this.document,"yandexContextAsyncCallbacks");
Будьте обережні з PHP empty при її використанні в шорткодах 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

Весь код:

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


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

Варіанти заміни empty() інші функції PHP

Щоб зрозуміти, чим замінити empty(), потрібно знати, що ми маємо, наприклад:
  • якщо це масив (array()), то краще перевіряти його функціями count або sizeof;
  • якщо змінна може бути дорівнює false, то використовуйте if( false == $var );
  • якщо змінна не встановлена, то з допомогою ісеть або is_null();
  • числам підійде is_numeric().
  • Багато варіантів можна знайти, щоб ваша програма працювала максимально точно, напишіть свою функцію, яка буде аналізувати дані так, як вам необхідно. Ми з'ясували, що empty PHP - функція, яка перевіряє чи порожня мінлива. Потрібно пам'ятати, які значення змінної визначаються як нулі, якщо використовуєте її в своєму коді, щоб потім не шукати, чому програма працює неправильно.