П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
Поиск по сайту:
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое








Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 3439 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 5995 раз(а).

Учебник HTML.
Просмотров 3220 раз(а).

Руководство по PHP5.
Просмотров 5441 раз(а).

Хостинг через призму DNS.
Просмотров 4050 раз(а).

Подборка текстов стандартных документов.
Просмотров 55723 раз(а).

Учебник PHP - Самоучитель
Просмотров 3020 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 4805 раз(а).

Внешние атаки...
Просмотров 3758 раз(а).

Учебник PHP.
Просмотров 2782 раз(а).

SSI в примерах.
Просмотров 37395 раз(а).



 
 
| Добавить в избранное | Сделать стартовой | Помощь





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

Глава 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>");
?>


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


Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
 





Copyright © 2005-2016 Project.Net.Ru