notes icon indicating copy to clipboard operation
notes copied to clipboard

PHP define() vs const

Open lanlin opened this issue 7 years ago • 0 comments

场景

在 PHP 中,定义常量有两种方式,要么使用 const 要么使用 define()。 究竟他们二者有什么不同呢?为什么说 define() 的性能低下呢?

分析

const 是在编译时(compile time)完成常量定义的,而 define 是在运行时(run time)完成的。 这是两者的根本性差别,由此也就解释了一些二者的其他差别。

  1. const 只能用于顶层作用域(top-level)中,因此不能用于逻辑判断内,或者是方法体中。 define 则没有该限制。
if (...) 
{
    const FOO = 'BAR';    // invalid
}

// but
if (...)
{
    define('FOO', 'BAR'); // valid
}
  1. const 的值只能使用静态纯量,比如数字、字符串、布尔等。不支持是变量和非常量类型的表达式。 define 也没有这些限制。(PHP 5.6 以前,const 连常量类型的表达式也不支持)
const BIT_5 = 1 << 5;    // valid since PHP 5.6, invalid previously
define('BIT_5', 1 << 5); // always valid
  1. const 只能用固定常量类型字符作为常量名,而 define 的常量名可以是动态拼接的表达式等。
for ($i = 0; $i < 32; ++$i)
{
    define('BIT_' . $i, 1 << $i);
}
  1. const 定义的常量,其常量名是大小写敏感的。而 define 可以通过第三个参数控制。
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
  1. const 还可以像属性一样被用于类和接口中,定义类为类常量或者接口常量。而 define 不可以。
class Foo
{
    const BAR = 2; // valid
}

// but
class Baz
{
    define('QUX', 2); // invalid
}
  1. const 的定义可以自动界定当前所在命名空间,自动定义为该命名空间下的常量。 而 define 必须传递完整的命名空间作为常量名才行。
namespace A\B\C;

// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');
  1. const 从 php 5.6 开始支持数组类型的常量值,而 define 直到 PHP 7.0 才支持。
const FOO = [1, 2, 3];    // valid in PHP 5.6
define('FOO', [1, 2, 3]); // invalid in PHP 5.6, valid in PHP 7.0
  1. 还有一点需要说明的,const 的性能要优于 define。 因为一个是运行时动态生成的,一个是编译时就生成的。因此 const 会更快。

结论

综合上所述的情况,我们可以得出一个简单的结论。 只有在以下两种情况下,你需要使用 define:

  1. 你需要在 逻辑体内 ,或者 方法体内 定义常量
// inside condition
if (...)
{
    define('HI', 'condition');
}

// inside function
function test()
{
    define('HI', 'function');
}
  1. 你的 常量名或者常量值是动态生成的
$a = 'World';
$b = 'China';

define('Hello_'. $a, 'Hello_'. $b);

除了以上两种情况必须使用 define 外,其他情形都建议使用 const

传说

传说到了 PHP 8.0 的时候,常量名的大小写敏感问题会有所调整。 具体如何,尚不清楚。(截稿版本为 PHP 7.2.9)

lanlin avatar Oct 30 '18 03:10 lanlin