PHP 未定义常量测试
在 PHP 中,如果我定义这样的常量:
define('FOO', true);
if(FOO) do_something();
方法 do_something
将按预期执行。
但如果我没有定义下面的 BOO
常量:
if(BOO) do_something();
那么 do_something
也会被执行。这是怎么回事?
In PHP if I define a constant like this:
define('FOO', true);
if(FOO) do_something();
The method do_something
gets executed as expected.
But if I don't define the BOO
constant below:
if(BOO) do_something();
Then do_something
also gets executed. What's going on here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
BOO
将被强制转换为字符串BOO
,该字符串不为空,因此它是 true。这就是为什么有些不了解的人会使用
$something[a]
访问数组成员。您应该使用
error_reporting(E_ALL)
进行编码,然后它会给您...您可以查看它是否是用
define()
定义的。很多人使用以下行,因此在其环境之外访问的 PHP 文件将无法运行...这利用了 短路评估 - 如果左侧为真,则不需要运行右侧。
BOO
will be coerced into the stringBOO
, which is not empty, so it is truthy.This is why some people who don't know better access an array member with
$something[a]
.You should code with
error_reporting(E_ALL)
which will then give you...You can see if it is defined with
defined()
. A lot of people use the following line so a PHP file accessed outside of its environment won't run...This exploits short circuit evaluation - if the left hand side is true, then it doesn't need to run the right hand side.
如果启用错误日志记录,您将看到如下错误:
发生的情况是 PHP 只是任意假设您打算使用“BOO”而只是忘记了引号。由于
''
和'0'
之外的字符串被视为“true”,因此条件通过。If you enable error logging, you'll see an error like the following:
What's happening is that PHP is just arbitrarily assuming that you meant to use 'BOO' and just forgot the quotes. And since strings other than
''
and'0'
are considered "true", the condition passes.如果不是您要测试的常量是否存在,但如果您想测试您定义的常量的值,这可能是更好的方法:
if(BOO === true)
或if(BOO === false)
If it's not the existance of the constant you want to test, but if you want to test the value of the constant you defined, this might be a better way:
if(BOO === true)
orif(BOO === false)
仅使用 FOO 会将其视为一个值而不是您定义的变量。最好使用 PHP 的 定义。
Just using FOO takes it as a value rather than the variable you defined. Better to use PHP's defined.
PHP 是动态类型的。您可以使用如下函数来实现您想要做的事情:
PHP is dynamically typed. You can achieve what you're trying to do with a function such as this:
PHP 会自动猜测您指的是字符串格式,字符串将返回 true。
但是,您应该使用定义的方法:
所以它是:
PHP will automatically make the guess that you meant the string format, which a string will return true.
However you should use the defined method:
So it would be:
另一种选择是使用 php 的
constant()
函数,如下所示:记住将常量名称括在引号中。
这是一个 PHP replit 演示以下示例。
根据 php 文档,如果定义了常量,则其值被退回;否则,返回
null
。由于
null
为 false,因此这将按预期运行。当您需要知道某些内容是否显式定义为 true(或至少一个 true 值)与未定义或定义为 false 值的情况下,可以使用此方法。当定义变量是例外,或者未定义变量可能存在安全风险时,这种方法特别有效。
检查变量时使用
constant()
是减轻某些情况下安全风险的好习惯。例如,仅当某个常量(已定义且)为 TRUE 时才打印 php 信息。正如您的问题所示,如果常量未定义,PHP 的字符串转换将暴露详细信息。
或者,您可以:
另一种可行的方法是使用
===
或!==
,它测试完全相等(包括类型),而不执行类型转换。Another option is to use php's
constant()
function, as in:Remember to enclose the constant's name in quotes.
Here is a PHP replit demonstrating the examples below.
Ap per the php docs, if the constant is defined, its value is returned; otherwise,
null
is returned.Since
null
is falsey, this will behave as expected.This can be used in cases where you need to know if something is explicitly defined as
true
(or at lease a truthy value) vs either not defined, or defined with a falsey value. This works particularly well when having a variable defined is the exception, or having it undefined could be a security risk.Using
constant()
when checking against variables is a good practice to mitigate against security risks in certain situations. For example, printing out php info only if a certain constant is (defined and) TRUE.As your question shows, PHP's string conversion would expose details if somehow the constant did not get defined.
Alternately, you could:
Another method that would work is to use
===
or!==
, which tests exact equality (including type), without performing typecast a conversion.