Запрос Аргументов
| ||||||||||
|
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...); |
Первый аргумент этой функции это количество реально переданных функции параметров, так что ZEND_NUM_ARGS() может использоваться здесь. Второй параметр всегда должен быть макросом TSRMLS_CC. Третий аргумент это строка, специфицирующая количество и типы аргументов, ожидаемых вашей функцией, аналогично тому, как строка форматирования printf специфицирует количество и формат выводимых значений, с которыми она должна работать. И, наконец, остальные аргументы это указатели на переменные, которые должны принимать значения от параметров.
zend_parse_parameters() выполняет также, где возможно, конвертацию типов, так что вы всегда получаете данные в том формате, который запросили. Любой скалярный тип может быть конвертирован в другой, но конвертация между сложными типами (массивами, объектами и ресурсами) и скалярными типами не допускается.
Если параметр может быть успешно получен и в процессе конвертации не было ошибок, функция возвратит SUCCESS, иначе - FAILURE. Функция выводит информативные сообщения об ошибках, если количество полученных параметров не совпадает с запрашиваемым количеством или если конвертация типов не может быть выполнена.
Вот некоторые примеры сообщений об ошибках:
Warning! - ini_get_all() requires at most 1 parameter, 2 given Warning! - wddx_deserialize() expects parameter 1 to be string, array given |
Естественно, каждое сообщение об ошибке сопровождается именем файла и строкой, в которой ошибка возникла.
Вот полный список спецификаторов типов:
l - long
d - double
s - string/строка (с возможным нулевым количеством байтов) и её длина
b - boolean
r - ресурс, хранимый в zval*
a - array/массив, хранимый в zval*
o - object/объект (любого класса), хранимый в zval*
O - object/объект (класса, специфицированного вхождением класса), хранимый в zval*
z - текущий zval*
| - указывает, что оставшиеся параметры являются необязательными. Переменные для хранения, соответствующие этим параметрам, должны быть инициализированы значениями по умолчанию расширением, поскольку они не будут затронуты разбирающей функцией, если параметры не переданы.
/ - разбирающая функция вызывает SEPARATE_ZVAL_IF_NOT_REF() для следующего за ней параметра, чтобы предоставить копию этого параметра, если только это не ссылка.
! - следующий за ним параметр может быть специфицированного типа или NULL (применяется только к a, o, O, r или z). Если значение NULL передаётся пользователем, хранимый указатель будет установлен в NULL.
Лучше всего показать работу этой функции на примерах:
/* Получить long, string и её длину и zval. */ long l; char *s; int s_len; zval *param; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz", &l, &s, &s_len, ¶m) == FAILURE) { return; } * Получить объект класса, специфицированного my_ce, и необязательное double. */ zval *obj; double d = 0.5; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d", &obj, my_ce, &d) == FAILURE) { return; } /* Получить объект или null и массив. Если null передаётся для объекта, obj будет установлен в NULL. */ zval *obj; zval *arr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O!a", &obj, &arr) == FAILURE) { return; } /* Получить массив. */ zval *arr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &arr) == FAILURE) { return; } /* Получить только первые три параметра (используется для varargs-функций). */ zval *z; zend_bool b; zval *r; if (zend_parse_parameters(3, "zbr!", &z, &b, &r) == FAILURE) { return; } |
Обратите внимание, что в третьем примере мы передаём 3 для числа принимаемых получаемых параметров вместо ZEND_NUM_ARGS(). Это позволяет получать наименьшее количество параметров, если наша функция ожидает их переменное количество. Разумеется, если вы хотите работать с остальными параметрами, вы должны использовать zend_get_parameters_array_ex() для их получения.
Функция-разборщик имеет расширенную версию, которая имеет дополнительный аргумент flags, управляющий её работой.
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...); |
Единственный флаг, который в настоящее время можно передавать, это ZEND_PARSE_PARAMS_QUIET, который указывает функции не выводить никаких сообщений об ошибках в ходе операции. Это можно использовать в функциях, которые ожидают несколько наборов совершенно разных аргументов, но вам придётся самостоятельно выводить сообщение об ошибке.
Например, вот как можно получить набор из трёх long или строку:
long l1, l2, l3; char *s; if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "lll", &l1, &l2, &l3) == SUCCESS) { /* работа с long */ } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "s", &s, &s_len) == SUCCESS) { /* работа с string */ } else { php_error(E_WARNING, "%s() takes either three long values or a string as argument", get_active_function_name(TSRMLS_C)); return; } |
С помощью рассмотренных способов получения параметров функцией вы должны были получить хорошее представление об этом процессе. Дополнительные примеры см. в исходном коде расширений, которые поставляются с PHP - они иллюстрируют каждый представленный случай.
| ||||||
|
Нет комментариев. Ваш будет первым!