协慌网

登录 贡献 社区

define()与 const

在 PHP 中,何时使用

define('FOO', 1);

以及何时使用

const FOO = 1;

两者之间的主要区别是什么?

答案

从 PHP 5.3 开始,有两种定义常量的方法:使用const关键字或使用define()函数:

const FOO = 'BAR';
define('FOO', 'BAR');

这两种方式之间的根本区别是const在编译时定义常量,而define在运行时定义常量。这导致了const的大多数缺点。 const一些缺点是:

  • const不能用于有条件地定义常量。要定义全局常量,必须在最外面的范围内使用它:

    if (...) {
        const FOO = 'BAR';    // Invalid
    }
    // but
    if (...) {
        define('FOO', 'BAR'); // Valid
    }

    您为什么仍要这样做?一种常见的应用是检查常量是否已经定义:

    if (!defined('FOO')) {
        define('FOO', 'BAR');
    }
  • const接受静态标量(数字,字符串或其他常量,如truefalsenull__FILE__ ),而define()可以接受任何表达式。由于 PHP 5.6 常量表达式也可以在const中使用:

    const BIT_5 = 1 << 5;    // Valid since PHP 5.6 and invalid previously
    define('BIT_5', 1 << 5); // Always valid
  • const采用简单的常量名称,而define()接受任何表达式作为名称。这样可以执行以下操作:

    for ($i = 0; $i < 32; ++$i) {
        define('BIT_' . $i, 1 << $i);
    }
  • const始终区分大小写,而define() true作为第三个参数传递来定义不区分大小写的常量(注意:自 PHP 7.3.0 起不建议使用不区分大小写的常量。):

    define('FOO', 'BAR', true);
    echo FOO; // BAR
    echo foo; // BAR

所以,那是不好的一面。现在让我们看看为什么我个人总是使用const的原因,除非出现以下情况之一:

  • const读起来更好。它是一种语言构造,而不是函数,并且与您在类中定义常量的方式保持一致。
  • const是一种语言构造,可以通过自动化工具进行静态分析。
  • const在当前名称空间中定义一个常量,而define()必须传递完整的名称空间名称:

    namespace A\B\C;
    // To define the constant A\B\C\FOO:
    const FOO = 'BAR';
    define('A\B\C\FOO', 'BAR');
  • 由于 PHP 5.6 const常量也可以是数组,而define()还不支持数组。但是,PHP 7 中的两种情况都将支持数组。

    const FOO = [1, 2, 3];    // Valid in PHP 5.6
    define('FOO', [1, 2, 3]); // Invalid in PHP 5.6 and valid in PHP 7.0

最后,请注意,也可以在类或接口内使用const来定义类常量或接口常量。 define不能用于此目的:

class Foo {
    const BAR = 2; // Valid
}
// But
class Baz {
    define('QUX', 2); // Invalid
}

概括

除非您需要任何类型的条件或表达式定义,否则使用const而不是define()只是出于可读性的考虑!

在 PHP 5.3 之前,不能在全局范围内使用const您只能在一个班级中使用它。当您要设置某种与该类有关的常量选项或设置时,应使用此选项。或者,也许您想创建某种枚举。

define可以用于相同的目的,但是只能在全局范围内使用。仅应将其用于影响整个应用程序的全局设置。

const用法的一个例子是摆脱魔术数字。看一下PDO 的常量。例如,当您需要指定获取类型时,可以输入PDO::FETCH_ASSOC 。如果不使用 const,您最终将输入类似35 (或任何定义为FETCH_ASSOC这对读者没有意义。

define用法的一个示例可能是指定应用程序的根路径或库的版本号。

我知道已经回答了这个问题,但是当前的回答都没有提及命名空间及其对常量和定义的影响。

从 PHP 5.3 开始,const 和 define 在大多数方面都是相似的。但是,仍然存在一些重要的区别:

  • 不能从表达式定义常量。 const FOO = 4 * 3;不起作用,但是define('CONST', 4 * 3);做。
  • 传递给define的名称必须包括要在该名称空间中定义的名称空间。

下面的代码应说明差异。

namespace foo 
{
    const BAR = 1;
    define('BAZ', 2);
    define(__NAMESPACE__ . '\\BAZ', 3);
}

namespace {
    var_dump(get_defined_constants(true));
}

用户子数组的内容将为['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]

=== 更新 ===

即将面世的 PHP 5.6 将为const更多的灵活性。现在,您将能够根据表达式定义 const,前提是这些表达式由其他 const 或文字组成。这意味着以下内容自 5.6 起有效:

const FOOBAR = 'foo ' . 'bar';
const FORTY_TWO = 6 * 9; // For future editors: THIS IS DELIBERATE! Read the answer comments below for more details
const ULTIMATE_ANSWER = 'The ultimate answer to life, the universe and everything is ' . FORTY_TWO;

不过,您仍然无法根据变量或函数返回值来定义 const,因此

const RND = mt_rand();
const CONSTVAR = $var;

仍然会出来。