|
Writing functionsOne core element of an extension are functions which are exported to the PHP userland. Even when you're planning to write object-oriented extensions you are advised to read this chapter as most of the information is valid for methods, too. When adding a function to an extension, for instance after using the ext_skel script to create the raw infrastructure, you can create a function by implementing it as a C function and then providing an entry for the extension's function table. The function entry can contain a pointer to an argument information structure. Providing this information ins not strictly necessary, unless you plan to accept parameters by reference or want to return a reference, but provides information that can be accessed via PHP's Reflection API. As you will see below the parameters aren't passed as direct function parameters to the implementation but passed on a stack, which is checked by the function's implementation which can't directly serve as source for this information. Пример #1 Minimal PHP extension with one function /* {{{ proto void hello_world() Do nothing */ PHP_FUNCTION(hello_world) { } /* }}} */ /* {{{ arginfo_hello_world */ ZEND_BEGIN_ARG_INFO(arginfo_hello_world, 0) ZEND_END_ARG_INFO() /* }}} */ /* {{{ demo_functions */ function_entry demo_functions[] = { PHP_FE(hello_world, arginfo_hello_world) {NULL, NULL, NULL} } /* }}} */ /* {{{ demo_module_enry */ zend_module_entry demo_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "demo", demo_functions, NULL, NULL, NULL, NULL, NULL, #if ZEND_MODULE_API_NO >= 20010901 "1.0.0", #en STANDARD_MODULE_PROPERTIES } /* }}} */ In this example you can see the above discussed elements and the module structure; if you don't remember this structure go back to The zend_module structure. The first part of this extension is the actual implementation. As a convention each exported function is preceded by a two line comment describing the function's userland prototype and a short one line comment.
For providing source code compatibility between different versions of PHP
the functions declaration is wrapped into the void zif_hello_world(int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC) { }
For preventing a naming conflict between a function exported to userland
and another C function with the same name the C symbol of the exported
function is prefixed with the prefix
As said the function shown above will simply return NULL to the user and do nothing else. The function can be called, from the PHP userland, with an arbitrary number of parameters. A more useful function consists of four parts in general:
In some cases the exact order of these steps may change. Especially the last two steps are often mixed up, but it's a good idea to stay in that order. Пример #2 A simple function /* {{{ proto void hello_world(string name) Greets a user */ PHP_FUNCTION(hello_world) { char *name; int name_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { return; } php_printf("Hello %s!", name); RETURN_TRUE; } /* }}} */
The function above shows these parts. Let's start the analysis with the
last lines:
The
The
The first parameter to
For compatibility with PHP's thread-isolation, the thread-safe resource
manager, we also have to pass the thread context using
Following the thread context the expected parameters are declared. Each
parameter is represented by a character in the string describing the type.
In our case we expect one parameter as a string so our type specification
is simply
Lastly one has to pass one or more pointers to C variables which should be
filled with the variable's value or provide more details. In the case of a
string we get the actual string, which will always be NULL-terminated, as a
A documentation of all type specifiers and the corresponding additional C types can be found in the file » README.PARAMETER_PARSING_API which is part of the source distribution. The most important types can be found in the table below.
|
|||||||||||||||||||||||||||||||||||||