Мне нужно проверить, определено ли значение как что-либо, включая null. isset
обрабатывает нулевые значения как неопределенные и возвращает false
. В качестве примера возьмем следующее:
$foo = null;
if(isset($foo)) // returns false
if(isset($bar)) // returns false
if(isset($foo) || is_null($foo)) // returns true
if(isset($bar) || is_null($bar)) // returns true, raises a notice
Обратите внимание, что $bar
это не определено.
Мне нужно найти условие, удовлетворяющее следующему:
if(something($bar)) // returns false;
if(something($foo)) // returns true;
Любые идеи?
isset
= установлено?, Ваша переменная установлена на ноль. Я потратил кучу времени из-за этого ...Ответы:
IIRC, вы можете использовать
get_defined_vars()
для этого:$foo = NULL; $vars = get_defined_vars(); if (array_key_exists('bar', $vars)) {}; // Should evaluate to FALSE if (array_key_exists('foo', $vars)) {}; // Should evaluate to TRUE
источник
get_defined_vars
с размахом прекрасно справляется.get_defined_vars()
:array_key_exists('foo', compact('foo'))
. Или быстрее, если тестирование глобальной:array_key_exists('foo', $GLOBALS)
.Если вы имеете дело со свойствами объекта, которые могут иметь значение NULL, вы можете использовать:
property_exists()
вместоisset()
<?php class myClass { public $mine; private $xpto; static protected $test; function test() { var_dump(property_exists($this, 'xpto')); //true } } var_dump(property_exists('myClass', 'mine')); //true var_dump(property_exists(new myClass, 'mine')); //true var_dump(property_exists('myClass', 'xpto')); //true, as of PHP 5.3.0 var_dump(property_exists('myClass', 'bar')); //false var_dump(property_exists('myClass', 'test')); //true, as of PHP 5.3.0 myClass::test(); ?>
источник
См. « Лучший способ проверить наличие переменной в PHP»; isset () явно не работает
if( array_key_exists('foo', $GLOBALS) && is_null($foo)) // true & true => true if( array_key_exists('bar', $GLOBALS) && is_null($bar)) // false & => false
источник
Я обнаружил, что
compact
это функция, которая игнорирует неустановленные переменные, но действует на те, которые установленыnull
, поэтому, когда у вас есть большая локальная таблица символов, я думаю, вы можете получить более эффективное решение по проверкеarray_key_exists('foo', get_defined_vars())
, используяarray_key_exists('foo', compact('foo'))
:$foo = null; echo isset($foo) ? 'true' : 'false'; // false echo array_key_exists('foo', compact('foo')) ? 'true' : 'false'; // true echo isset($bar) ? 'true' : 'false'; // false echo array_key_exists('bar', compact('bar')) ? 'true' : 'false'; // false
Обновить
Начиная с PHP 7.3 compact () выдает уведомление о неустановленных значениях, поэтому, к сожалению, эта альтернатива больше не действует.
источник
compact
. Тем не менее, я поддержал его, потому что он полезен в одной ситуации: если вы хотите знать,foo
существует ли он в текущем контексте , независимо от того, откуда он появился - если вам все равно, является ли он локальным или глобальным, просто хотите знать, является ли он существует.get_defined_vars
. Смотрите здесь .Следующий код, написанный как расширение PHP, эквивалентен array_key_exists ($ name, get_defined_vars ()) (спасибо Хенрику и Ханнесу).
// get_defined_vars() // https://github.com/php/php-src/blob/master/Zend/zend_builtin_functions.c#L1777 // array_key_exists // https://github.com/php/php-src/blob/master/ext/standard/array.c#L4393 PHP_FUNCTION(is_defined_var) { char *name; int name_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; } if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); } if (zend_symtable_exists(EG(active_symbol_table), name, name_len + 1)) { RETURN_TRUE; } }
источник
Вы можете использовать is_null и empty вместо isset (). Empty не выводит сообщение об ошибке, если переменная не существует.
источник
isset
.is_null
имеет ту же проблему, что иis_set
: он не может различить «не установлено» и «установлено в ноль», что и является проблемой OP.empty
еще хуже, как отмечает Калум.Вот какой глупый обходной путь с помощью xdebug. ;-)
function is_declared($name) { ob_start(); xdebug_debug_zval($name); $content = ob_get_clean(); return !empty($content); } $foo = null; var_dump(is_declared('foo')); // -> true $bla = 'bla'; var_dump(is_declared('bla')); // -> true var_dump(is_declared('bar')); // -> false
источник
is_null($bar)
возвращает истину, поскольку у него вообще нет значений. В качестве альтернативы вы можете использовать:if(isset($bar) && is_null($bar)) // returns false
чтобы проверить,
$bar
определено ли оно, и вернет истину, только если:$bar = null; if(isset($bar) && is_null($bar)) // returns true
источник
if(isset($bar))
неверно, когда$bar = null
.$bar = "test"
).isset($bar)
возвращает false даже после$bar = null;
.