Değerin ayarlanmış ve boş olup olmadığını kontrol edin


90

Değerin null dahil herhangi bir şey olarak tanımlanıp tanımlanmadığını kontrol etmem gerekiyor. issetboş değerleri tanımsız olarak değerlendirir ve döndürür false. Aşağıdakileri bir örnek olarak ele alalım:

$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

Bunun $bartanımsız olduğuna dikkat edin .

Aşağıdakileri karşılayan bir koşul bulmam gerekiyor:

if(something($bar)) // returns false;
if(something($foo)) // returns true;

Herhangi bir fikir?


20
if (isset ($ foo)) // false döndürür, sandalyeden düştüm, bunca yıl ...
max4ever

in_array ($ key, array_keys ($ _ SESSION)) && is_null ($ _ SESSION [$ key]) Bunu çok uzun zamandır merak ediyordum ..
Jack

1
Bu benim için normal bir davranış değil, isset= ayarlandı mı?, Değişkeniniz null olarak ayarlanmış. Bunun yüzünden çok zaman harcadım ...
Vincent Decaux

Yanıtlar:


85

IIRC, get_defined_vars()bunun için kullanabilirsiniz :

$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 Aynı işlevi önerecektim, get_defined_varskapsamla mutlu bir şekilde başa çıkıyor.
salate

1
Çalışıyor gibi görünüyor, ama daha basit bir şey umuyordum. Oh iyi. Bakalım biri tek astar bulabilecek mi?
Tatu Ulmanen

4
pekala, değişkene ihtiyacınız yok, bu yüzden teoride tek satırlık "if (array_key_exists ('foo', get_defined_vars ())) {}"
Hannes

fvn en yeni cevap , mevcut bağlamda var olan bir değişkeni almak için daha hızlı bir yol olabilir maliyeti kaçınarak arasında get_defined_vars(): array_key_exists('foo', compact('foo')). Ya daha hızlı, küresel test edin: array_key_exists('foo', $GLOBALS).
ToolmakerSteve

25

NULL değerine sahip olabilen nesne özellikleriyle uğraşıyorsanız, property_exists()bunun yerine şunu kullanabilirsiniz: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();

?>

İsset () ile tersine, property_exists () özelliği NULL değerine sahip olsa bile TRUE döndürür.


11
Array_key_exists () ile diziler için aynısını yapabilirsiniz;
teaqu

14

PHP'de bir değişkenin varlığını test etmenin en iyi yoluna bakın ; isset () açıkça bozuk

 if( array_key_exists('foo', $GLOBALS) && is_null($foo)) // true & true => true
 if( array_key_exists('bar', $GLOBALS) && is_null($bar)) // false &  => false

3
Alıntı yaptığınız kod yalnızca değişken genel kapsamda ise çalışır.
Raveline

Gerçekten ama en sık görülen durum değil mi? Bir işlevde, genel kapsamda değişkenlere ve bağımsız değişkenlere (her zaman tanımlanmış olan) sahip olursunuz. Nesne özelliklerine de sahip olabilirsiniz, ancak daha sonra 'property_exists'i kullanabilirsiniz.
Loïc Février

$ GLOBALS kullanmak biraz uçucu görünüyor, bunun çalıştığını ilan etmeden önce kendim bazı testler yapmam gerekiyor.
Tatu Ulmanen

4

Bunun, compactayarlanmayan değişkenleri yok sayan, ancak ayarlanmış olanlara göre hareket eden bir işlev olduğunu buldum null, bu nedenle büyük bir yerel sembol tablonuz olduğunda array_key_exists('foo', get_defined_vars()), aşağıdakileri kullanarak kontrol yerine daha verimli bir çözüm elde edebileceğinizi hayal ederim 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

Güncelleme

PHP 7.3'ten itibaren compact () ayarlanmayan değerler için bir uyarı verecektir, bu nedenle maalesef bu alternatif artık geçerli değildir.

compact () artık eğer belirli bir dizge bir unset değişkenine başvuruyorsa E_NOTICE seviyesinde bir hata verir. Eskiden bu tür dizeler sessizce atlanırdı.


İlginç bir alternatif. Ancak bunun, $ GLOBALS gibi var olan bir dizide array_key_exists'i çağırmaktan muhtemelen daha yavaş olduğunu unutmayın - çünkü bir karma tablodaki bir arama daha yavaş olmaz, tablo büyüdüğünde ve ek işini eklediniz compact. Yine de, bunu bir durumda faydalı olduğu için ekledim: Nereden geldiğine bakılmaksızın mevcut bağlamdafoo var olup olmadığını bilmek istiyorsanız - yerel mi yoksa küresel mi olduğunu umursamıyorsanız, sadece bunun olup olmadığını bilmek isteyin. var.
ToolmakerSteve

@ToolmakerSteve - Aslında aramayla ilgili potansiyel olarak önemli ek yükten bahsediyordum get_defined_vars. Buraya bakın .
nzn

1

PHP uzantısı olarak yazılan aşağıdaki kod array_key_exists ($ name, get_defined_vars ()) ile eşdeğerdir (Henrik ve Hannes sayesinde).

// 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

İsset () yerine is_null ve boş kullanabilirsiniz . Değişken yoksa Empty bir hata mesajı yazdırmaz.


İs_null kullanıyorum. Sonuç ne olursa olsun aynıdır isset.
Tatu Ulmanen

İlk cevabımı gönderirken bir hata yaptım: boş () ile denediniz mi?
Raveline

1
Bu, FALSE, 0, array () veya "" gibi boş olmayan ve NULL olmayan değerler için çalışmaz.
teaqu

1
Bu cevap yanlış. is_nullaynı sorun is_seto "belirtilmedi" ve problem OP sahiptir "null seti", ayırt edemez. emptyCalum'un işaret ettiği gibi daha da kötü.
ToolmakerSteve

0

Burada xdebug kullanarak bazı aptalca geçici çözümler. ;-)

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
Çok taşınabilir görünmüyor .. :)
Tatu Ulmanen

-3

is_null($bar)hiç değeri olmadığı için true döndürür. Alternatif olarak şunları kullanabilirsiniz:

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

$bartanımlı olup olmadığını kontrol etmek için ve yalnızca aşağıdaki durumlarda doğru döndürür:

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

Hayır, bunun if(isset($bar))ne zaman yanlış olduğunu söyledi $bar = null.
Loïc Février

2
Bu, null dışında herhangi bir değişken geçirmez (örn. Eğer $bar = "test").
Tatu Ulmanen

3
$ Bar = null isset () olduğunda "false", is_null () ise true döndürür. Yanlış ve doğru her zaman yanlış verir.
Bartek Kosa

Bu cevap tamamen yanlış. OP'nin dediği gibi, isset($bar)sonrasında bile yanlış döndürür $bar = null;.
ToolmakerSteve
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.