为什么'define()||定义常量时的define()'语法

时间:2022-07-21 17:03:08

Why is this method of checking if a constant exist before defining it:

为什么这种方法在定义常量之前检查是否存在常量:

defined('CONSTANT') || define('CONSTANT', somedefinition);

used instead of:

用来代替:

if !(defined('CONSTANT')) {
    define('CONSTANT', somedefinition);
}

Is there any difference in using 'or' instead of '||' in the first method, I have seen both in books.

使用'或'代替'||'有什么区别吗在第一种方法中,我已经在书中看到过。

4 个解决方案

#1


8  

Due to the || being (in C, Java, C#, php) being "short-circuited" (if the first operand is true, the second is not evaluated because the expression has already been evaluated to be true, no matter what the second is.

由于||存在(在C,Java,C#,php中)被“短路”(如果第一个操作数为真,则第二个操作数未被评估,因为表达式已被评估为真,无论第二个是什么。

So this is classic C-style "brevity" in action. Use as fewer lines of code as possible, even though its doing exactly the same as something more longhand.

所以这是经典的C风格“简洁”。使用尽可能少的代码行,即使它与更长的代码完全相同。

So it reads: if defined(...), don't do the define() bit... if not defined(), do try to evaluate the define() bit and in the process, it'll define the constant.

所以它读取:如果定义(...),不要执行define()位...如果没有定义(),请尝试评估define()位,并在此过程中,它将定义常量。

#2


4  

Others have answered first part of your question, so I'll take the latter:

其他人回答了你问题的第一部分,所以我会采取后者:

As far as or vs || is concerned there is no difference in this specific case. However, or has lower operator precedence than = (assignment operator), while || has higher. This is significant, if you want to use short-circuiting to do assignment.

至于或vs ||关注这个具体案例没有区别。但是,或者运算符优先级低于=(赋值运算符),而||有更高的。如果您想使用短路来进行分配,这很重要。

Consider:

考虑:

$a = 2 or $b = 2;
var_dump($a);  // int(2)


$a = 3 || $b = 3;
var_dump($a);  // bool(true)

In second example, || got evaluated before =. Using parentheses it would look like this

在第二个例子中,||在=之前得到评估。使用括号,它看起来像这样

$a = (3 || $b = 3);

while the first one

而第一个

($a = 2) or ($b = 2);

#3


3  

defined('CONSTANT') || define('CONSTANT', somedefinition);

Is actually a bit of a trick. You see, the || operator only executes the second part of the expression when the first part is false :) It's a quick, short way to write the same functioning code.

实际上有点诡计。你看,||当第一部分为false时,operator仅执行表达式的第二部分:)这是编写相同功能代码的快速,简短的方法。

#4


1  

So my assumption is the short circuit is faster, since the if statement is taking the boolean value from defined and flipping it using a not operator, but just to be thorough, here's my benchmark testing:

所以我的假设是短路更快,因为if语句从定义中取出布尔值并使用not运算符翻转它,但只是为了彻底,这是我的基准测试:


PHP 5.6:

0.23026204109192 - Test1a: Short circuit: Dynamic define on first loop.
0.22264909744263 - Test1b: If Statement: Dynamic define on first loop.
0.22433304786682 - Test2a: Short circuit: Static define before test is run.
0.22339177131653 - Test2b: If Statement: Static define before test is run.
0.27459692955017 - Test3a: Short circuit: Never define variable.
0.28696393966675 - Test3b: If Statement: Never define variable.

0.23026204109192 - Test1a:短路:第一次循环动态定义。 0.22264909744263 - Test1b:如果语句:动态定义第一个循环。 0.22433304786682 - Test2a:短路:运行测试前的静态定义。 0.22339177131653 - Test2b:如果语句:静态在运行测试之前定义。 0.27459692955017 - Test3a:短路:从不定义变量。 0.28696393966675 - Test3b:If Statement:从不定义变量。

Conclusion
Too close to tell, though we can see a noticeable speed improvement for short circuit if the variable is never defined.

结论太接近了,但如果从未定义变量,我们可以看到短路速度有明显改善。


PHP 7:

0.031289100646973 - Test1a: Short circuit: Dynamic define on first loop.
0.041652917861938 - Test1b: If Statement: Dynamic define on first loop.
0.023349046707153 - Test2a: Short circuit: Static define before test is run.
0.052791118621826 - Test2b: If Statement: Static define before test is run.
0.064755916595459 - Test3a: Short circuit: Never define variable.
0.056003093719482 - Test3b: If Statement: Never define variable.

0.031289100646973 - Test1a:短路:第一次循环动态定义。 0.041652917861938 - Test1b:如果语句:动态定义第一个循环。 0.023349046707153 - Test2a:短路:运行测试前的静态定义。 0.052791118621826 - Test2b:如果语句:静态在运行测试之前定义。 0.064755916595459 - Test3a:短路:从不定义变量。 0.056003093719482 - Test3b:If语句:从不定义变量。

Conclusion PHP 7 clearly optimizes for the short circuit in the case of constants/defined variables, though we see the opposite if the constant is never defined. This implies that checking for constants that actually exist has been dramatically improved, making it easier to see the extra processing that is required by the added not operator in the if statement.

结论PHP 7在常量/定义变量的情况下明显优化了短路,但是如果从未定义常量,我们会看到相反的情况。这意味着检查实际存在的常量已经大大改进,使得更容易看到if语句中添加的not运算符所需的额外处理。

Overall Conclusion

The difference is negligible (unless you're getting into the millions of loads of the same line of code) so use whatever makes the most sense for you and your team.

差异可以忽略不计(除非你进入同一行代码的数百万个负载),所以使用对你和你的团队最有意义的东西。

Also, man, PHP7 smokes PHP 6.5 in terms of performance of these tests!

另外,男人,PHP7在这些测试的性能方面抽了PHP 6.5!


Code:

$c1a=0;
$title1a = 'Test1a: Short circuit: Dynamic define on first loop.';
$c1b=0;
$title1b = 'Test1b: If Statement: Dynamic define on first loop.';

$c2a=0;
$title2a = 'Test2a: Short circuit: Static define before test is run.';
$c2b=0;
$title2b = 'Test2b: If Statement: Static define before test is run.';

$c3a=0;
$title3a = 'Test3a: Short circuit: Never define variable.';
$c3b=0;
$title3b = 'Test3b: If Statement: Never define variable.';

$start1a = microtime(true);
while ($c1a < 1000000) {
  ++$c1a;
  defined('TEST_CONST_1A') || define('TEST_CONST_1A', 'test');
}
$stop1a = microtime(true);

$start1b = microtime(true);
while ($c1b < 1000000) {
  ++$c1b;
  if (!defined('TEST_CONST_1B')) {
    define('TEST_CONST_1B', 'test');
  }
}
$stop1b = microtime(true);

define('TEST_CONST_2A', 'test');
$start2a = microtime(true);
while ($c2a < 1000000) {
  ++$c2a;
  defined('TEST_CONST_2A') || define('TEST_CONST_2A', 'test');
}
$stop2a = microtime(true);

define('TEST_CONST_2B', 'test');
$start2b = microtime(true);
while ($c2b < 1000000) {
  ++$c2b;
  if (!defined('TEST_CONST_2B')) {
    define('TEST_CONST_2B', 'test');
  }
}
$stop2b = microtime(true);

$start3a = microtime(true);
while ($c3a < 1000000) {
  ++$c3a;
  defined('TEST_CONST_3A') || $c3a;
}
$stop3a = microtime(true);

$start3b = microtime(true);
while ($c3b < 1000000) {
  ++$c3b;
  if (!defined('TEST_CONST_3B')) {
    $c3b;
  }
}
$stop3b = microtime(true);

print ($stop1a - $start1a) . ' - ' . $title1a . "\n";
print ($stop1b - $start1b) . ' - ' . $title1b . "\n";
print ($stop2a - $start2a) . ' - ' . $title2a . "\n";
print ($stop2b - $start2b) . ' - ' . $title2b . "\n";
print ($stop3a - $start3a) . ' - ' . $title3a . "\n";
print ($stop3b - $start3b) . ' - ' . $title3b . "\n";

#1


8  

Due to the || being (in C, Java, C#, php) being "short-circuited" (if the first operand is true, the second is not evaluated because the expression has already been evaluated to be true, no matter what the second is.

由于||存在(在C,Java,C#,php中)被“短路”(如果第一个操作数为真,则第二个操作数未被评估,因为表达式已被评估为真,无论第二个是什么。

So this is classic C-style "brevity" in action. Use as fewer lines of code as possible, even though its doing exactly the same as something more longhand.

所以这是经典的C风格“简洁”。使用尽可能少的代码行,即使它与更长的代码完全相同。

So it reads: if defined(...), don't do the define() bit... if not defined(), do try to evaluate the define() bit and in the process, it'll define the constant.

所以它读取:如果定义(...),不要执行define()位...如果没有定义(),请尝试评估define()位,并在此过程中,它将定义常量。

#2


4  

Others have answered first part of your question, so I'll take the latter:

其他人回答了你问题的第一部分,所以我会采取后者:

As far as or vs || is concerned there is no difference in this specific case. However, or has lower operator precedence than = (assignment operator), while || has higher. This is significant, if you want to use short-circuiting to do assignment.

至于或vs ||关注这个具体案例没有区别。但是,或者运算符优先级低于=(赋值运算符),而||有更高的。如果您想使用短路来进行分配,这很重要。

Consider:

考虑:

$a = 2 or $b = 2;
var_dump($a);  // int(2)


$a = 3 || $b = 3;
var_dump($a);  // bool(true)

In second example, || got evaluated before =. Using parentheses it would look like this

在第二个例子中,||在=之前得到评估。使用括号,它看起来像这样

$a = (3 || $b = 3);

while the first one

而第一个

($a = 2) or ($b = 2);

#3


3  

defined('CONSTANT') || define('CONSTANT', somedefinition);

Is actually a bit of a trick. You see, the || operator only executes the second part of the expression when the first part is false :) It's a quick, short way to write the same functioning code.

实际上有点诡计。你看,||当第一部分为false时,operator仅执行表达式的第二部分:)这是编写相同功能代码的快速,简短的方法。

#4


1  

So my assumption is the short circuit is faster, since the if statement is taking the boolean value from defined and flipping it using a not operator, but just to be thorough, here's my benchmark testing:

所以我的假设是短路更快,因为if语句从定义中取出布尔值并使用not运算符翻转它,但只是为了彻底,这是我的基准测试:


PHP 5.6:

0.23026204109192 - Test1a: Short circuit: Dynamic define on first loop.
0.22264909744263 - Test1b: If Statement: Dynamic define on first loop.
0.22433304786682 - Test2a: Short circuit: Static define before test is run.
0.22339177131653 - Test2b: If Statement: Static define before test is run.
0.27459692955017 - Test3a: Short circuit: Never define variable.
0.28696393966675 - Test3b: If Statement: Never define variable.

0.23026204109192 - Test1a:短路:第一次循环动态定义。 0.22264909744263 - Test1b:如果语句:动态定义第一个循环。 0.22433304786682 - Test2a:短路:运行测试前的静态定义。 0.22339177131653 - Test2b:如果语句:静态在运行测试之前定义。 0.27459692955017 - Test3a:短路:从不定义变量。 0.28696393966675 - Test3b:If Statement:从不定义变量。

Conclusion
Too close to tell, though we can see a noticeable speed improvement for short circuit if the variable is never defined.

结论太接近了,但如果从未定义变量,我们可以看到短路速度有明显改善。


PHP 7:

0.031289100646973 - Test1a: Short circuit: Dynamic define on first loop.
0.041652917861938 - Test1b: If Statement: Dynamic define on first loop.
0.023349046707153 - Test2a: Short circuit: Static define before test is run.
0.052791118621826 - Test2b: If Statement: Static define before test is run.
0.064755916595459 - Test3a: Short circuit: Never define variable.
0.056003093719482 - Test3b: If Statement: Never define variable.

0.031289100646973 - Test1a:短路:第一次循环动态定义。 0.041652917861938 - Test1b:如果语句:动态定义第一个循环。 0.023349046707153 - Test2a:短路:运行测试前的静态定义。 0.052791118621826 - Test2b:如果语句:静态在运行测试之前定义。 0.064755916595459 - Test3a:短路:从不定义变量。 0.056003093719482 - Test3b:If语句:从不定义变量。

Conclusion PHP 7 clearly optimizes for the short circuit in the case of constants/defined variables, though we see the opposite if the constant is never defined. This implies that checking for constants that actually exist has been dramatically improved, making it easier to see the extra processing that is required by the added not operator in the if statement.

结论PHP 7在常量/定义变量的情况下明显优化了短路,但是如果从未定义常量,我们会看到相反的情况。这意味着检查实际存在的常量已经大大改进,使得更容易看到if语句中添加的not运算符所需的额外处理。

Overall Conclusion

The difference is negligible (unless you're getting into the millions of loads of the same line of code) so use whatever makes the most sense for you and your team.

差异可以忽略不计(除非你进入同一行代码的数百万个负载),所以使用对你和你的团队最有意义的东西。

Also, man, PHP7 smokes PHP 6.5 in terms of performance of these tests!

另外,男人,PHP7在这些测试的性能方面抽了PHP 6.5!


Code:

$c1a=0;
$title1a = 'Test1a: Short circuit: Dynamic define on first loop.';
$c1b=0;
$title1b = 'Test1b: If Statement: Dynamic define on first loop.';

$c2a=0;
$title2a = 'Test2a: Short circuit: Static define before test is run.';
$c2b=0;
$title2b = 'Test2b: If Statement: Static define before test is run.';

$c3a=0;
$title3a = 'Test3a: Short circuit: Never define variable.';
$c3b=0;
$title3b = 'Test3b: If Statement: Never define variable.';

$start1a = microtime(true);
while ($c1a < 1000000) {
  ++$c1a;
  defined('TEST_CONST_1A') || define('TEST_CONST_1A', 'test');
}
$stop1a = microtime(true);

$start1b = microtime(true);
while ($c1b < 1000000) {
  ++$c1b;
  if (!defined('TEST_CONST_1B')) {
    define('TEST_CONST_1B', 'test');
  }
}
$stop1b = microtime(true);

define('TEST_CONST_2A', 'test');
$start2a = microtime(true);
while ($c2a < 1000000) {
  ++$c2a;
  defined('TEST_CONST_2A') || define('TEST_CONST_2A', 'test');
}
$stop2a = microtime(true);

define('TEST_CONST_2B', 'test');
$start2b = microtime(true);
while ($c2b < 1000000) {
  ++$c2b;
  if (!defined('TEST_CONST_2B')) {
    define('TEST_CONST_2B', 'test');
  }
}
$stop2b = microtime(true);

$start3a = microtime(true);
while ($c3a < 1000000) {
  ++$c3a;
  defined('TEST_CONST_3A') || $c3a;
}
$stop3a = microtime(true);

$start3b = microtime(true);
while ($c3b < 1000000) {
  ++$c3b;
  if (!defined('TEST_CONST_3B')) {
    $c3b;
  }
}
$stop3b = microtime(true);

print ($stop1a - $start1a) . ' - ' . $title1a . "\n";
print ($stop1b - $start1b) . ' - ' . $title1b . "\n";
print ($stop2a - $start2a) . ' - ' . $title2a . "\n";
print ($stop2b - $start2b) . ' - ' . $title2b . "\n";
print ($stop3a - $start3a) . ' - ' . $title3a . "\n";
print ($stop3b - $start3b) . ' - ' . $title3b . "\n";