php内核探索-常量

在PHP中常量的结构只是在变量的基础上添加了一些额外的元素:

typedef struct _zend_constant {
    zval value;     /* zval结构,PHP内部变量的存储结构,在前面有说明 */
    int flags;      /* 常量的标记如 CONST_PERSISTENT | CONST_CS */
    char *name;     /* 常量名称 */
    uint name_len;  
    int module_number;  /* 模块号 */
} zend_constant;

PHP常量定义方式:

define('^_^', 'Think in PHP');

define定义常量过程:

/* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false)
Define a new constant */
ZEND_FUNCTION(define)
{
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name,
            &name_len, &val, &non_cs) == FAILURE) {
            return;
    }
    ... // 类常量定义 此处不做介绍

    ... // 值类型判断和处理
    c.value = *val;
    zval_copy_ctor(&c.value);
    if (val_free) {
            zval_ptr_dtor(&val_free);
    }

    c.flags = case_sensitive; /* non persistent */
    c.name = zend_strndup(name, name_len);
    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;
    }
}
    /* }}} */

上面的代码已经对对象和类常量做了简化处理,其实现上是一个将传递的参数传递给新建的zend_constant结构,并将这个结构体注册到常量列表中的过程。第三个参数表示大小写敏感,默认为false.
PHP对于常量的名称没有具体的限制,常量赋值时需要用constant()方法来获取到。否则在语法解析时会报错。

    //$var = ^_^;   //语法错误
$var = constant("^_^");

flags的标记除了CONST_CS,还可以为CONST_PERSISTENT和CONST_CT_SUBST.
CONST_PERSISTENT表示该常量可持久化,非持久化的常量在请求结束(RSHUTDOWN)时就会被释放,否则在MSHUTDOWN释放。用户空间的常量为费持久化,拓展模块和内核中常量会设置为持久化,提升执行效率。
CONST_CT_SUBST表示Allow compile-time substitution(在编译时可被替换)。

你可能感兴趣的:(PHP,内核)