Muszę sprawdzić, czy wartość jest zdefiniowana jako cokolwiek, w tym null. isset
traktuje wartości null jako niezdefiniowane i zwraca false
. Weźmy jako przykład:
$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
Zwróć uwagę, że $bar
jest to niezdefiniowane.
Muszę znaleźć warunek spełniający następujące warunki:
if(something($bar)) // returns false;
if(something($foo)) // returns true;
Jakieś pomysły?
isset
= jest ustawione?, Twoja zmienna jest ustawiona na null. Zmarnowałem dużo czasu z powodu tego ...Odpowiedzi:
IIRC, możesz użyć
get_defined_vars()
do tego:$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
źródło
get_defined_vars
szczęśliwie radzi sobie z zakresem.get_defined_vars()
:array_key_exists('foo', compact('foo'))
. Lub szybciej, jeśli testowanie globalny:array_key_exists('foo', $GLOBALS)
.Jeśli masz do czynienia z właściwościami obiektu, które mogą mieć wartość NULL, możesz użyć:
property_exists()
zamiastisset()
<?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(); ?>
źródło
Zobacz Najlepszy sposób na sprawdzenie istnienia zmiennej w PHP; isset () jest wyraźnie uszkodzony
if( array_key_exists('foo', $GLOBALS) && is_null($foo)) // true & true => true if( array_key_exists('bar', $GLOBALS) && is_null($bar)) // false & => false
źródło
Odkryłem, że
compact
jest to funkcja, która ignoruje nieustawione zmienne, ale działa na tych ustawionychnull
, więc gdy masz dużą lokalną tablicę symboli, wyobrażam sobie, że możesz uzyskać bardziej wydajne rozwiązanie niż sprawdzaniearray_key_exists('foo', get_defined_vars())
, używającarray_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
Aktualizacja
Od PHP 7.3 compact () wyświetli powiadomienie o nieustawionych wartościach, więc niestety ta alternatywa nie jest już ważna.
źródło
compact
. Niemniej jednak zagłosowałem za tym, ponieważ jest to przydatne w jednej sytuacji: jeśli chcesz wiedzieć, czyfoo
istnieje w obecnym kontekście , niezależnie od tego, skąd pochodzi - jeśli nie obchodzi Cię, czy jest lokalny czy globalny, po prostu chcesz wiedzieć, czy to istnieje.get_defined_vars
. Zobacz tutaj .Poniższy kod napisany jako rozszerzenie PHP jest odpowiednikiem array_key_exists ($ name, get_defined_vars ()) (dzięki Henrik i Hannes).
// 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; } }
źródło
Możesz użyć is_null i empty zamiast isset (). Pusta nie wyświetla komunikatu o błędzie, jeśli zmienna nie istnieje.
źródło
isset
.is_null
ma ten sam problem cois_set
: nie może rozróżnić między „nie ustawiono” i „ustawiono na wartość null”, co jest problemem, który ma OP.empty
jest jeszcze gorzej, jak wskazuje Calum.Oto głupie obejście problemu przy użyciu 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
źródło
is_null($bar)
zwraca prawdę, ponieważ nie ma żadnych wartości. Alternatywnie możesz użyć:if(isset($bar) && is_null($bar)) // returns false
aby sprawdzić, czy
$bar
jest zdefiniowana i zwróci wartość true tylko wtedy, gdy:$bar = null; if(isset($bar) && is_null($bar)) // returns true
źródło
if(isset($bar))
daje fałsz kiedy$bar = null
.$bar = "test"
).isset($bar)
zwraca fałsz, nawet po$bar = null;
.