J'ai besoin de vérifier si la valeur est définie comme quoi que ce soit, y compris null. isset
traite les valeurs nulles comme non définies et renvoie false
. Prenons l'exemple suivant:
$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
Notez que $bar
n'est pas défini.
Je dois trouver une condition qui remplit les conditions suivantes:
if(something($bar)) // returns false;
if(something($foo)) // returns true;
Des idées?
IIRC, vous pouvez utiliser get_defined_vars()
pour cela:
$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
Si vous avez affaire à des propriétés d'objet qui peuvent avoir une valeur NULL, vous pouvez utiliser: property_exists()
au lieu de 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();
?>
Contrairement à isset (), property_exists () renvoie TRUE même si la propriété a la valeur NULL.
Voir Meilleure façon de tester l'existence d'une variable en PHP; isset () est clairement cassé
if( array_key_exists('foo', $GLOBALS) && is_null($foo)) // true & true => true
if( array_key_exists('bar', $GLOBALS) && is_null($bar)) // false & => false
J'ai constaté que compact
est une fonction qui ignore les variables non définies mais agit sur celles définies sur null
, donc lorsque vous avez une grande table de symboles locale, j'imagine que vous pouvez obtenir une solution plus efficace sur la vérification de array_key_exists('foo', get_defined_vars())
en utilisant 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
Mise à jour
À partir de PHP 7.3 compact () donnera un avis pour les valeurs non définies, donc malheureusement cette alternative n'est plus valide.
compact () émet désormais une erreur de niveau E_NOTICE si une chaîne donnée fait référence à une variable non définie. Auparavant, ces chaînes étaient silencieusement ignorées.
Le code suivant écrit sous la forme PHP est équivalente à array_key_exists ($ name, get_defined_vars ()) (merci à Henrik et 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;
}
}
Voici une solution de contournement stupide en utilisant 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