Можно ли вызвать PHP_FUNCTION из расширения - PullRequest
3 голосов
/ 01 сентября 2010

позвольте мне подробнее остановиться на названии.Рассмотрим, например, PHP_FUNCTION (session_start).Смогу ли я вызвать session_start из session_id, который является другим PHP_FUNCTION (это только для иллюстрации, а не для реальной цели)?

Ответы [ 2 ]

6 голосов
/ 01 сентября 2010

Ну, да, но вы должны избегать этого как можно больше.Одним из основных преимуществ написания внутренних реализаций функций является то, что, в отличие от того, что происходит в PHP, вызовы функций C дешевы.Кроме того, внутренний вызов функций PHP в коде C является довольно болезненным.

Например, в случае session_start, у вас есть php_session_start, что раскрывается расширением сеанса.Вследствие того, что я описал в первом абзаце, расширения обычно экспортируют функции Си, которые могут быть полезны для других.

Фактически, внутренняя функция PHP foo необходима для вызова внутренней функции PHP bar,лучшая стратегия, если это возможно, заключалась бы в определении вспомогательной (не PHP_FUNCTION) C-функции с большей частью реализации bar.Тогда и PHP_FUNCTION(foo), и PHP_FUNCTION(bar) могут вызывать эту вспомогательную функцию.

В любом случае, самый простой способ вызова функций PHP - это использовать call_user_function:

int call_user_function(HashTable *function_table, zval **object_pp,
    zval *function_name, zval *retval_ptr, zend_uint param_count,
    zval *params[] TSRMLS_DC);

Вариант call_user_function_ex также позволяет запретить разделение, когда аргумент должен отправляться по ссылке, если это не так, и указание таблицы символов.

Это будет работать как в том случае, если соответствующая функция является внутренней (PHP_FUNCTION) или определена в пространстве пользователя.Если это обычная функция, вы должны использовать EG(function_table) в качестве первого аргумента, второй должен быть NULL, и я думаю, что вы можете выяснить другие.

Если вы выполняете функцию несколько раз, это не оченьэффективный.В этом случае см. Функции в "Zend_API.h" , которые начинаются с zend_fcall_.

. Я бы не рекомендовал другие параметры для вызова внутренних функций, такие как ручная настройкастек аргументов и другие хитрости, а также их ручной вызов базовой функции C.

0 голосов
/ 01 сентября 2010

т. session_start(session_id())

Да, однако в этом случае это не имеет смысла, поскольку session_id() требует, чтобы сессия уже была запущена.

...