是否可以从扩展中调用PHP_FUNCTION
let me elaborate more on the Title. Consider for example PHP_FUNCTION(session_start). Will I be able to invoke session_start from within session_id which is another PHP_FUNCTION (this is just for illustration not the actual purpose)?
让我详细说明标题。 考虑例如PHP_FUNCTION(session_start)。 我是否能够在session_id中调用session_start,这是另一个PHP_FUNCTION(这只是为了说明而不是实际目的)? p> div>
Well, yes, but you should avoid it as much as possible. One of the main benefits of writing internal implementations of functions is that, contrary to what happens in PHP, C function calls are cheap. Additionally, calling PHP functions internally in C code is relatively painful.
For instance, in the case of session_start
, you have php_session_start
, which is exposed by the session extension. Owing to what I described in the first paragraph, extensions will usually export C functions that may be useful to others.
In fact, the internal PHP function foo
needed to call the internal PHP function bar
, the best strategy, if possible, would be to define an auxiliary (non PHP_FUNCTION
) C function with most of the implementation of bar
. Then both PHP_FUNCTION(foo)
and PHP_FUNCTION(bar)
could call that auxiliary function.
Anyway, the easiest way to call PHP functions is to use 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);
The variant call_user_function_ex
also allows prohibiting separation when the argument should be sent by reference by it's not and specifying a symbol table.
This will work both if the relevant function is internal (PHP_FUNCTION
) or was defined in userspace. If it's a regular function, you should use EG(function_table)
as the first argument, the second should be NULL and I think you can figure out the others.
If you execute the function several times, this is not very efficient. In that case, see the functions in "Zend_API.h" that start with zend_fcall_
.
I wouldn't recommend other options to call internal functions, such as manually setting up the arguments stack and other trickery and them manually calling the underlying C function.
ie. session_start(session_id())
Yes, however in this case it doesn't make sense because session_id()
requires the session to already be started.