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

时间:2011-08-10 09:51:52

标签: php

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

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

代替:

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

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

4 个答案:

答案 0 :(得分:10)

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

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

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

答案 1 :(得分:4)

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

or vs ||而言,这个具体案例没有区别。但是,or的{​​{3}}低于=(赋值运算符),而||的值较高。如果您想使用短路来进行分配,这很重要。

考虑:

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


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

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

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

而第一个

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

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

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

PHP 5.6:

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

<强>结论
太接近了,但如果变量从未被定义,我们可以看到短路速度明显提高。

PHP 7:

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

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

总体结论

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

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

代码:

$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";
相关问题