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

1、在 PHP 中是使用 define() 函数来定义常量,PHP 5.3.0 以后,PHP 中也能够使用 const 关键字来声明常量了,一个常量一旦被定义,就不能再改变或者取消定义

2、常量只能包含标量数据(boolean,integer,float 和 string)。可以定义 resource 常量,但应尽量避免,因为会造成不可预料的结果

3、可以简单的通过指定其名字来取得常量的值,与变量不同,不应该在常量前面加上 $ 符号。如果常量名是动态的,也可以用函数 constant() 来获取常量的值。用 get_defined_constants() 可以获得所有已定义的常量列表

Note: 常量和(全局)变量在不同的名字空间中。这意味着例如 TRUE$TRUE 是不同的

常量和变量有如下不同

常量前面没有美元符号($);
常量只能用 define() 函数定义,而不能通过赋值语句;
常量可以不用理会变量的作用域而在任何地方定义和访问;
常量一旦定义就不能被重新定义或者取消定义;
常量的值只能是标量。

define vs const

1、define() 在执行期定义常量,使用 const 关键字定义常量必须处于最顶端的作用区域,因为用此方法是在编译时定义的,这就意味着不能在函数内,循环内以及 if 语句之内用 const 来定义常量,这样 const 就有轻微的速度优势, 但不值得考虑这个问题

2、define() 将常量放入全局作用域,虽然你可以在常量名中包含命名空间, 这意味着你不能使用 define() 定义类常量

3、define() 允许你在常量名和常量值中使用表达式,而 const 则都不允许,这使得 define() 更加灵活

示例

1、const不能使用条件表达式定义常量. 如果要定义一个全局常量,只能在表达式外面

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

2、const 可以使用一个静态标量 (number, string or other constant like true, false, null, __FILE__), 反之define()没有限制.不过从 PHP 5.6 之后可以使用常量表达式

const BIT_5 = 1 << 5;    // valid since PHP 5.6, invalid previously
define('BIT_5', 1 << 5); // always valid

3、const 使用一个普通的常量名称 反之define() 可以使用任意的常量表达式

for ($i = 0; $i < 32; ++$i) {define('BIT_' . $i, 1 << $i);
}

4、const总是大小写敏感的, 反之define() 允许你定义一个大小写不敏感的常量通过第三个参数

define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR

5、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 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');

6、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, valid in PHP 7.0

As consts are language constructs and defined at compile time they are a bit faster than define().

It is well known that PHP define() are slow when using a large number of constants. People have even invented things like apc_load_constants() and hidef to get around this.

consts make the definition of constants approximately twice as fast (on development machines with XDebug turned on even more). Lookup time on the other hand does not change (as both constant types share the same lookup table)

Finally, note that const can also be used within a class or interface to define a class constant or interface constant. define cannot be used for this purpose:

class Foo {const BAR = 2; // valid
}
// but
class Baz {define('QUX', 2); // invalid
}

Summary

Unless you need any type of conditional or expressional definition, use consts instead of define()s - simply for the sake of readability!

<?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()
}
?>

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

看一下define在内核中如何实现的

/* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false)Define a new constant */
ZEND_FUNCTION(define)
{char *name;int name_len;zval *val;zval *val_free = NULL;zend_bool non_cs = 0;int case_sensitive = CONST_CS;zend_constant c;if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {return;}if(non_cs) {case_sensitive = 0;}/* class constant, check if there is name and make sure class is valid & exists */if (zend_memnstr(name, "::", sizeof("::") - 1, name + name_len)) {zend_error(E_WARNING, "Class constants cannot be defined or redefined");RETURN_FALSE;}repeat:switch (Z_TYPE_P(val)) {case IS_LONG:case IS_DOUBLE:case IS_STRING:case IS_BOOL:case IS_RESOURCE:case IS_NULL:break;case IS_OBJECT:if (!val_free) {if (Z_OBJ_HT_P(val)->get) {val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);goto repeat;} else if (Z_OBJ_HT_P(val)->cast_object) {ALLOC_INIT_ZVAL(val_free);if (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {val = val_free;break;}}}/* no break */default:zend_error(E_WARNING,"Constants may only evaluate to scalar values");if (val_free) {zval_ptr_dtor(&val_free);}RETURN_FALSE;}c.value = *val;zval_copy_ctor(&c.value);if (val_free) {zval_ptr_dtor(&val_free);}c.flags = case_sensitive; /* non persistent */c.name = IS_INTERNED(name) ? name : zend_strndup(name, name_len);if(c.name == NULL) {RETURN_FALSE;}c.name_len = name_len+1;c.module_number = PHP_USER_CONSTANT;if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {RETURN_TRUE;} else {RETURN_FALSE;}
}
/* }}} *//* {{{ proto bool defined(string constant_name)Check whether a constant exists */
ZEND_FUNCTION(defined)
{char *name;int name_len;zval c;if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {return;}if (zend_get_constant_ex(name, name_len, &c, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {zval_dtor(&c);RETURN_TRUE;} else {RETURN_FALSE;}
}
/* }}} */

const

ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
{char *lowercase_name = NULL;char *name;int ret = SUCCESS;ulong chash = 0;#if 0printf("Registering constant for module %d\n", c->module_number);
#endifif (!(c->flags & CONST_CS)) {/* keep in mind that c->name_len already contains the '\0' */lowercase_name = estrndup(c->name, c->name_len-1);zend_str_tolower(lowercase_name, c->name_len-1);lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);name = lowercase_name;chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;} else {char *slash = strrchr(c->name, '\\');if(slash) {lowercase_name = estrndup(c->name, c->name_len-1);zend_str_tolower(lowercase_name, slash-c->name);lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);name = lowercase_name;chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;} else {name = c->name;}}if (chash == 0) {chash = zend_hash_func(name, c->name_len);}/* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */if ((c->name_len == sizeof("__COMPILER_HALT_OFFSET__")&& !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))|| zend_hash_quick_add(EG(zend_constants), name, c->name_len, chash, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {/* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */if (c->name[0] == '\0' && c->name_len > sizeof("\0__COMPILER_HALT_OFFSET__")&& memcmp(name, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {name++;}zend_error(E_NOTICE,"Constant %s already defined", name);str_free(c->name);if (!(c->flags & CONST_PERSISTENT)) {zval_dtor(&c->value);}ret = FAILURE;}if (lowercase_name && !IS_INTERNED(lowercase_name)) {efree(lowercase_name);}return ret;
}

参考

  • Stack Overflow: define() vs. const
  • PHP 手册:常量
  • Stack Overflow: define() vs. 变量
  • 测试地址

转载于:https://www.cnblogs.com/chenpingzhao/p/4811957.html

define() vs const 该如何选择?相关推荐

  1. #define与const的差别

    #define与const的差别 虽然他们在使用中感觉"差不多",但是他们在实现上有什么区别? 请看下面的代码: #define T 13 /*用#define定义的一个常量T*/ ...

  2. php定义常量 define vs const

    常量一旦定义就不能在改变或者取消. 在php中定义常量可以使用define()函数,在php5.3之后同样可以使用const关键字来定义常量. define 和 const的区别 语法区别 // 使用 ...

  3. define、const、typedef区别

    1.define与const的区别 define生效与预处理阶段,const生效与编译阶段.预处理在编译之前,预处理器将代码中的宏统一替换为指定的字符 .从语义上讲,const是声明一个不可修改的数据 ...

  4. [翻译]PHP中define()和const定义常量的区别

    在PHP中可以通过define()和const两种方式定义常量 可是在开发中我们应该什么时候用define()定义常量,什么时候用const定义常量? 这两种方式定义常量的主要区别是什么? 从5.3版 ...

  5. 2.尽量用const, enum, inline代替#define -- Prefer const, enum, inline to #define.

    1. 我们都知道,#define PRICE 30 是预编译处理器进行预编译的时候执行的,无法在编译器进行编译的过程中看见,因此,当编译出错的时候,通常错误信息是提到30,而不是PRICE,因此程序员 ...

  6. arduino中 #define、const和int 的差别

    首选我们要了解到的一个信息是arduino板子上的两个参数SRAM:2KB,Flash:32KB; 对应到我们使用的电脑呢,你可以认为SRAM是我们的内存,而Flash由是硬盘.先把这个理解清楚. # ...

  7. c语言 define和int,C语言中define与const的用法区别分析

    其实这个是困惑了我好久的问题,没想到在上机课做到的题里找到了答案--我的困惑是:#define与const到底有什么区别. 题目:  代码如下 复制代码 #define N 2 #define M N ...

  8. #define 和 const 区别

    const定义的常数是变量,需要带类型: #define定义的只是常数,不带类型 #define在编译的预处理阶段起作用:const在编译.运行时起作用 #define只是简单的字符串替换,没有类型检 ...

  9. PHP的define与const

    总结 运行时间:在于const会在代码编译时定义一个常量,而define则是在代码运行时才定义一个常量 函数内外:const不能在函数内使用,可以作为类静态属性:define可以在函数内也可以在函数外 ...

最新文章

  1. 一眼定位问题,函数计算发布日志关键词秒检索功能
  2. 东北大学 计算机调剂,2018年东北大学信息科学与工程学院考研调剂信息
  3. JS高效关键字搜索---转
  4. python完整安装顺序_Python安装与卸载流程详细步骤(图解)
  5. 关于arraylist的扩容机制
  6. 乐视云计算基于OpenStack的IaaS实践
  7. linux git删除的文件怎么还原,从Git仓库中恢复已删除的分支、文件或丢失的commit...
  8. mysql5.7免安版配置_mysql5.7免安装版配置
  9. The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
  10. asp.net mvc 过滤器
  11. Eclipse 导入项目到git@osc中
  12. .相亲过程:你有房子么?你有钱么?你有能力么? 【结婚吧】【先买房子在结婚】【先赚钱再买房子再结婚】都没有【拜拜~~】 利用if嵌套做相亲过程...
  13. 1. SVN (1)
  14. 27岁没文凭自学编程成为程序员难不难
  15. 风华散尽,葬送何言?伤感日志分享
  16. 安卓中压缩纹理ETC1和ETC2
  17. 切片器可以设置日期格式?_用Excel切片器为你的数据报告增加交互功能,很简单!...
  18. 大制作,1500多行python代码实现各大平台音乐搜索,下载,收听
  19. 自定义实现一个RPC框架(七)
  20. 软考复习-软件工程05-软件项目估算进度管理

热门文章

  1. 数据结构经典书籍--数据结构与算法分析
  2. 巧妙解法:买卖股票最佳时机
  3. wireshark抓包数据学习
  4. tmpfs 内存文件系统
  5. 《研磨设计模式》读后感一
  6. 【Golang 基础】Go 语言的程序结构
  7. HyperLedger Fabric 错误记录
  8. PHP动物书总结14-17
  9. 做好信息安全 必须打造良好的企业安全文化
  10. Vigen#232;re密码