在PHP中,你可以用两种方式声明常量:
使用define关键字 定义(“FOO”,1); 使用const关键字 const FOO = 1;
这两者之间的主要区别是什么? 什么时候,为什么要使用一种,什么时候使用另一种?
在PHP中,你可以用两种方式声明常量:
使用define关键字 定义(“FOO”,1); 使用const关键字 const FOO = 1;
这两者之间的主要区别是什么? 什么时候,为什么要使用一种,什么时候使用另一种?
定义我用于全局常量。
const用于类常量。
不能在类范围内定义,而使用const可以。
同样,使用const,它实际上成为类的成员,而使用define,它将被推入全局作用域。
在PHP 5.3之前,const不能在全局作用域中使用。您只能在类中使用它。当您想要设置一些属于该类的常量选项或设置时,应该使用此选项。或者你可能想要创建某种enum。
Define可以用于相同的目的,但只能在全局作用域中使用。它只能用于影响整个应用程序的全局设置。
良好使用const的一个例子是去掉神奇的数字。看一下PDO的常数。例如,当需要指定获取类型时,可以输入PDO::FETCH_ASSOC。如果不使用const,则最终会键入类似35的值(或FETCH_ASSOC定义的任何值)。这对读者来说毫无意义。
好的define用法的一个例子是指定应用程序的根路径或库的版本号。
我相信从PHP 5.3开始,你可以在类之外使用const,如下面的第二个例子所示:
http://www.php.net/manual/en/language.constants.syntax.php
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
从PHP 5.3开始,有两种方法定义常量:要么使用const关键字,要么使用define()函数:
const FOO = 'BAR';
define('FOO', 'BAR');
这两种方式的根本区别在于const在编译时定义常量,而define在运行时定义常量。这导致了const的大部分缺点。const的一些缺点是:
const cannot be used to conditionally define constants. To define a global constant, it has to be used in the outermost scope: if (...) { const FOO = 'BAR'; // Invalid } // but if (...) { define('FOO', 'BAR'); // Valid } Why would you want to do that anyway? One common application is to check whether the constant is already defined: if (!defined('FOO')) { define('FOO', 'BAR'); } const accepts a static scalar (number, string or other constant like true, false, null, __FILE__), whereas define() takes any expression. Since PHP 5.6 constant expressions are allowed in const as well: const BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously define('BIT_5', 1 << 5); // Always valid const takes a plain constant name, whereas define() accepts any expression as name. This allows to do things like this: for ($i = 0; $i < 32; ++$i) { define('BIT_' . $i, 1 << $i); } consts are always case sensitive, whereas define() allows you to define case insensitive constants by passing true as the third argument (Note: defining case-insensitive constants is deprecated as of PHP 7.3.0 and removed since PHP 8.0.0): define('FOO', 'BAR', true); echo FOO; // BAR echo foo; // BAR
这就是事情不好的一面。现在让我们看看为什么我个人总是使用const,除非发生上述情况之一:
const simply reads nicer. It's a language construct instead of a function and also is consistent with how you define constants in classes. const, being a language construct, can be statically analysed by automated tooling. const defines a constant in the current namespace, while define() has to be passed the full namespace name: namespace A\B\C; // To define the constant A\B\C\FOO: const FOO = 'BAR'; define('A\B\C\FOO', 'BAR'); Since PHP 5.6 const constants can also be arrays, while define() does not support arrays yet. However, arrays will be supported for both cases in 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() -只是为了可读性!
是的,const是在编译时定义的,因为nikic状态不能被分配一个表达式,而define()可以。但是const也不能有条件地声明(出于同样的原因)。ie。你不能这样做:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
而使用define()则可以。所以,这并不取决于个人喜好,两者都有正确和错误的使用方式。
题外话……我想看到某种类型的类const,可以分配一个表达式,一种定义(),可以隔离到类?
我知道这个问题已经有人回答了,但是目前的回答都没有提到名称空间以及它如何影响常量和定义。
从PHP 5.3开始,const和define在大多数方面是相似的。然而,仍有一些重要的区别:
常量不能从表达式中定义。const FOO = 4 * 3;定义('CONST', 4 * 3);所做的事。 传递给定义的名称必须包括要在该名称空间中定义的名称空间。
下面的代码将说明其中的区别。
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
user子数组的内容将是['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]。
=== update ===
即将到来的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;
还是会出来的。
NikiC的答案是最好的,但是让我在使用名称空间时添加一个不明显的警告,这样您就不会遇到意想不到的行为。需要记住的是,定义总是在全局名称空间中,除非显式地将该名称空间添加为定义标识符的一部分。不明显的是,命名空间标识符胜过全局标识符。所以:
<?php
namespace foo
{
// Note: when referenced in this file or namespace, the const masks the defined version
// this may not be what you want/expect
const BAR = 'cheers';
define('BAR', 'wonka');
printf("What kind of bar is a %s bar?\n", BAR);
// To get to the define in the global namespace you need to explicitely reference it
printf("What kind of bar is a %s bar?\n", \BAR);
}
namespace foo2
{
// But now in another namespace (like in the default) the same syntax calls up the
// the defined version!
printf("Willy %s\n", BAR);
printf("three %s\n", \foo\BAR);
}
?>
生产:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
这让我对const的概念产生了不必要的困惑,因为在许多其他语言中,const的概念在代码中的任何地方都是相同的,而PHP并不能真正保证这一点。
这些答案大多是错误的,或者只说了一半。
可以通过使用名称空间来限定常量的范围。 你可以在类定义之外使用“const”关键字。然而,就像在 使用"const"关键字赋值的类必须是 常数表达式。
例如:
const AWESOME = 'Bob'; // Valid
不好的例子:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
使用define()创建变量常量,如下所示:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
补充一下尼克的回答。Const可以在类中以以下方式使用:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
使用define()不能做到这一点。