PHP 未定义常量测试

发布于 2024-10-26 14:49:42 字数 284 浏览 1 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

但可醉心 2024-11-02 14:49:42
// BOO has not been defined

if(BOO) do_something();

BOO 将被强制转换为字符串 BOO,该字符串不为空,因此它是 true。

这就是为什么有些不了解的人会使用 $something[a] 访问数组成员。

您应该使用 error_reporting(E_ALL) 进行编码,然后它会给您...

注意:使用未定义的常量 HELLO - 在 /t.php 第 5 行中假设为“HELLO”

您可以查看它是否是用 define() 定义的。很多人使用以下行,因此在其环境之外访问的 PHP 文件将无法运行...

<?php defined('APP') OR die('No direct access');

这利用了 短路评估 - 如果左侧为真,则不需要运行右侧。

// BOO has not been defined

if(BOO) do_something();

BOO will be coerced into the string BOO, 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...

Notice: Use of undefined constant HELLO - assumed 'HELLO' in /t.php on line 5

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

<?php defined('APP') OR die('No direct access');

This exploits short circuit evaluation - if the left hand side is true, then it doesn't need to run the right hand side.

不交电费瞎发啥光 2024-11-02 14:49:42

如果启用错误日志记录,您将看到如下错误:

PHP 注意:使用未定义的常量 BOO - 假设文件中的第 N 行为“BOO”

发生的情况是 PHP 只是任意假设您打算使用“BOO”而只是忘记了引号。由于 '''0' 之外的字符串被视为“true”,因此条件通过。

If you enable error logging, you'll see an error like the following:

PHP Notice: Use of undefined constant BOO - assumed 'BOO' in file at line N

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.

所有深爱都是秘密 2024-11-02 14:49:42

如果不是您要测试的常量是否存在,但如果您想测试您定义的常量的值,这可能是更好的方法: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) or if(BOO === false)

日暮斜阳 2024-11-02 14:49:42
if($FOO) do_something(); 

仅使用 FOO 会将其视为一个值而不是您定义的变量。最好使用 PHP 的 定义

if($FOO) do_something(); 

Just using FOO takes it as a value rather than the variable you defined. Better to use PHP's defined.

青春如此纠结 2024-11-02 14:49:42

PHP 是动态类型的。您可以使用如下函数来实现您想要做的事情:

function consttrue($const) {
    return !defined($const) ? false : constant($const);
}

PHP is dynamically typed. You can achieve what you're trying to do with a function such as this:

function consttrue($const) {
    return !defined($const) ? false : constant($const);
}
成熟的代价 2024-11-02 14:49:42

PHP 会自动猜测您指的是字符串格式,字符串将返回 true。

但是,您应该使用定义的方法

布尔定义(字符串$name)

所以它是:

if(defined('BOO')) {\\code }

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:

bool defined ( string $name )

So it would be:

if(defined('BOO')) {\\code }
浅唱ヾ落雨殇 2024-11-02 14:49:42

另一种选择是使用 php 的 constant() 函数,如下所示:

if (constant('BOO')) doSomething();

记住将常量名称括在引号中。

这是一个 PHP replit 演示以下示例。

根据 php 文档,如果定义了常量,则其值被退回;否则,返回null

由于 null 为 false,因此这将按预期运行。
当您需要知道某些内容是否显式定义为 true(或至少一个 true 值)与未定义或定义为 false 值的情况下,可以使用此方法。当定义变量是例外,或者未定义变量可能存在安全风险时,这种方法特别有效。

if (constant('IS_DEV')) {
  // *Remember to enclose the constant's name in quotes.*
  // do stuff that should only happen in a dev environment
  // By Default, if it didn't get defined it is, as though, 'false'
}

检查变量时使用 constant() 是减轻某些情况下安全风险的好习惯。例如,仅当某个常量(已定义且)为 TRUE 时才打印 php 信息。
正如您的问题所示,如果常量未定义,PHP 的字符串转换将暴露详细信息。

或者,您可以:

if (defined('IS_DEV') && (IS_DEV)) {
  // *Remember to enclose the constant's name in quotes for the FIRST operator.*
  // do stuff that should only happen in a dev environment
}

另一种可行的方法是使用 ===!==,它测试完全相等(包括类型),而不执行类型转换。

if (IS_DEV === true)) {
  // do stuff that should only happen in a dev environment
}

Another option is to use php's constant() function, as in:

if (constant('BOO')) doSomething();

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.

if (constant('IS_DEV')) {
  // *Remember to enclose the constant's name in quotes.*
  // do stuff that should only happen in a dev environment
  // By Default, if it didn't get defined it is, as though, 'false'
}

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:

if (defined('IS_DEV') && (IS_DEV)) {
  // *Remember to enclose the constant's name in quotes for the FIRST operator.*
  // do stuff that should only happen in a dev environment
}

Another method that would work is to use === or !==, which tests exact equality (including type), without performing typecast a conversion.

if (IS_DEV === true)) {
  // do stuff that should only happen in a dev environment
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文