检查值是否设置为null


88

我需要检查value是否定义为任何东西,包括null。isset将null值视为undefined并返回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;

有任何想法吗?


19
if(isset($ foo))//返回false,这些年来我从椅子上掉下来了
max4ever 2012年

in_array($ key,array_keys($ _ SESSION))&& is_null($ _ SESSION [$ key])我想了这么久..
杰克

1
这对我来说不是正常现象,isset=设置为?,您的变量设置为null。因为这个,我浪费了很多时间...
Vincent Decaux

Answers:


84

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

+1我将建议相同的功能,get_defined_vars愉快地应对范围。
萨拉特(Salathe)2010年

1
似乎正在工作,但我希望有一些简单的方法。那好吧。让我们看看是否有人能拿出一支衬板。
塔图·乌尔曼嫩

4
好吧,您不需要var,因此从理论上讲,它的一行是“ if(array_key_exists('foo',get_defined_vars()){}”
Hannes

FVN的新的答案可能是一种更快的方式来获得存在于当前背景下,一个变量避免了成本get_defined_vars()array_key_exists('foo', compact('foo'))。或更快,如果测试一个全球性的:array_key_exists('foo', $GLOBALS)
ToolmakerSteve

25

如果你正在处理的对象属性whcih可能有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();

?>

与isset()相反,即使该属性的值为NULL,property_exists()也会返回TRUE。


11
您可以使用array_key_exists()对数组执行相同的操作;
Calum 2014年

14

请参阅测试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

3
您引用的代码仅在变量位于全局范围内时才有效。
拉夫兰

确实,但这不是最常见的情况吗?在一个函数中,您将具有全局范围内的变量和参数(始终已定义)。您也可以具有对象属性,但是可以使用'property_exists'。
卢瓦克FEVRIER

使用$ GLOBALS似乎有点不稳定,我必须先做一些测试,然后才能声明它是有效的。
塔图·乌尔曼嫩

4

我发现这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()现在会发出E_NOTICE级错误。以前,此类字符串已被静默跳过。


有趣的选择。但要注意,它可能是比调用现有的阵列上array_key_exists,如$ GLOBALS -因为一个查找在哈希表中没有得到任何慢,当表变大,并且您已经添加额外的工作compact。不过,我赞成它,因为它在一种情况下很有用:如果您想知道当前上下文中是否foo存在,无论它来自何处-如果您不在乎本地还是全局,都只想知道它是否存在?存在。
ToolmakerSteve

@ToolmakerSteve-我实际上指的是调用的潜在开销get_defined_vars。看这里
nzn

1

以下编写为PHP扩展的代码等效于array_key_exists($ name,get_defined_vars())(感谢Henrik和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;
    }

}

0

您可以使用is_nullempty代替isset()。如果变量不存在,则Empty不显示错误消息。


我正在使用is_null。不管的结果是一样的isset
塔图·乌尔曼嫩

发布第一个答案时我犯了一个错误:您尝试用empty()吗?
Raveline

1
对于非空和非NULL的值(例如FALSE,0,array()或“”),此方法将不起作用。
Calum 2014年

1
这个答案是错误的。is_null具有与以下问题相同的问题is_set:无法区分“未设置”和“设置为null”,这是OP的问题。empty正如Calum指出的那样,情况甚至更糟。
制造商史蒂夫(Steve)

0

这里有一些使用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

1
看起来不太便于携带.. :)
Tatu Ulmanen 2010年

-3

is_null($bar)返回true,因为它根本没有任何值。或者,您可以使用:

if(isset($bar) && is_null($bar)) // returns false

检查是否$bar已定义,并且仅在以下情况下返回true:

$bar = null;
if(isset($bar) && is_null($bar)) // returns true

不,他说那是if(isset($bar))假的$bar = null
卢瓦克FEVRIER

2
这将不传递除null外的任何其他变量(例如if $bar = "test")。
塔图·乌尔曼嫩

3
当$ bar = null时,isset()将返回“ false”,而is_null()将返回true。假与真总是假。
Bartek Kosa

这个答案是完全错误的。正如OP所说isset($bar),即使在之后也返回false $bar = null;
ToolmakerSteve
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.