Почему нужно четко понимать ISSET и EMPTY различия в PHP

  • написал: MpaK
  • 1705
Как бы не ругали PHP за слабую и плохую типизированность помноженную на кучу функций на все случаи жизни, у него есть полно плюсов как простота при подходе к решению задач, обилие инструментов по умолчанию и т.д.

Один вот нюанс я заметил, что часто встречается у разработчиков на PHP это люди путают назначение функций empty и isset.

Вот вам пример, как вам кажется этот код хорош или нет?

if(isset($params['alias'])) $where[] = 'alias = "'.addslashes($params['alias']).'"';


я даже не буду ничего говорить про addslashes без проверки magic_quotes* если вы не новичок вам и так понятно, да и всё же дальше используется dibi библиотека в которой есть гибкий и очень удобный конструктор запросов и плэйсхолдер по умолчанию. Что люди не используют всех возможностей библиотек и так ясно, это просто лень почитать одностраничный ман.

Речь не об этом, речь об isset и empty.

Что мы знаем об empty? Это на самом деле простая директива или конструкция языка, которая проверяет переменную на пустоту и не выдаёт предупреждения, если даже переменная не определена, то есть она совмещает в себе функцию isset
empty() is the opposite of (boolean) var, except that no warning is generated when the variable is not set.)

Второе, что такое пустота для PHP. Именно за такие вещи многие не любят PHP или многие не любят после PHP другие языки, когда пустота в них имеет определенное значение например nil (Ruby, puts nil.class) или undefined (JS).

В PHP пустота это 0, "", array(), 0.0, FALSE, Null или просто даже без значения определенная переменная:
The following things are considered to be empty:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
«0» (0 as a string)
NULL
FALSE
array() (an empty array)
var $var; (a variable declared, but without a value in a class)

История с isset вообще проще, это так же конструкция языка, которая проверяет только две вещи: объявлена ли переменная ($var; например) и не является ли она NULL!
Всё!

То есть получается, что вот код.
$name = '';
if( isset($name) ) echo "Hello {$name}\n";
if( !empty($name) ) echo "Good night {$name}\n";

Выдаст всё же не тот что нам как бы нужен:
> Hello

Так и выше код соберётся с ненужным условием и даже скорее неправильным (!!!) условием, когда было происходит сбор параметров

 $params['alias'] = $_GET['alias'];
...
// сбор sql запроса, для PHP переменная $params['alias'] всё же объявлена, НО ПУСТАЯ!
if(isset($params['alias'])) $where[] = 'alias = "'.addslashes($params['alias']).'"';

ваш SQL запрос получится смешного вида alias = '', хотя я уверен вам бы хотелось видеть его совсем иного вида.

Поэтому я всё же правильнее понимать отличия где и когда использовать isset и empty.

Удачи, оставайтесь на стороне разума!

6 комментариев

avatar
  • yan
  • 0
не совсем понял вывод статьи — в данном примере надо было заменить isset на !empty?
но тогда $where[] не добавится и при $params['alias']=0, а это может оказаться необходимо и хорошо если сразу необходимо — можно поправить, хуже если необходимость использования 0 появится позже в ходе разработки и придется искать где ж 0 игнорируется
avatar
  • MpaK
  • 0
В этом случае alias не может быть НУЛЁМ ну никак :) это строковое значение.

И да надо было заменить на empty потому как isset при пустой строке будет не правильно работать, это из за непонимания как раз работы этих функций, о том и пост.
avatar
  • yan
  • 0
все же я бы предпочел более длинное
if(isset($params['alias']) &&  strlen($params['alias'])>0) ...

мало ли, что там завтра будет, вдруг $params['alias']='0' тоже будет иметь смысл
avatar
  • MpaK
  • 0
Ну тут не на будущее страховаться надо, надо понимать как работает empty и isset в этом суть статьи.

А если на будущее, то вот твой код тоже лучше переписать, && всё же битовая И лучше на AND, а strlen на mb_strlen так как utf-8 он уже везде и на завтра :)))
avatar
  • yan
  • 0
насчет && и and не понял — у них разве есть отличия в работе в данном случае?
а mb_strlen при сравнении с нулем наверное не так все таки принципиален
avatar
  • MpaK
  • 0
в данном случае нет, но всё не следует в языке как PHP использовать не то что не надо, там где не надо, это в духе echo 0x00+2; вот и пример.

С mb_strlen тоже самое раз ты «на будущее» смотришь
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.