194

isset()文档

isset() will return FALSE if testing a variable that has been set to NULL.

基本上,isset()根本不检查变量是否已设置,但是否设置为NULL.

鉴于此,实际检查变量是否存在的最佳方法是什么?我试过类似的东西:

if(isset($v) || @is_null($v))

@有必要避免$v未设置时的警告)但is_null()有类似的问题isset():它返回未设置的TRUE变量!还可以看出:

@($v === NULL)

工作原理完全一样@is_null($v),所以也出来了。

我们应该如何可靠地检查 PHP 中变量的存在?


编辑:PHP中未设置的变量和设置为的变量之间显然存在差异NULL

<?php
$a = array('b' => NULL);
var_dump($a);

PHP表明$a['b']存在,并且具有NULL价值。如果添加:

var_dump(isset($a['b']));
var_dump(isset($a['c']));

你可以看到我正在谈论的isset()功能的歧义。这是所有这三个的输出var_dump()s

array(1) {
  ["b"]=>
  NULL
}
bool(false)
bool(false)

进一步编辑:两件事。

一,用例。将数组转换为 SQLUPDATE语句的数据,其中数组的键是表的列,数组的值是要应用于每一列的值。表的任何列都可以保存一个值,通过在数组中NULL传递一个值来表示。NULL需要一种方法来区分不存在的数组键和数组的值设置为NULL; 这就是不更新列的值和将列的值更新为NULL.

其次,对于我的上述用例和任何全局变量, Zoredache 的答案都可以正常工作:array_key_exists()

<?php
$a = NULL;
var_dump(array_key_exists('a', $GLOBALS));
var_dump(array_key_exists('b', $GLOBALS));

输出:

bool(true)
bool(false)

由于这可以正确处理几乎所有我可以看到不存在的变量和设置为的变量之间存在任何歧义,因此NULL调用array_key_exists()PHP 中最简单的官方方法来真正检查变量的存在

(我能想到的唯一其他情况是类属性,property_exists()根据它的文档,它的工作原理与它类似array_key_exists(),因为它正确区分了未设置和设置为NULL。)

4

17 回答 17

97

如果您要检查的变量在全局范围内,您可以这样做:

array_key_exists('v', $GLOBALS) 
于 2009-01-06T21:07:07.590 回答
48

试图概述各种讨论和答案:

这个问题没有一个单一的答案可以取代所有isset可以使用的方法。一些用例由其他功能解决,而另一些则经不起审查,或者具有超出代码高尔夫的可疑价值。其他用例远非“破碎”或“不一致”,而是说明了为什么isset对 的反应null是合乎逻辑的行为。

真实用例(带有解决方案)

1. 数组键

数组可以被当作变量的集合来对待,就像unset对待isset它们一样对待它们。但是,由于它们可以被迭代、计数等,缺失值与值为 的值不同null

在这种情况下,答案是使用array_key_exists()而不是isset().

由于这是将数组作为函数参数进行检查,因此如果数组本身不存在,PHP 仍会发出“通知”。在某些情况下,可以有效地争论每个维度应该首先被初始化,所以通知正在完成它的工作。array_key_exists对于其他情况,依次检查数组的每个维度的“递归”函数可以避免这种情况,但基本上与@array_key_exists. 它也与null值的处理有些相切。

2.对象属性

在传统的“面向对象编程”理论中,封装和多态是对象的关键属性;在 PHP 等基于类的 OOP 实现中,封装的属性被声明为类定义的一部分,并被赋予访问级别(publicprotectedprivate)。

但是,PHP 还允许您动态地向对象添加属性,就像您将键添加到数组一样,并且有些人以类似的方式使用无类对象(从技术上讲,内置的实例stdClass,它没有方法或私有功能)关联数组的方法。这会导致函数可能想知道是否已将特定属性添加到给定对象的情况。

与数组键一样,用于检查对象属性的解决方案包含在语言中,称为property_exists.

不合理的用例,有讨论

3. register_globals、全局命名空间等污染

register_globals功能将变量添加到全局范围,其名称由 HTTP 请求的各个方面(GET 和 POST 参数以及 cookie)确定。这可能会导致错误和不安全的代码,这就是为什么它自PHP 4.2(2000 年 8 月发布)以来默认禁用并在PHP 5.4(2012 年 3 月发布)中完全删除的原因。但是,某些系统可能在启用或模拟此功能的情况下仍在运行。global也可以使用关键字或$GLOBALS数组以其他方式“污染”全局命名空间。

首先,register_globals它本身不太可能意外产生null变量,因为 GET、POST 和 cookie 值将始终是字符串(''仍然返回truefrom isset),并且会话中的变量应该完全在程序员的控制之下。

其次,只有当这覆盖了一些先前的初始化时,变量与值的污染null才是一个问题。仅当其他地方的代码区分这两种状态时, “覆盖”未初始化的变量null才会有问题,因此这种可能性本身就是反对进行这种区分的论据。

4.get_defined_varscompact

PHP 中的一些很少使用的函数,例如get_defined_varsand compact,允许您将变量名视为数组中的键。对于全局变量,超全局数组$GLOBALS允许类似的访问,并且更常见。如果变量未在相关范围内定义,这些访问方法的行为将有所不同。

一旦您决定使用其中一种机制将一组变量视为一个数组,您就可以对其执行所有与任何普通数组相同的操作。因此,见 1。

仅用于预测这些函数将如何运行的功能(例如,“在返回的数组中是否会有一个键 'foo' get_defined_vars?”)是多余的,因为您可以简单地运行该函数并找出没有任何不良影响。

4a。变量变量 ( $$foo)

虽然与将一组变量转换为关联数组的函数并不完全相同,但大多数使用“变量变量”(“分配给基于此其他变量命名的变量”)的情况可以并且应该改为使用关联数组.

从根本上说,变量名是程序员赋予值的标签。如果您在运行时确定它,它实际上并不是一个标签,而是某个键值存储中的一个键。更实际的是,如果不使用数组,您将失去计数、迭代等的能力;也可能无法在键值存储“外部”拥有一个变量,因为它可能会被$$foo.

一旦更改为使用关联数组,代码将适用于解决方案 1。间接对象属性访问(例如$foo->$property_name)可以使用解决方案 2 解决。

5.isset比打字容易得多array_key_exists

我不确定这是否真的相关,但是是的,PHP 的函数名称有时会非常冗长且不一致。显然,PHP 的史前版本使用函数名的长度作为哈希键,所以 Rasmus 故意编造函数名,htmlspecialchars这样它们就会有不寻常的字符数......

不过,至少我们不是在写 Java,对吧?;)

6.未初始化的变量有类型

变量基础的手册页包括以下语句:

未初始化的变量具有其类型的默认值,具体取决于使用它们的上下文

我不确定 Zend 引擎中是否存在“未初始化但已知类型”的概念,或者这是否对声明的解读过多。

很明显,这对它们的行为没有实际影响,因为该页面上描述的未初始化变量的行为与值为 的变量的行为相同null。举一个例子,这段代码中的$a$b都以整数结尾42

unset($a);
$a += 42;

$b = null;
$b += 42;

(第一个会引发关于未声明变量的通知,试图让您编写更好的代码,但它不会对代码的实际运行方式产生任何影响。)

99. 检测函数是否运行

(最后保留这个,因为它比其他的要长得多。也许我稍后会编辑它......)

考虑以下代码:

$test_value = 'hello';
foreach ( $list_of_things as $thing ) {
    if ( some_test($thing, $test_value) ) {
        $result = some_function($thing);
    }
}
if ( isset($result) ) {
    echo 'The test passed at least once!';
}

如果some_function可以返回null,则有可能echo即使some_test返回也无法到达true。程序员的意图是检测何时$result从未设置,但 PHP 不允许他们这样做。

但是,这种方法还有其他问题,如果添加外部循环,这些问题就会变得清晰:

foreach ( $list_of_tests as $test_value ) {
    // something's missing here...
    foreach ( $list_of_things as $thing ) {
        if ( some_test($thing, $test_value) ) {
            $result = some_function($thing);
        }
    }
    if ( isset($result) ) {
        echo 'The test passed at least once!';
    }
}

因为$result从未显式初始化,所以当第一个测试通过时,它将采用一个值,因此无法判断后续测试是否通过。当变量没有正确初始化时,这实际上是一个非常常见的错误。

为了解决这个问题,我们需要在我评论说缺少某些东西的那一行做一些事情。最明显的解决方案是设置一个永远无法返回$result的“终端值” ;some_function如果是这样null,那么其余代码将正常工作。如果由于some_function具有极其不可预测的返回类型(这本身可能是一个不好的迹象)而没有自然的终端值候选者,那么可以使用额外的布尔值,例如$found,来代替。

思想实验一:very_null常数

PHP 理论上可以提供一个特殊的常量 - 以及null- 在这里用作终端值;据推测,从函数返回 this 是非法的,或者它会被强制转换为null,同样可能适用于将它作为函数参数传入。这将使这个非常具体的情况稍微简单一些,但是一旦您决定重构代码 - 例如,将内部循环放入单独的函数中 - 它就会变得无用。如果常量可以在函数之间传递,则不能保证some_function不会返回它,因此它不再用作通用终端值。

在这种情况下,用于检测未初始化变量的论点归结为该特殊常量的论点:如果将注释替换为unset($result),并将其与 区别对待$result = null,则您将引入一个“值”,$result因为它不能传递,只能由特定的内置函数检测到。

思想实验二:赋值计数器

思考最后一个if问题的另一种方式是“有什么任务$result吗?” 与其将其视为 的特殊值,不如将其视为有关$result变量的“元数据” ,有点像 Perl 的“变量污染”。所以不是你可能会调用它,而不是,。issethas_been_assigned_tounsetreset_assignment_state

但如果是这样,为什么要停在一个布尔值上?如果您想知道测试通过了多少次怎么办?您可以简单地将元数据扩展为整数并拥有get_assignment_countreset_assignment_count...

显然,添加这样的功能会在语言的复杂性和性能上进行权衡,因此需要仔细权衡其预期的有用性。与very_null常数一样,它仅在非常狭窄的情况下才有用,并且类似地抵抗重构。

希望显而易见的问题是,为什么 PHP 运行时引擎应该提前假设您想要跟踪这些事情,而不是让您使用普通代码明确地进行。

于 2013-09-05T21:52:07.150 回答
21

有时我在试图弄清楚在给定情况下使用哪种比较操作时会有点迷茫。isset()仅适用于未初始化或显式空值。传递/分配 null 是确保逻辑比较按预期工作的好方法。

尽管如此,考虑起来还是有点困难,所以这里有一个简单的矩阵,比较不同的值将如何被不同的操作评估:

|           | ===null | is_null | isset | empty | if/else | ternary | count>0 |
| -----     | -----   | -----   | ----- | ----- | -----   | -----   | -----   |
| $a;       | true    | true    |       | true  |         |         |         |
| null      | true    | true    |       | true  |         |         |         |
| []        |         |         | true  | true  |         |         |         |
| 0         |         |         | true  | true  |         |         | true    |
| ""        |         |         | true  | true  |         |         | true    |
| 1         |         |         | true  |       | true    | true    | true    |
| -1        |         |         | true  |       | true    | true    | true    |
| " "       |         |         | true  |       | true    | true    | true    |
| "str"     |         |         | true  |       | true    | true    | true    |
| [0,1]     |         |         | true  |       | true    | true    | true    |
| new Class |         |         | true  |       | true    | true    | true    |

为了适应表格,我稍微压缩了标签:

  • $a;指已声明但未赋值的变量
  • 第一列中的所有其他内容都指的是分配的值,例如:
    • $a = null;
    • $a = [];
    • $a = 0;
    • …</li>
  • 这些列指的是比较操作,例如:
    • $a === null
    • isset($a)
    • empty($a)
    • $a ? true : false
    • …</li>

所有结果都是布尔值,true被打印并被false省略。

你可以自己运行测试,检查这个要点:
https ://gist.github.com/mfdj/8165967

于 2013-12-29T07:05:53.657 回答
17

您可以使用紧凑的语言结构来测试是否存在空变量。结果中不会出现不存在的变量,而会显示空值。

$x = null;
$y = 'y';

$r = compact('x', 'y', 'z');
print_r($r);

// Output:
// Array ( 
//  [x] => 
//  [y] => y 
// ) 

在您的示例中:

if (compact('v')) {
   // True if $v exists, even when null. 
   // False on var $v; without assignment and when $v does not exist.
}

当然,对于全局范围内的变量,您也可以使用 array_key_exists()。

顺便说一句,我会避免像瘟疫这样的情况,即不存在的变量和具有空值的变量之间存在语义差异。PHP 和大多数其他语言只是认为没有。

于 2009-12-28T11:57:53.477 回答
15

解释NULL,逻辑思维

我想所有这一切的明显答案是......不要将您的变量初始化为NULL,将它们初始化为与它们打算成为的东西相关的东西。

正确对待NULL

NULL应该被视为“不存在的值”,这就是NULL的含义。该变量不能归类为 PHP 存在的变量,因为它没有被告知它试图成为什么类型的实体。它也可能不存在,所以 PHP 只是说“好吧,它不存在,因为它没有任何意义,而 NULL 是我的说法”。

一个论点

现在让我们争论。“但 NULL 就像说 0 或 FALSE 或 ''。

错误,0-FALSE-'' 仍然被归类为空值,但它们被指定为某种类型的值或问题的预定答案。FALSE是对是或否的答案,''是对某人提交的标题的答案,而0是对数量或时间等的答案。它们被设置为某种类型的答案/结果,这使得它们在设置时有效。

NULL 只是没有答案,它没有告诉我们是或否,它没有告诉我们时间,也没有告诉我们提交了一个空白字符串。这就是理解 NULL 的基本逻辑。

概括

这不是要创建古怪的函数来解决问题,它只是改变你的大脑看待 NULL 的方式。如果它是 NULL,假设它没有被设置为任何东西。如果您正在预定义变量,则根据您打算使用它们的类型将它们预定义为 0、FALSE 或“”。

随意引用这个。这超出了我的逻辑头脑:)

于 2010-03-31T10:13:18.697 回答
9

可以通过property_exists检查对象属性是否存在

来自单元测试的示例:

function testPropertiesExist()
{
    $sl =& $this->system_log;
    $props = array('log_id',
                   'type',
                   'message',
                   'username',
                   'ip_address',
                   'date_added');

    foreach($props as $prop) {
        $this->assertTrue(property_exists($sl, $prop),
                           "Property <{$prop}> exists");
    }
}
于 2009-01-24T12:35:01.213 回答
5

作为greatbigmassive 关于 NULL 含义的讨论的补充,请考虑“变量的存在”实际上意味着什么。

在许多语言中,您必须在使用每个变量之前显式声明它;这可能决定了它的类型,但更重要的是它声明了它的范围。一个变量“存在”在其范围内的任何地方,而在它之外的任何地方——无论是整个函数还是单个“块”。

在其范围内,变量为您(程序员)选择的标签赋予了某种意义。在其范围之外,该标签是没有意义的(在不同的范围内是否使用相同的标签基本上是无关紧要的)。

在 PHP 中,不需要声明变量——只要你需要它们,它们就会立即生效。当您第一次写入变量时,PHP 会在内存中为该变量分配一个条目。如果您从当前没有条目的变量中读取,PHP 会认为该变量具有 value NULL

但是,如果您使用变量而不首先“初始化”它,自动代码质量检测器通常会警告您。首先,这有助于检测拼写错误,例如分配给$thingId但读取自$thing_id; 但其次,它迫使您考虑该变量具有意义的范围,就像声明一样。

任何关心变量是否“存在”的代码都是该变量范围的一部分——无论它是否已被初始化,作为程序员的你已经在代码的那个点赋予了该标签的含义。既然你在使用它,它就必须在某种意义上“存在”,如果它存在,它就必须有一个隐含的价值;在 PHP 中,该隐含值为null.

由于 PHP 的工作方式,可以编写代码,将现有变量的名称空间不作为您赋予意义的标签范围,而是作为某种键值存储。例如,您可以运行如下代码:$var = $_GET['var_name']; $$var = $_GET['var_value'];. 仅仅因为你可以,并不意味着这是一个好主意。

事实证明,PHP 有一种更好的方式来表示键值存储,称为关联数组。尽管可以将数组的值视为变量,但您也可以对整个数组执行操作。如果你有一个关联数组,你可以使用array_key_exists().

您也可以以类似的方式使用对象,动态设置属性,在这种情况下,您可以property_exists()以完全相同的方式使用。当然,如果你定义了一个类,你可以声明它有哪些属性——你甚至可以在public,privateprotectedscope 之间进行选择。

尽管尚未初始化(或已显式)的变量(与数组键或对象属性相反)与值为 的变量之间存在技术差异,但任何认为该差异有意义的代码正在以不应该使用的方式使用变量。unset()null

于 2013-09-03T21:11:59.243 回答
4

isset检查变量是否已设置,如果是,则其是否不为 NULL。后一部分(在我看来)不在此功能的范围内。没有像样的解决方法来确定变量是 NULL是因为它没有设置还是因为它被显式设置为 NULL

这是一种可能的解决方案:

$e1 = error_get_last();
$isNULL = is_null(@$x);
$e2 = error_get_last();
$isNOTSET = $e1 != $e2;
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0

其他解决方法是探测以下输出get_defined_vars()

$vars = get_defined_vars();
$isNOTSET = !array_key_exists("x", $vars);
$isNULL = $isNOTSET ? true : is_null($x);
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0
于 2013-01-31T15:32:55.250 回答
2

我不同意你关于 NULL 的推理,并且说你需要改变你对 NULL 的心态是很奇怪的。

我认为 isset() 设计不正确, isset() 应该告诉您变量是否已设置并且它不应该关心变量的实际值。

如果您正在检查从数据库返回的值并且其中一列具有 NULL 值,即使该值为 NULL,您仍然想知道它是否存在......不,不要相信 isset() 在这里。

同样地

$a = array ('test' => 1, 'hello' => NULL);

var_dump(isset($a['test']));   // TRUE
var_dump(isset($a['foo']));    // FALSE
var_dump(isset($a['hello']));  // FALSE

isset() 应该被设计成这样工作:

if(isset($var) && $var===NULL){....

这样我们就让程序员来检查类型,而不是让 isset() 来假设它不存在,因为值为 NULL - 它只是愚蠢的设计

于 2011-01-28T15:48:40.510 回答
2

我要为此加两分钱。这个问题令人困惑的一个原因是因为这种情况似乎返回了相同的结果,但错误报告完全:

$a = null;
var_dump($a); // NULL
var_dump($b); // NULL

您可以从这个结果中假设,$a = null与根本没有定义之间的区别$b是什么。

曲柄错误报告:

NULL

Notice: Undefined variable: b in xxx on line n
NULL

注意:它抛出了一个未定义的变量错误,但输出值var_dump仍然是NULL.

PHP 显然确实具有区分空变量和未定义变量的内部能力。在我看来,应该有一个内置函数来检查这个。

我认为接受的答案在很大程度上是好的,但如果我要实现它,我会为它写一个包装器。正如前面在这个答案中提到的,我必须同意我实际上并没有遇到过这种问题的情况。我似乎几乎总是在我的变量被设置和定义的情况下结束,或者它们不是(未定义、未设置、空、空白等)。并不是说这样的情况将来不会发生,但由于这似乎是一个非常独特的问题,我并不感到惊讶 PHP 开发人员没有费心把它放进去。

于 2014-05-22T21:52:04.660 回答
1

如果我运行以下命令:

echo '<?php echo $foo; ?>' | php

我收到一个错误:

PHP Notice:  Undefined variable: foo in /home/altern8/- on line 1

如果我运行以下命令:

echo '<?php if ( isset($foo) ) { echo $foo; } ?>' | php

我没有得到错误。

如果我有一个应该设置的变量,我通常会执行以下操作。

$foo = isset($foo) ? $foo : null;

或者

if ( ! isset($foo) ) $foo = null;

这样,稍后在脚本中,我可以安全地使用 $foo 并知道它“已设置”,并且默认为 null。稍后,if ( is_null($foo) ) { /* ... */ }如果我需要并确定变量存在,即使它为空,我也可以。

完整的isset 文档比最初粘贴的内容要多一些。是的,它为先前设置但现在为 null 的变量返回 false,但如果尚未设置(曾经)变量以及已标记为未设置的任何变量,它也会返回 false。它还指出 NULL 字节 ("\0") 不被视为 null 并将返回 true。

确定是否设置了变量。

如果一个变量已经用 unset() 取消设置,它将不再被设置。如果测试已设置为 NULL 的变量,isset() 将返回 FALSE。另请注意,NULL 字节(“\0”)不等同于 PHP NULL 常量。

于 2009-01-06T21:00:42.627 回答
1

尝试使用

unset($v)

似乎唯一没有设置变量的时间是当它特别未设置($v)时。听起来您对“存在”的含义与 PHP 的定义不同。NULL肯定是存在的,它是NULL。

于 2009-01-06T22:17:20.630 回答
0

我不得不说,在我多年的 PHP 编程中,我从未遇到过isset()在 null 变量上返回 false 的问题。OTOH,我遇到isset()了空数组条目失败的问题-但array_key_exists()在这种情况下可以正常工作。

为了进行一些比较,Icon 明确定义了一个未使用的变量作为返回&null,因此您可以使用 Icon 中的 is-null 测试来检查未设置的变量。这确实使事情变得更容易。另一方面,Visual BASIC 对没有值的变量有多种状态(Null、Empty、Nothing,...),您经常需要检查其中的多个状态。众所周知,这是错误的来源。

于 2009-01-06T21:50:57.393 回答
0

根据 empty() 函数的 PHP 手册,“确定一个变量是否被认为是空的。如果一个变量不存在或者它的值等于 FALSE,那么它就被认为是空的。如果变量不存在。” (我的重点。)这意味着 empty() 函数应该符合“在 PHP 中测试变量存在的最佳方法”,根据标题问题。

但是,这还不够好,因为 empty() 函数可能会被确实存在并设置为 NULL 的变量所欺骗。

我打断了我之前的答案以提出更好的东西,因为它比我的原始答案(在此中断之后进行比较)更简单。

  function undef($dnc) //do not care what we receive
  { $inf=ob_get_contents();             //get the content of the buffer
    ob_end_clean();                     //stop buffering outputs, and empty the buffer
    if($inf>"")                         //if test associated with the call to this function had an output
    { if(false!==strpos($inf, "Undef"); //if the word "Undefined" was part of the output
        return true;                    //tested variable is undefined
    }
    return false;                       //tested variable is not undefined
  }

两行简单的代码可以使用上述函数来显示变量是否未定义:

  ob_start();                           //pass all output messages (including errors) to a buffer
  if(undef($testvar===null))            //in this case the variable being tested is $testvar

您可以在这两行之后添加任何适当的内容,例如以下示例:

    echo("variable is undefined");
  else
    echo("variable exists, holding some value");

我想将调用 ob_start() 和 ($testvar===null) 放在函数内部,然后简单地将变量传递给函数,但它不起作用。即使您尝试将变量“通过引用传递”给函数,变量也已被定义,然后函数永远无法检测到它以前未定义。这里展示的是我想要做的和实际工作之间的妥协。

前面暗示有另一种方法可以始终避免遇到“未定义变量”错误消息。(这里的假设是,阻止此类消息是您想要测试变量是否未定义的原因。)

   function inst(&$v) { return; }  //receive any variable passed by reference; instantiates the undefined

只需在对 $testvar 执行某些操作之前调用该函数:

   inst($testvar);                //The function doesn't affect any value of any already-existing variable

当然,新实例化的变量的值设置为 null!

(中断结束)

所以,经过一些研究和实验,这里有一些保证可以工作的东西:

 function myHndlr($en, $es, $ef, $el)
 { global $er;
   $er = (substr($es, 0, 18) == "Undefined variable");
   return;
 }

 $er = false;
 if(empty($testvar))
 { set_error_handler("myHndlr");
   ($testvar === null);
   restore_error_handler();
 }
 if($er)  // will be 1 (true) if the tested variable was not defined.
 { ; //do whatever you think is appropriate to the undefined variable
 }

解释:变量 $er 被初始化为默认值“无错误”。定义了“处理函数”。如果 $testvar(我们想知道是否未定义的变量)通过了初步的 empty() 函数测试,那么我们进行更彻底的测试。我们调用 set_error_handler() 函数来使用之前定义的处理函数。然后我们做一个涉及 $testvar 的简单身份比较,如果未定义将触发错误。处理函数捕获错误并专门测试以查看错误的原因是否是变量未定义的事实。结果被放置在错误信息变量 $er 中,我们可以稍后测试它以执行我们想要的任何操作,因为确定是否定义了 $testvar。因为我们只需要处理函数来达到这个有限的目的,所以我们恢复了原来的错误处理函数。“myHndlr”函数只需要声明一次;其他代码可以复制到任何合适的地方,对于 $testvar 或我们想要以这种方式测试的任何其他变量。

于 2014-05-22T06:10:39.717 回答
0

我认为唯一的完整解决方案是报告通知

error_reporting(E_ALL); // Enables E_NOTICE

但是您必须修复由未定义变量、常量、数组键、类属性等生成的所有通知。一旦你这样做了,你就不必担心空变量和未声明变量之间的区别,并且歧义消失了。

在所有情况下启用通知报告可能不是一个好的选择,但启用它有充分的理由:

为什么要修复 E_NOTICE 错误?

在我的情况下,在没有它的情况下在项目中工作了一年多,但习惯于在声明变量时小心翼翼,因此过渡很快。

于 2015-05-29T17:50:22.480 回答
0

知道变量是否在当前范围内定义($GLOBALS不可信)的唯一方法是array_key_exists( 'var_name', get_defined_vars() ).

于 2017-02-01T14:34:35.390 回答
-1

我更喜欢使用 not empty 作为检查 a) 存在且 b) 不为 null 的变量是否存在的最佳方法。

if (!empty($variable)) do_something();
于 2011-03-07T22:28:42.133 回答