2010-09-27 111 views
65

我需要檢查值是否被定義爲任何值,包括null。 isset將空值視爲未定義,並返回false。以下列爲例:檢查值是否爲null並且爲空

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

任何想法?

+14

如果(isset($ FOO))//返回false,我掉下了椅子上,這些年來... – max4ever 2012-09-21 13:42:24

回答

63

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 
+0

+1我打算提出相同的函數,'get_defined_vars'愉快地處理範圍。 – salathe 2010-09-27 12:00:04

+1

似乎工作,但我希望更簡單。好吧。讓我們看看是否有人能夠拿出一個班輪。 – 2010-09-27 12:13:05

+4

好吧,你不需要變量,所以理論上它的一行「if(array_key_exists('foo',get_defined_vars())){}」 – Hannes 2010-09-27 12:47:37

0

您可以使用is_nullempty而不是isset()。如果變量不存在,Empty不會打印錯誤消息。

+0

我使用is_null。無論isset是什麼結果都是一樣的。 – 2010-09-27 11:27:43

+0

發佈我的第一個答案時發生了錯誤:您是否嘗試使用空()? – Raveline 2010-09-27 11:32:04

+0

對於非空且不爲NULL的值(例如FALSE,0,array()或「」),這不起作用。 – C9HDN 2014-02-26 15:22:18

12

Best way to test for a variable's existence in PHP; isset() is clearly broken

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-09-27 11:33:08

+0

的確,但這不是最常見的情況嗎?在一個函數中,你將在全局作用域和參數(總是定義的)上有變量。你也可以擁有對象屬性,但你可以使用'property_exists'。 – 2010-09-27 11:37:54

+0

使用$ GLOBALS似乎有點不穩定,我必須先自己做一些測試,然後才能聲明這是工作。 – 2010-09-27 12:14:38

-2

is_null($bar)返回true,因爲它沒有任何價值可言。或者,你可以使用:

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

檢查$bar定義,如果只返回true:

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

不,他說'if(isset($ bar))'在'$ bar = null'時給出false。 – 2010-09-27 11:32:07

+0

我的不好。將更新我的答案。 – Ruel 2010-09-27 11:57:40

+2

這不會傳遞任何其他變量而不是null(例如,如果'$ bar =「test」')。 – 2010-09-27 12:08:06

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

看起來不很便攜.. :) – 2010-09-27 12:09:15

+1

確實。性能也可能下降。 ;-) – 2010-09-29 17:28:19

1

寫成PHP擴展下面的代碼就相當於array_key_exists($名,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; 
    } 

} 
21

如果你正在處理whcih可能有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。

+7

你可以對array_key_exists(); – C9HDN 2014-02-26 15:40:02

2

我發現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 
+0

有趣的選擇。但是請注意,它可能比在現有數組上調用array_key_exists慢,比如$ GLOBALS - 因爲哈希表中的查找不會變慢,當表變大時,並且添加了額外的工作'compact'。儘管如此,我還是喜歡它,因爲它在一種情況下很有用:如果您想知道當前上下文中是否存在* foo *,無論它來自哪裏 - 如果您不在乎是本地還是全局,只是想知道它是否存在。 – ToolmakerSteve 2017-01-09 22:27:22

+0

@ToolmakerSteve - 我實際上是指調用'get_defined_vars'的潛在重要開銷。見[這裏](http://stackoverflow.com/questions/27808704/what-is-the-performance-impact-off-get-defined-vars)。 – nzn 2017-01-10 13:42:37