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


88

値がnullを含む何かとして定義されているかどうかを確認する必要があります。issetnull値を未定義として扱い、を返します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($キー、array_keys($ _ SESSION))&& IS_NULL($ _ SESSION [$キー])私はあまりにも長い間、これを思っていた...
ジャック

1
これは私にとって通常の動作ではありません、isset=が設定されていますか?、変数がnullに設定されています。私は...このために一つで多くの時間を無駄に
ヴィンセントDecaux

回答:


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、スコープにうまく対応しました。
2010

1
動作しているようですが、もっと簡単なものが欲しいと思っていました。しかたがない。誰もがワンライナーを思い付くことができるかどうか見てみましょう。
Tatu Ulmanen 2010

4
ええと、varsは必要ないので、理論的にはその1行 "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 2017年

25

あなたがオブジェクトのプロパティを扱っている場合は、使用できるNULL値を持っているかもしれませんwhcih: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を返します。


11
array_key_exists();を使用して配列に対して同じことを行うことができます。
teaqu 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
引用するコードは、変数がグローバルスコープ内にある場合にのみ機能します。
Raveline 2010

確かに、しかしそれは最も頻繁なケースではありませんか?関数には、グローバルスコープと引数(常に定義されている)の変数があります。オブジェクトプロパティを持つこともできますが、その場合は「property_exists」を使用できます。
ロイックFévrier

$ GLOBALSの使用は少し不安定に思えます。これが機能していると宣言する前に、自分でテストを行う必要があります。
Tatu Ulmanen 2010

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()は未設定の値を通知するため、残念ながらこの代替手段は無効になります。

コンパクト()は、指定された文字列が未設定の変数を参照している場合にE_NOTICEレベルのエラーを発行するようになりました。以前は、そのような文字列は黙ってスキップされていました。


興味深い選択肢。ただし、$ GLOBALSなどの既存の配列でarray_key_existsを呼び出すよりもおそらく遅いことに注意してください。これは、テーブルが大きくなり、の余分な作業を追加した場合でも、ハッシュテーブルでのルックアップが遅くなることはないためですcompact。それにもかかわらず、私はそれが1つの状況で役立つので、それを賛成しました:それがどこから来たかに関係なく、現在のコンテキストにfoo存在するかどうかを知りたい場合-ローカルかグローバルかを気にしない場合は、それが存在します。
toolmakerSteve 2017年

@ ToolmakerSteve-私は実際に呼び出しの潜在的に重大なオーバーヘッドについて言及していましたget_defined_vars。こちらをご覧ください
nzn 2017年

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

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


is_nullを使用しています。結果は、に関係なく同じissetです。
Tatu Ulmanen 2010

最初の回答を投稿しているときに間違えました:empty()で試しましたか?
Raveline 2010

1
これは、FALSE、0、array()、 ""など、空でもNULLでもない値では機能しません。
teaqu 2014

1
この答えは間違っています。is_nullと同じ問題がありis_setます:OPが抱えている問題である「未設定」と「nullに設定」を区別できません。emptyCalumが指摘するように、さらに悪いです。
toolmakerSteve 2017年

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
ロイックFévrier

2
これは、null以外の変数を渡しません(例:if $bar = "test")。
Tatu Ulmanen 2010

3
$ bar = nullの場合、isset()は「false」を返し、is_null()はtrueを返します。Falseとtrueは常にfalseを与えます。
Bartek Kosa

この答えは完全に間違っています。OPが言ったように、。のisset($bar)後でもfalseを返します$bar = null;
toolmakerSteve 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.