В PHP сценариях константы объявляются с помощью функции define()
, которая принимает два параметра: имя константы и ее значение.
Внутри PHP константы объявляются похожим способом.Для объявления константы используются макросы семейства REGISTER_*_CONSTANT()
. Большинство констант объявляются один раз в во время инициализации модуля, в PHP_MINIT_FUNCTION()
Макросы семейства REGISTER_*_CONSTANT()
:
REGISTER_LONG_CONSTANT(char *name, long lval, int flags)
- макрос объявляет целочисленную константуREGISTER_DOUBLE_CONSTANT(char *name, double dval, int flags)
- макрос объявляет константу с плавающим числомREGISTER_STRING_CONSTANT(char *name, char *value, int flags)
- макрос объявляет строковую константу. Значение, передаваемое во втором параметре, обязано размещаться во внутренней памяти Zend. Передаваемое значение будет скопировано полностьюREGISTER_STRINGL_CONSTANT(char *name, char *value, int value_len, int flags)
- макрос объявляет строковую константу. В отличие от макросаREGISTER_STRING_CONSTANT()
значение, передаваемое во втором параметре, будет скопировано не полностью, а только первыхvalue_len
символов .
Все макросы в качестве первого параметра принимают строковую литералу с названием константы под которым она будет доступна в пользовательском пространстве.
Макросы семейства REGISTER_*_CONSTANT()
для определения длинны имени константы используют вызов sizeof()
, поэтому в качестве имени константы допускается использование только строкового литерала, нельзя использовать указатель на строку (char *
) так как результат вычисления будет не верен, sizeof( char * )
на 32-х битных системах обычно возвращает 4 — размер, в байтах, указателя на char
Вторым параметром задается значение константы, тип значения зависит от вызываемого макроса соответственно.
Макрос REGISTER_STRINGL_CONSTANT()
третьем параметром принимает цело число символов которое будет скопировано из значения переданного во втором параметре.
Последним параметром макросы принимают один из битовых флагов или несколько флагов объеденные побитовым ИЛИ. В качестве битовых флагов принимается константы:
CONST_CS
— указывает на то что создаваемая константа регистрозависимая. Это правило является принятым по умолчанию для констант объявляемых в пользовательском пространстве и для констант объявляемых внутри PHP. Для некоторых констант, таких как TRUE
, FALSE
, NULL
, это правило не применяется. Данных константы объявлены как регитронезависимые.
CONST_PERSISTENT
— указывает на то, что константа должно быть доступна между запросами
Если константы объявляется в PHP_MINIT_FUNCTION()
, то очевидно, что она должна быть объявлена с флагом CONST_PERSISTENT
и она будет доступна между запросами. Когда же константа объявляется при поступлении запроса, в функции PHP_RINIT_FUNCTION()
, вы должны опускать данный флаг, позволяя движку уничтожить данную константу в конце запроса.
Примеры объявления констант с использованием макросов семейства REGISTER_*_CONSTANT()
PHP_MINIT_FUNCTION(my_extension)
{
REGISTER_STRING_CONSTANT("MY_EXTENSION_CONST", "Value of my extension constant", CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
В данном примере объявляется строковая константа, которая будет доступна в пользовательском пространстве под именем MY_EXTENSION_CONST
. Константа объявлена как регистрозависимая и будет доступна между запросами, на протяжении всего времени работы модуля. Значение константы будет скопировано в отдельный участок памяти, который будет автоматически освобожден в фазе завершения работы модуля.
Использование константы в пользовательском пространстве:
<?php
echo MY_EXTENSION_CONST; // Выведет Value of my extension constant
echo my_extension_const; // Ошибка! Константа регистрозависимая
?>
В следующем примере также объявляется строковая константа:
static char *const_value = NULL;
PHP_MINIT_FUNCTION(my_extension) {
const_value = (char*)malloc(12);
strcpy( const_value, "Hello world");
REGISTER_STRING_CONSTANT("MY_EXTENSION_CONST_2", const_value, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(my_extension){
free(const_value);
}
В примере объявляется указатель const_value
на char
. Внутри функции PHP_MINIT_FUNCTION()
выделяется участок память, в выделенный участок помещается строка "Hello world". Указатель const_value
указывает на начало выделенного блока памяти. Далее происходит инициализация константы, которая в пользовательском пространстве будет доступна под именем MY_EXTENSION_CONST_2
. Во втором параметре передается не строковая литерала со значением, а указатель на бок памяти в котором содержится значение константы.
Если в качестве имени константы необходимо использовать переменную, в которой хранится название, например, создаваемое в цикле, то макросы семейства REGISTER_*_CONSTANT
не могут быть для этого использованы из-за за использования вызова sizeof()
для определения длинны имени константы. В таких случаях необходимо использовать следующие функции:
void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC)
void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC)
void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC)
void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC)
Макросы семейства REGISTER_*_CONSTANT
также вызывают выше указанные функции. Первым параметром в функцию передается название константы под которым она будет доступна в пользовательском пространстве, вторым параметром передается длина имени константы. Если для вычисления длинны строки будет использоваться функция strlen()
, то к возвращаемому ею значению необходимо прибавить 1, так как функция не учитывает символ завершения строки '\0'. Третьим параметром функции принимают значение константы.
Функция zend_register_string_constant()
и zend_register_stringl_constant()
четвертым параметром принимают длину строки, указанной в качестве значения. Следующим параметром функции принимают битовые флаги, которые описаны выше. Предпоследним параметром в функции передается переменная module_number
- номер модуля. Данная переменная инициализируется движком при загрузке расширения и служит ключом для отчисти данных когда модуль выгружается из памяти. Данная переменная доступна во всех PHP_MINIT_FUNCTION()
и PHP_RINIT_FUNCTION()
, поэтому просто передавайте её в функции создания констант не задумываясь о её содержимым. Последним параметром должен явно передаваться макрос TSRMLS_CC
Пример создания константы:
PHP_MINIT_FUNCTION(my_extension )
{
char *const_name = "MY_EXTENSION_CONST";
zend_register_string_constant( const_name, strlen(const_name)+1, "Hello world ", CONST_CS |CONST_PERSISTENT, module_number TSRMLS_CC);
return SUCCES;
}
Макросы семейства REGISTER_*_CONSTANT
и функции семейства zend_register_*_constant()
не охватывают все типы констант которые могут понадобиться. В Zend API нет макросов и функций способных, например, создавать константы в качестве которых будет массивы или объекты. Для создания таких констант необходимо использовать функцию zend_register_constant()
.
Прототип функции:
int zend_register_constant( zend_constant *c, TSRMLS_DC )
В качестве первого аргумента функция принимает инициализированную структуру с информацией о константе, вторым параметром макрос TSRMLS_CC
zend_constant
— структура имеющая следующие объявление:
typedef struct _zend_constant {
zval value;
int flags;
char *name;
uint name_len;
int module_number;
} zend_constant;
Поля структуры:
value
— данные константыflags
— битовый флаг или несколько флагов объединенные побитовым ИЛИname
— название константыname_len
— длинна имени константыmodule_number
— номер модуля
Пример создания константы:
PHP_MINIT_FUNCTION(my_extension )
{
char *const_name = "MY_EXTENSION_CONST";
zend_constant c;
ZVAL_TRUE( (&c.value);
c.flags = CONST_CS | CONST_PERSISTENT;
c.name = zend_strndup(const_name, strlen(const_name ));
c.name_len = strlen(const_name) + 1 ;
c.module_number = module_number;
zend_register_constant(&c; TSRMLS_CC);
return SUCCES;
}
В данном примере создается константа с булевым значением TRUE