Новые книги

Автор сообщает интересные, зачастую уникальные сведения об организационной структуре Apple, режиме секретности, стратегии и тактике компании, личности и стиле руководства ее основателя Стива Джобса. Рассказывает, как рождаются «яблочные» шедевры. Анализирует, каким образом небольшая фирма, пренебрегающая традиционными методами управления, сумела стать технологическим гигантом и при этом сохранить дух стартапа. Рассуждает, какое будущее ждет Apple без Стива Джобса. Книга адресована поклонникам Apple, бизнесменам, всем, кто мечтает найти свою «формулу успеха».
Инсайдерское откровение о том, как один человек построил мировую корпорацию, способную противостоять таким гигантам как Walmart и Amazon.

Всего за десять лет Джек Ма, бывший преподаватель английского, основал и построил Alibaba Group, в которую сегодня входят: Alibaba.com, Alibaba Pictures, AliExpress.com, Taobao.com, Tmall.com, Alipay и другие.

Джек Ма – Рокфеллер XXI века, акции Alibaba в 2014 году побили рекорды, достигнув 25 млрд долларов.

Перед вами история компании и самого Джека, иконы частного предпринимательства и привратника миллионов потребителей от китайского Ханчжоу до тверского Торжка.

Вызов Пользовательских Функций

Учебник РНР
Назад Вперёд

Глава 39. Вызов пользовательских функций

Вы можете вызывать пользовательские функции из ваших модулей, что очень удобно при реализации callbacks/обратных вызовов; например, для прохода по массиву, поиска или просто для программ на базе событий.

Пользовательские функции можно вызывать функцией call_user_function_ex(). Необходимы: hash-значение для таблицы функции, доступ к которой вы хотите получить, указатель на объект (если хотите вызвать метод), имя функции, return-значение, количество аргументов, массив аргументов и флаг, указывающий, хотите ли вы использовать zval-сепарацию.

ZEND_API int call_user_function_ex(HashTable *function_table, zval *object,
                                   zval *function_name, zval **retval_ptr_ptr,
                                   int param_count, zval **params[],
                                   int no_separation);

Заметьте, что вы не должны специфицировать и function_table, и object; нужен только один из них. Если вы хотите вызвать метод, вы должны предоставить объект, который содержит этот метод, при этом call_user_function() автоматически устанавливает таблицу функции на таблицу функции этого объекта. Иначе вам необходимо специфицировать только function_table и можно установить object в NULL.

Обычно по умолчанию таблица функции это таблица "корневой" функции, содержащая вхождения всех функций. Эта таблица функции является частью глобалов компилятора, и доступ к ней может быть обеспечен макросом CG. Для введения глобалов компилятора в вашу функцию, вызовите однократно макрос CLS_FETCH.

Имя функции специфицируется в zval-контейнере. На первый взгляд это может показаться необычным, но это довольно логичный шаг, поскольку в большинстве случаев вы будете принимать имена функций как параметры вызывающих функций в вашем скрипте, которые в свою очередь также содержаться в zval-контейнерах. Таким образом, вы должны лишь передать ваши аргументы этой функции. Этот zval обязан иметь тип IS_STRING.

Следующий аргумент это указатель на return-значение. Вы не должны выделять память для этого контейнера; функция сделает это сама. Однако вы должны уничтожить этот контейнер (используя zval_dtor()) впоследствии!

Затем идёт целочисленный parameter_count и массив, содержащий все необходимые параметры. Последний аргумент специфицирует, должна ли функция выполнять zval-сепарацию - он должен всегда быть установлен в 0. Если он установлен в 1, функция потребляет меньше памяти, но терпит неудачу, если любой из параметров требует сепарации.

Листинг 9.16 и Рисунок 9.11 показывают вызов пользовательской функции. Этот код вызывает функцию, которая предоставлена как аргумент, и непосредственно передаёт return-значение этой функции как своё собственное return-значение. Обратите внимание на использование вызовов конструктора и деструктора в конце - это может быть и не обязательно здесь (так как они являются раздельными значениями, и присвоение проходит безопасно), но так 100-процентно надёжнее.

Рисунок 39-1. Листинг 9.16. Вызов пользовательской функции.
zval **function_name;
zval *retval;

if((ZEND_NUM_ARGS() != 1) || (zend_get_parameters_ex(1, &function_name) != SUCCESS))
{
    WRONG_PARAM_COUNT;
}

if((*function_name)->type != IS_STRING)
{
    zend_error(E_ERROR, "Функция requires string argument");
}

CLS_FETCH();

if(call_user_function_ex(CG(function_table), NULL, *function_name, &retval, 0, NULL, 0) != SUCCESS)
{
    zend_error(E_ERROR, "Функция call failed");
}

zend_printf("We have %i as type<br>", retval->type);

*return_value = *retval;
zval_copy_ctor(return_value);
zval_ptr_dtor();
 
<?php

dl("call_userland.so");

function test_function()
{

    print("We are in the test function!<br>");

    return("hello");

}

$return_value = call_userland("test_function");

print("Return value: \"$return_value\"<br>");
?>


НазадОглавление Вперёд
Функции старта и остановаВверх Поддержка файла инициализации