Проверьте, установлено ли значение и равно нулю - PullRequest
79 голосов
/ 27 сентября 2010

Мне нужно проверить, определено ли значение как что-либо, включая ноль. 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;

Есть идеи?

Ответы [ 8 ]

76 голосов
/ 27 сентября 2010

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
24 голосов
/ 22 января 2014

Если вы имеете дело со свойствами объекта, которые могут иметь значение 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.

12 голосов
/ 27 сентября 2010

См. Лучший способ проверить существование переменной в 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 голосов
/ 27 сентября 2016

Я обнаружил, что 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, если данная строка ссылается на неустановленную переменную.Раньше такие строки молча пропускались.

1 голос
/ 27 августа 2013

Следующий код, написанный как расширение 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;
    }

}
0 голосов
/ 27 сентября 2010

Вот какой-то глупый обходной путь с использованием 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
0 голосов
/ 27 сентября 2010

is_null($bar) возвращает true, так как у него вообще нет значений.В качестве альтернативы, вы можете использовать:

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

, чтобы проверить, определено ли $bar и будет ли оно верным, только если:

$bar = null;
if(isset($bar) && is_null($bar)) // returns true
0 голосов
/ 27 сентября 2010

Вы можете использовать is_null и пусто вместо isset (). Empty не печатает сообщение об ошибке, если переменная не существует.

...