define() vs. const

使用 define(),除非考虑到可读性、类常量、或关注微优化

习惯上,在 PHP 中是使用 define() 函数来定义常量。
但从某个时候开始,PHP 中也能够使用 const 关键字来声明常量了。
那么当定义常量时,该使用哪种方式呢?

答案在于这两种方法之间的区别。

  • define()在执行期定义常量,而const在编译期定义常量。这样const就有轻微的速度优势,
    但不值得考虑这个问题,除非你在构建大规模的软件。
  • define()将常量放入全局作用域,虽然你可以在常量名中包含命名空间。
    这意味着你不能使用define()定义类常量。
  • define()允许你在常量名和常量值中使用表达式,而const则都不允许。
    这使得define()更加灵活。
  • define()可以在if()代码块中调用,但const不行。

示例

  1. <?php
  2. // 来看看这两种方法如何处理 namespaces
  3. namespace MiddleEarth\Creatures\Dwarves;
  4. const GIMLI_ID = 1;
  5. define('MiddleEarth\Creatures\Elves\LEGOLAS_ID', 2);
  6.  
  7. echo(\MiddleEarth\Creatures\Dwarves\GIMLI_ID); // 1
  8. echo(\MiddleEarth\Creatures\Elves\LEGOLAS_ID); // 2; 注意:我们使用了 define()
  9.  
  10. // Now let's declare some bit-shifted constants representing ways to enter Mordor.
  11. define('TRANSPORT_METHOD_SNEAKING', 1 << 0); // OK!
  12. const TRANSPORT_METHOD_WALKING = 1 << 1; //Compile error! const can't use expressions as values
  13.  
  14. // 接下来, 条件常量。
  15. define('HOBBITS_FRODO_ID', 1);
  16.  
  17. if($isGoingToMordor){
  18. define('TRANSPORT_METHOD', TRANSPORT_METHOD_SNEAKING); // OK!
  19. const PARTY_LEADER_ID = HOBBITS_FRODO_ID // 编译错误: const 不能用于 if 块中
  20. }
  21.  
  22. // 最后, 类常量
  23. class OneRing{
  24. const MELTING_POINT_DEGREES = 1000000; // OK!
  25. define('SHOW_ELVISH_DEGREES', 200); // 编译错误: 在类内不能使用 define()
  26. }
  27. ?>

小插曲:当我看到第一行的 MiddleEarth 还没有感觉到什么,再往下看到 Mordor 时,震惊了。OneRingOneRingOneRingggggg

因为 define() 更加灵活,你应该使用它以避免一些令人头疼的事情,除非你明确地需要类常量。
使用 const 通常会产生更加可读的代码,但是以牺牲灵活性为代价的。

无论你选择哪一种,请保持一致。

进一步阅读