菲律宾比索 |define() vs. const

2022-08-30 05:49:13

在 PHP 中,可以通过两种方式声明常量:

  1. 带关键字define

    define('FOO', 1);
    
  2. 使用关键字const

    const FOO = 1;
    

  • 这两者之间的主要区别是什么?
  • 何时以及为何应使用一个,何时使用另一个?

答案 1

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

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

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

  • const不能用于有条件地定义常量。要定义全局常量,必须在最外层的作用域中使用它:

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

    你为什么要这样做呢?一个常见的应用是检查是否已定义常量:

     if (!defined('FOO')) {
         define('FOO', 'BAR');
     }
    
  • const接受静态标量(数字、字符串或其他常量,如 、 、 、),而接受任何表达式。由于 PHP 5.6 常量表达式也是允许的:truefalsenull__FILE__define()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);
     }
    
  • consts 始终区分大小写,而允许您通过作为第三个参数传递来定义不区分大小写的常量(注意:从 PHP 7.3.0 开始不推荐定义不区分大小写的常量,并从 PHP 8.0.0 开始删除):define()true

     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 常量也可以是数组,而还不支持数组。但是,在 PHP 7 中,这两种情况都支持数组。constdefine()

     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
    

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

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

总结

除非您需要任何类型的条件或表达式定义,否则请使用s而不是s - 只是为了提高可读性!constdefine()


答案 2

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

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

良好用法的一个例子是摆脱幻数。看看PDO的常量。例如,当您需要指定抓取类型时,可以键入 。如果不使用consts,你最终会输入类似的东西(或任何被定义为的东西)。这对读者来说毫无意义。constPDO::FETCH_ASSOC35FETCH_ASSOC

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


推荐