web-dev-qa-db-ja.com

値が設定され、nullかどうかを確認します

値が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;

何か案は?

81
Tatu Ulmanen

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
78
Henrik Opel

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()は、プロパティの値がNULLであってもTRUEを返します。

25
John Magnolia

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
13
Loïc Février

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レベルのエラーを発行するようになりました。以前は、このような文字列は静かにスキップされていました。

3
nzn

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;
    }

}
1
masakielastic

Isset()の代わりに is_null および empty を使用できます。変数が存在しない場合、Emptyはエラーメッセージを出力しません。

0
Raveline

ここで、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
Philippe Gerber