100

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

有任何想法吗?

4

11 回答 11

91

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
于 2010-09-27T11:51:37.957 回答
31

如果您正在处理可能具有 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() 不同,property_exists() 会返回 TRUE,即使该属性的值为 NULL。

于 2014-01-22T08:20:26.560 回答
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
于 2010-09-27T11:28:13.453 回答
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 级别的错误。以前,此类字符串已被默默跳过。

于 2016-09-27T10:02:12.113 回答
3

我在寻找数组的解决方案时发现了这个主题。检查是否存在包含 NULL 的数组元素,这种构造帮助了我

    $arr= [];
    $foo = 'foo';
    $arr[$foo]= NULL;
    if (array_key_exists('bar', $arr)) {}; // Should evaluate to FALSE
    if (array_key_exists('foo', $arr)) {}; // Should evaluate to TRUE
    if (array_key_exists($foo, $arr)) {}; // Should evaluate to TRUE
于 2021-06-25T18:45:34.840 回答
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;
    }

}
于 2013-08-27T06:39:06.750 回答
0

您可以使用is_nullempty而不是 isset()。如果变量不存在,Empty 不会打印错误消息。

于 2010-09-27T11:20:03.707 回答
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
于 2010-09-27T11:31:03.567 回答
0

冒着被否决的风险,我什至不会打扰 - 显然 PHP 希望您在逻辑上认为 NULL 和 Undef 是相同的。我只是用它运行 - 我创建了一个函数:

bool isEmpty(& $davar);

检查 isset(处理 null 和 undef)、“”和 array()。请注意,这是故意不处理虚假;只是空的。& 'reference-izer' 允许在未定义的情况下传递变量而没有错误消息,如果您首先检查 isset 并返回 false,则可以在没有错误的情况下对 "" 和 array() 进行下一次检查。

下一个函数利用了这个函数,并在你会使用的地方使用

$davar || some-default.

那就是:

mixed defaultForEmpty(& $daVar, $default);

仅具有以下条件:

if (isEmpty($daVar)) 
    return $default;
else
    return $daVar;

顺便说一句,这些适用于对象引用、数组索引、$_GET、$_POST 等。

于 2021-06-18T04:07:58.680 回答
0

就我而言,我有以下代码:

class SomeClass {

  private $cachedInstance;

  public instance()
  {
    if (! isset($this->cachedInstance)) {
      $this->cachedInstance = GetCachedInstanceFromDb(); // long operation, that could return Null if the record not found
    }

    return $this->cachedInstance;
  }
}

如果它返回 null ,它会以一种GetCachedInstanceFromDb()被多次调用的方式失败。因为isset()即使该属性被显式设置为 Null,也会返回 false。

因此,我必须进行以下更改:

  1. 声明初始值设置为 False 的属性;

  2. 检查当前变量值时使用严格(类型安全)比较;

class SomeClass {

  private $cachedInstance = false; // #1

  public instance()
  {
    if ($this->cachedInstance === false) { // #2
      $this->cachedInstance = GetCachedInstanceFromDb();
    }

    return $this->cachedInstance;
  }
}
于 2021-08-20T05:36:46.280 回答
-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
于 2010-09-27T11:29:45.783 回答