## 使用 [define()](http://www.php.net/manual/en/function.define.php),除非考虑到可读性、类常量、或关注微优化
习惯上,在 PHP 中是使用 define() 函数来定义常量。 但从某个时候开始,PHP 中也能够使用 [const](http://php.net/manual/zh/language.oop5.constants.php) 关键字来声明常量了。 那么当定义常量时,该使用哪种方式呢?
答案在于这两种方法之间的区别。
1. define() 在执行期定义常量,而 const 在编译期定义常量。这样 const 就有轻微的速度优势, 但不值得考虑这个问题,除非你在构建大规模的软件。
2. define() 将常量放入全局作用域,虽然你可以在常量名中包含命名空间。 这意味着你不能使用 define() 定义类常量。
3. define() 允许你在常量名和常量值中使用表达式,而 const 则都不允许。 这使得 define() 更加灵活。
4. define() 可以在 if() 代码块中调用,但 const 不行。
## 示例
~~~
<?php
// 来看看这两种方法如何处理 namespaces
namespace MiddleEarth\Creatures\Dwarves;
const GIMLI_ID = 1;
define('MiddleEarth\Creatures\Elves\LEGOLAS_ID', 2);
echo(\MiddleEarth\Creatures\Dwarves\GIMLI_ID); // 1
echo(\MiddleEarth\Creatures\Elves\LEGOLAS_ID); // 2; 注意:我们使用了 define()
// Now let's declare some bit-shifted constants representing ways to enter Mordor.
define('TRANSPORT_METHOD_SNEAKING', 1 << 0); // OK!
const TRANSPORT_METHOD_WALKING = 1 << 1; //Compile error! const can't use expressions as values
// 接下来, 条件常量。
define('HOBBITS_FRODO_ID', 1);
if($isGoingToMordor){
define('TRANSPORT_METHOD', TRANSPORT_METHOD_SNEAKING); // OK!
const PARTY_LEADER_ID = HOBBITS_FRODO_ID // 编译错误: const 不能用于 if 块中
}
// 最后, 类常量
class OneRing{
const MELTING_POINT_DEGREES = 1000000; // OK!
define('SHOW_ELVISH_DEGREES', 200); // 编译错误: 在类内不能使用 define()
}
?>
~~~
> 小插曲:当我看到第一行的 MiddleEarth 还没有感觉到什么,再往下看到 Mordor 时,震惊了。**OneRing**,**OneRing**,**OneRingggggg**!
因为 define() 更加灵活,你应该使用它以避免一些令人头疼的事情,除非你明确地需要类常量。 使用 const 通常会产生更加可读的代码,但是以牺牲灵活性为代价的。
无论你选择哪一种,请保持一致。
## 进一步阅读
* [Stack Overflow: define() vs. const](http://stackoverflow.com/questions/2447791/define-vs-const)
* [PHP 手册:常量](http://www.php.net/manual/en/language.constants.syntax.php)
* [Stack Overflow: define() vs. 变量](http://stackoverflow.com/questions/1225082/define-vs-variable-in-php)