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
接受一个静态标量(数字,string或其他常数,如true
,false
,null
,__FILE__
),而define()
则使用任何expression式。 由于常量expression式允许使用PHP 5.6常量expression式,const BIT_5 = 1 << 5; // valid since PHP 5.6, invalid previously define('BIT_5', 1 << 5); // always valid
-
const
接受一个普通的常量名,而define()
接受任何expression式作为名字。 这允许做这样的事情:for ($i = 0; $i < 32; ++$i) { define('BIT_' . $i, 1 << $i); }
-
const
总是区分大小写的,而define()
允许你通过传递true
作为第三个参数来定义不区分大小写的常量:define('FOO', 'BAR', true); echo FOO; // BAR echo foo; // BAR
所以,这是事情的坏处。 现在让我们看看为什么我个人总是使用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, valid in PHP 7.0
-
由于
const
是语言结构,在编译时定义,它们比define()
要快一些。众所周知,当使用大量的常量时,PHP
define()
很慢。 人们甚至发明了像apc_load_constants()
和hidef
来解决这个问题。const
使得const
的定义大约快一倍(在XDebug打开的开发机器上)。 查询时间另一方面不会改变(因为两个常量types共享相同的查找表): 演示 。
最后,请注意, const
也可以在类或接口中使用来定义类常量或接口常量。 define
不能用于这个目的:
class Foo { const BAR = 2; // valid } // but class Baz { define('QUX', 2); // invalid }
概要
除非需要任何types的条件或expression式定义,否则使用const
s而不是define()
s – 仅仅是为了便于阅读!
在PHP 5.3之前, const
不能在全局范围内使用。 你只能在课堂上使用这个。 当你想要设置某种常量选项或与该类相关的设置时,应该使用这个选项。 或者,也许你想创build某种枚举。
define
可以用于相同的目的,但是它只能在全局范围内使用。 它只能用于影响整个应用程序的全局设置。
一个很好的const
用法的例子是摆脱幻数。 看看PDO的常量 。 当您需要指定提取types时,例如,您将键入PDO::FETCH_ASSOC
。 如果不使用const,你最终会input35
(或者其他的FETCH_ASSOC
被定义为)。 这对读者来说没有意义。
一个好的define
用法的例子可能是指定你的应用程序的根path或一个库的版本号。
我知道这已经回答了,但是目前的答案没有提到任何提及命名空间,以及它如何影响常量和定义。
从PHP 5.3开始,常量和定义在大多数方面是相似的。 但是,还是有一些重要的区别:
- Consts不能从expression式中定义。
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
有更多的灵活性。 你现在可以用expression式来定义const,只要这些expression式是由其他常量或文字组成的。 这意味着以下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;
尽pipe如此,你仍然无法通过variables或函数返回来定义const
const RND = mt_rand(); const CONSTVAR = $var;
仍然会出局。
我相信从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; ?>
define
我用于全局常量。
const
我使用类常量。
你不能define
类的范围,而用const
你可以。 不用说,你不能在类的范围外使用const
此外,与const
,它实际上成为类的成员,与define
,它将被推到全球范围。
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的概念总是和代码中的任何地方一样,而PHP并不能保证这一点。
这些答案大部分是错误的,或者只是讲述了一半的故事。
- 你可以使用命名空间来限定你的常量。
- 您可以在类定义之外使用“const”关键字。 但是,就像在类中一样,使用“const”关键字指定的值必须是常量expression式。
例如:
const AWESOME = 'Bob'; // Valid
不好的例子:
const AWESOME = whatIsMyName(); // Invalid (Function call) const WEAKNESS = 4+5+6; // Invalid (Arithmetic) const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
要创buildvariables常量使用define()就像这样:
define('AWESOME', whatIsMyName()); // Valid define('WEAKNESS', 4 + 5 + 6); // Valid define('FOO', BAR . OF . SOAP); // Valid
是的,const是在编译时定义的,而nikic状态是不能被赋值的,就像define()的can一样。 但是也不能有条件地声明const(出于同样的原因)。 即。 你不可以做这个:
if (/* some condition */) { const WHIZZ = true; // CANNOT DO THIS! }
而你可以用define()。 所以,这并不是真正归因于个人喜好,使用两者的方法是正确的和错误的。
作为一个旁白…我想看到某种types的const可以被分配一个expression式,一种可以被隔离到类的define()?
添加NikiC的答案。 const
可以按以下方式在类中使用:
class Foo { const BAR = 1; public function myMethod() { return self::BAR; } }
你不能用define()
来做到这一点。