mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-27 06:18:56 +00:00

- PHP 3 development appendix moved to this part - Streams API docs moved to this part - ZendAPI docs with figures integrated in this part More info: http://news.php.net/php.doc/969369673 git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@194089 c90b9560-bf6c-de11-be94-00142212c4b1
712 lines
29 KiB
XML
712 lines
29 KiB
XML
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
|
<!-- $Revision: 1.1 $ -->
|
|
<sect1 id="zend.structure">
|
|
<title>Source Discussion</title>
|
|
<para>
|
|
Now that you've got a safe build environment and you're able to include
|
|
the modules into PHP files, it's time to discuss how everything works.
|
|
</para>
|
|
<sect2 id="zend.structure.module">
|
|
<title>Module Structure</title>
|
|
<para>
|
|
All PHP modules follow a common structure:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
Header file inclusions (to include all required macros, API
|
|
definitions, etc.)
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
C declaration of exported functions (required to declare the Zend
|
|
function block)
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Declaration of the Zend function block</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Declaration of the Zend module block</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Implementation of <function>get_module</function></para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Implementation of all exported functions</para>
|
|
</listitem>
|
|
</itemizedlist></para>
|
|
</sect2>
|
|
|
|
<sect2 id="zend.structure.headers">
|
|
<title>Header File Inclusions</title>
|
|
<para>
|
|
The only header file you really have to include for your modules is
|
|
<filename>php.h</filename>, located in the PHP directory. This file makes all
|
|
macros and API definitions required to build new modules available to your
|
|
code.
|
|
</para>
|
|
<para>
|
|
<emphasis>Tip:</emphasis> It's good practice to create a separate
|
|
header file for your module that contains module-specific
|
|
definitions. This header file should contain all the forward
|
|
definitions for exported functions and include
|
|
<filename>php.h</filename>. If you created your module using
|
|
<literal>ext_skel</literal> you already have such a header file
|
|
prepared.
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 id="zend.structure.exporting-functions">
|
|
<title>Declaring Exported Functions</title>
|
|
<para>
|
|
To declare functions that are to be exported (i.e., made available to PHP
|
|
as new native functions), Zend provides a set of macros. A sample declaration
|
|
looks like this:
|
|
<programlisting>
|
|
ZEND_FUNCTION ( my_function );
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
<literal>ZEND_FUNCTION</literal> declares a new C function that complies
|
|
with Zend's internal API. This means that the function is of
|
|
type <literal>void</literal> and
|
|
accepts <literal>INTERNAL_FUNCTION_PARAMETERS</literal> (another macro) as
|
|
parameters. Additionally, it prefixes the function name with
|
|
<literal>zif</literal>. The immediately expanded version of the above
|
|
definitions would look like this:
|
|
<programlisting>
|
|
void zif_my_function ( INTERNAL_FUNCTION_PARAMETERS );
|
|
</programlisting>
|
|
Expanding <literal>INTERNAL_FUNCTION_PARAMETERS</literal>
|
|
results in the following:
|
|
<programlisting>
|
|
void zif_my_function( int ht
|
|
, zval * return_value
|
|
, zval * this_ptr
|
|
, int return_value_used
|
|
, zend_executor_globals * executor_globals
|
|
);
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
Since the interpreter and executor core have been separated from
|
|
the main PHP package, a second API defining macros and function
|
|
sets has evolved: the Zend API. As the Zend API now handles quite
|
|
a few of the responsibilities that previously belonged to PHP, a
|
|
lot of PHP functions have been reduced to macros aliasing to calls
|
|
into the Zend API. The recommended practice is to use the Zend API
|
|
wherever possible, as the old API is only preserved for
|
|
compatibility reasons. For example, the types <envar>zval</envar>
|
|
and <envar>pval</envar> are identical. <envar>zval</envar> is
|
|
Zend's definition; <envar>pval</envar> is PHP's definition
|
|
(actually, <envar>pval</envar> is an alias for <envar>zval</envar>
|
|
now). As the macro <literal>INTERNAL_FUNCTION_PARAMETERS</literal>
|
|
is a Zend macro, the above declaration contains
|
|
<envar>zval</envar>. When writing code, you should always use
|
|
<envar>zval</envar> to conform to the new Zend API.
|
|
</para>
|
|
<para>
|
|
The parameter list of this declaration is very important; you should keep these parameters in mind (see <xref linkend='tab.parameters'/> for descriptions).
|
|
<table id='tab.parameters'>
|
|
<title>Zend's Parameters to Functions Called from PHP</title>
|
|
<tgroup cols="2">
|
|
<colspec colnum="1" colname="col1" colwidth="1.00*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1.79*"/>
|
|
<tbody>
|
|
<row>
|
|
<entry colname="col1">Parameter</entry>
|
|
<entry colname="col2">Description</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>ht</envar></entry>
|
|
<entry colname="col2">
|
|
The number of arguments passed to the Zend function.
|
|
You should not touch this directly, but instead use ZEND_NUM_ARGS() to obtain the
|
|
value.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1">
|
|
<envar>return_value</envar></entry>
|
|
<entry colname="col2">
|
|
This variable is used to pass any return values of
|
|
your function back to PHP. Access to this variable is best done using the
|
|
predefined macros. For a description of these see below.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>this_ptr</envar></entry>
|
|
<entry colname="col2">
|
|
Using this variable, you can gain access to the object
|
|
in which your function is contained, if it's used within an object. Use
|
|
the function <function>getThis</function> to obtain this pointer.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>return_value_used</envar></entry>
|
|
<entry colname="col2">
|
|
This flag indicates whether an eventual return value
|
|
from this function will actually be used by the calling script.
|
|
<literal>0</literal> indicates that the return value is not used;
|
|
<literal>1</literal> indicates that the caller expects a return value.
|
|
Evaluation of this flag can be done to verify correct usage of the function as
|
|
well as speed optimizations in case returning a value requires expensive
|
|
operations (for an example, see how <filename>array.c</filename> makes use of
|
|
this).
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>executor_globals</envar></entry>
|
|
<entry colname="col2">
|
|
This variable points to global settings of the Zend
|
|
engine. You'll find this useful when creating new variables, for example
|
|
(more about this later). The executor globals can also be introduced to your
|
|
function by using the macro <literal>TSRMLS_FETCH()</literal>.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 id="zend.structure.function-block">
|
|
<title>Declaration of the Zend Function Block</title>
|
|
<para>
|
|
Now that you have declared the functions to be exported, you also
|
|
have to introduce them to Zend. Introducing the list of functions is done by
|
|
using an array of <envar>zend_function_entry</envar>. This array consecutively
|
|
contains all functions that are to be made available externally, with the function's name
|
|
as it should appear in PHP and its name as defined in the C source.
|
|
Internally, <envar>zend_function_entry</envar> is defined as shown in
|
|
<xref linkend='example.zend-function-entry'/>.
|
|
</para>
|
|
<para>
|
|
<example id='example.zend-function-entry'>
|
|
<title>Internal declaration of <envar>zend_function_entry</envar>.</title>
|
|
<programlisting>
|
|
typedef struct _zend_function_entry {
|
|
char *fname;
|
|
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
|
|
unsigned char *func_arg_types;
|
|
} zend_function_entry;
|
|
</programlisting>
|
|
<informaltable>
|
|
<tgroup cols="2">
|
|
<colspec colnum="1" colname="col1" colwidth="1.00*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1.82*"/>
|
|
<tbody>
|
|
<row>
|
|
<entry colname="col1">Entry</entry>
|
|
<entry colname="col2">Description</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>fname</envar></entry>
|
|
<entry colname="col2">
|
|
Denotes the function name as seen in PHP (for
|
|
example, <literal>fopen</literal>, <literal>mysql_connect</literal>, or, in our
|
|
example, <literal>first_module</literal>).
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>handler</envar></entry>
|
|
<entry colname="col2">
|
|
Pointer to the C function responsible for handling calls
|
|
to this function. For example, see the standard macro
|
|
<literal>INTERNAL_FUNCTION_PARAMETERS</literal> discussed earlier.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>func_arg_types</envar></entry>
|
|
<entry colname="col2">
|
|
Allows you to mark certain parameters so that they're forced
|
|
to be passed by reference. You usually should set this to
|
|
NULL.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</example>
|
|
In the example above, the declaration looks like this:
|
|
<programlisting>
|
|
zend_function_entry firstmod_functions[] =
|
|
{
|
|
ZEND_FE(first_module, NULL)
|
|
{NULL, NULL, NULL}
|
|
};
|
|
</programlisting>
|
|
You can see that the last entry in the list always has to be
|
|
<literal>{NULL, NULL, NULL}</literal>.
|
|
This marker has to be set for Zend to know when the end of the
|
|
list of exported functions is reached.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
You <emphasis>cannot</emphasis> use the predefined macros for the
|
|
end marker, as these would try to refer to a function named "NULL"!
|
|
</para>
|
|
</note>
|
|
<para>
|
|
The macro <literal>ZEND_FE</literal> (short for 'Zend Function
|
|
Entry') simply expands to a structure entry in
|
|
<envar>zend_function_entry</envar>. Note that these macros
|
|
introduce a special naming scheme to your functions - your C
|
|
functions will be prefixed with <literal>zif_</literal>, meaning
|
|
that <literal>ZEND_FE(first_module)</literal> will refer to a C
|
|
function <function>zif_first_module</function>. If you want to mix
|
|
macro usage with hand-coded entries (not a good practice), keep
|
|
this in mind.
|
|
</para>
|
|
<para>
|
|
Tip: Compilation errors that refer to functions
|
|
named <function>zif_*</function> relate to functions defined
|
|
with <literal>ZEND_FE</literal>.
|
|
</para>
|
|
<para>
|
|
<xref linkend='tab.funcdef-macros'/> shows a list of all the macros
|
|
that you can use to define functions.
|
|
</para>
|
|
<table id='tab.funcdef-macros'>
|
|
<title>Macros for Defining Functions</title>
|
|
<tgroup cols="2">
|
|
<colspec colnum="1" colname="col1" colwidth="1.00*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1.08*"/>
|
|
<tbody>
|
|
<row>
|
|
<entry colname="col1">Macro Name</entry>
|
|
<entry colname="col2">Description</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><literal>ZEND_FE(name, arg_types)</literal></entry>
|
|
<entry colname="col2">
|
|
Defines a function entry of the name <envar>name</envar> in
|
|
<envar>zend_function_entry</envar>. Requires a corresponding C
|
|
function. <envar>arg_types</envar> needs to be set to <literal>NULL</literal>.
|
|
This function uses automatic C function name generation by prefixing the PHP
|
|
function name with <literal>zif_</literal>.
|
|
For example, <literal>ZEND_FE("first_module", NULL)</literal> introduces a
|
|
function <function>first_module</function> to PHP and links it to the C
|
|
function <function>zif_first_module</function>. Use in conjunction
|
|
with <literal>ZEND_FUNCTION</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1">
|
|
<literal>ZEND_NAMED_FE(php_name, name, arg_types)</literal>
|
|
</entry>
|
|
<entry colname="col2">
|
|
Defines a function that will be available to PHP by the
|
|
name <envar>php_name</envar> and links it to the corresponding C
|
|
function <envar>name</envar>. <envar>arg_types</envar> needs to be set
|
|
to <literal>NULL</literal>. Use this function if you don't want the automatic
|
|
name prefixing introduced by <literal>ZEND_FE</literal>. Use in conjunction
|
|
with <literal>ZEND_NAMED_FUNCTION</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1">
|
|
<literal>ZEND_FALIAS(name, alias, arg_types)</literal>
|
|
</entry>
|
|
<entry colname="col2">
|
|
Defines an alias named <envar>alias</envar> for
|
|
<envar>name</envar>. <envar>arg_types</envar> needs to be set
|
|
to <literal>NULL</literal>. Doesn't require a corresponding C
|
|
function; refers to the alias target instead.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><literal>PHP_FE(name, arg_types)</literal></entry>
|
|
<entry colname="col2">
|
|
Old PHP API equivalent of <literal>ZEND_FE</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1">
|
|
<literal>PHP_NAMED_FE(runtime_name, name, arg_types)</literal>
|
|
</entry>
|
|
<entry colname="col2">
|
|
Old PHP API equivalent of <literal>ZEND_NAMED_FE</literal>.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
<emphasis>Note:</emphasis> You can't use
|
|
<literal>ZEND_FE</literal> in conjunction with
|
|
<literal>PHP_FUNCTION</literal>, or <literal>PHP_FE</literal> in
|
|
conjunction with <literal>ZEND_FUNCTION</literal>. However, it's
|
|
perfectly legal to mix <literal>ZEND_FE</literal> and
|
|
<literal>ZEND_FUNCTION</literal> with <literal>PHP_FE</literal>
|
|
and <literal>PHP_FUNCTION</literal> when staying with the same
|
|
macro set for each function to be declared. But mixing is
|
|
<emphasis>not</emphasis> recommended; instead, you're advised to
|
|
use the <literal>ZEND_*</literal> macros only.
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 id="zend.structure.module-block">
|
|
<title>Declaration of the Zend Module Block</title>
|
|
<para>
|
|
This block is stored in the structure
|
|
<envar>zend_module_entry</envar> and contains all necessary
|
|
information to describe the contents of this module to Zend. You can
|
|
see the internal definition of this module in
|
|
<xref linkend='example.zend-module-entry'/>.
|
|
</para>
|
|
<example id='example.zend-module-entry'>
|
|
<title>Internal declaration of <envar>zend_module_entry</envar>.</title>
|
|
<programlisting>
|
|
typedef struct _zend_module_entry zend_module_entry;
|
|
|
|
struct _zend_module_entry {
|
|
unsigned short size;
|
|
unsigned int zend_api;
|
|
unsigned char zend_debug;
|
|
unsigned char zts;
|
|
char *name;
|
|
zend_function_entry *functions;
|
|
int (*module_startup_func)(INIT_FUNC_ARGS);
|
|
int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
|
|
int (*request_startup_func)(INIT_FUNC_ARGS);
|
|
int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
|
|
void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
|
|
char *version;
|
|
|
|
[ Rest of the structure is not interesting here ]
|
|
|
|
};
|
|
</programlisting>
|
|
<informaltable>
|
|
<tgroup cols="2">
|
|
<colspec colnum="1" colname="col1" colwidth="1.00*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1.69*"/>
|
|
<thead>
|
|
<row>
|
|
<entry colname="col1">Entry</entry>
|
|
<entry colname="col2">Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry colname="col1">
|
|
<envar>size</envar>, <envar>zend_api</envar>,
|
|
<envar>zend_debug</envar> and <envar>zts</envar>
|
|
</entry>
|
|
<entry colname="col2">
|
|
Usually filled with the
|
|
<literal>"STANDARD_MODULE_HEADER"</literal>, which fills these
|
|
four members with the size of the whole zend_module_entry, the
|
|
<literal>ZEND_MODULE_API_NO</literal>, whether it is a debug
|
|
build or normal build (<literal>ZEND_DEBUG</literal>) and if
|
|
ZTS is enabled (<literal>USING_ZTS</literal>).
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>name</envar></entry>
|
|
<entry colname="col2">
|
|
Contains the module name (for example, <literal>"File
|
|
functions"</literal>, <literal>"Socket functions"</literal>,
|
|
<literal>"Crypt"</literal>, etc.). This name will show up in
|
|
<function>phpinfo</function>, in the section "Additional
|
|
Modules."
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>functions</envar></entry>
|
|
<entry colname="col2">
|
|
Points to the Zend function block, discussed in the preceding
|
|
section.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>module_startup_func</envar></entry>
|
|
<entry colname="col2">
|
|
This function is called once upon module initialization and can
|
|
be used to do one-time initialization steps (such as initial
|
|
memory allocation, etc.). To indicate a failure during
|
|
initialization, return <literal>FAILURE</literal>; otherwise,
|
|
<literal>SUCCESS</literal>. To mark this field as unused, use
|
|
<literal>NULL</literal>. To declare a function, use the macro
|
|
<literal>ZEND_MINIT</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>module_shutdown_func</envar></entry>
|
|
<entry colname="col2">
|
|
This function is called once upon module shutdown and can be
|
|
used to do one-time deinitialization steps (such as memory
|
|
deallocation). This is the counterpart to
|
|
<function>module_startup_func</function>. To indicate a failure
|
|
during deinitialization, return <literal>FAILURE</literal>;
|
|
otherwise, <literal>SUCCESS</literal>. To mark this field as
|
|
unused, use <literal>NULL</literal>. To declare a function, use
|
|
the macro <literal>ZEND_MSHUTDOWN</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>request_startup_func</envar></entry>
|
|
<entry colname="col2">
|
|
This function is called once upon every page request and can be
|
|
used to do one-time initialization steps that are required to
|
|
process a request. To indicate a failure here, return
|
|
<literal>FAILURE</literal>; otherwise,
|
|
<literal>SUCCESS</literal>. <emphasis>Note:</emphasis> As
|
|
dynamic loadable modules are loaded only on page requests, the
|
|
request startup function is called right after the module
|
|
startup function (both initialization events happen at the same
|
|
time). To mark this field as unused, use
|
|
<literal>NULL</literal>. To declare a function, use the macro
|
|
<literal>ZEND_RINIT</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>request_shutdown_func</envar></entry>
|
|
<entry colname="col2">
|
|
This function is called once after every page request and works
|
|
as counterpart to <function>request_startup_func</function>. To
|
|
indicate a failure here, return <literal>FAILURE</literal>;
|
|
otherwise, <literal>SUCCESS</literal>.
|
|
<emphasis>Note:</emphasis> As dynamic loadable modules are
|
|
loaded only on page requests, the request shutdown function is
|
|
immediately followed by a call to the module shutdown handler
|
|
(both deinitialization events happen at the same time). To mark
|
|
this field as unused, use <literal>NULL</literal>. To declare a
|
|
function, use the macro <literal>ZEND_RSHUTDOWN</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>info_func</envar></entry>
|
|
<entry colname="col2">
|
|
When <function>phpinfo</function> is called in a script, Zend
|
|
cycles through all loaded modules and calls this function.
|
|
Every module then has the chance to print its own "footprint"
|
|
into the output page. Generally this is used to dump
|
|
environmental or statistical information. To mark this field as
|
|
unused, use <literal>NULL</literal>. To declare a function, use
|
|
the macro <literal>ZEND_MINFO</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><envar>version</envar></entry>
|
|
<entry colname="col2">
|
|
The version of the module. You can use
|
|
<literal>NO_VERSION_YET</literal> if you don't want to give the
|
|
module a version number yet, but we really recommend that you
|
|
add a version string here. Such a version string can look like
|
|
this (in chronological order): <literal>"2.5-dev"</literal>,
|
|
<literal>"2.5RC1"</literal>, <literal>"2.5"</literal> or
|
|
<literal>"2.5pl3"</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1">Remaining structure elements</entry>
|
|
<entry colname="col2">
|
|
These are used internally and can be prefilled by using the
|
|
macro <literal>STANDARD_MODULE_PROPERTIES_EX</literal>. You
|
|
should not assign any values to them. Use
|
|
<literal>STANDARD_MODULE_PROPERTIES_EX</literal> only if you
|
|
use global startup and shutdown functions; otherwise, use
|
|
<literal>STANDARD_MODULE_PROPERTIES</literal> directly.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</example>
|
|
<para>
|
|
In our example, this structure is implemented as follows:
|
|
<programlisting>
|
|
zend_module_entry firstmod_module_entry =
|
|
{
|
|
STANDARD_MODULE_HEADER,
|
|
"First Module",
|
|
firstmod_functions,
|
|
NULL, NULL, NULL, NULL, NULL,
|
|
NO_VERSION_YET,
|
|
STANDARD_MODULE_PROPERTIES,
|
|
};
|
|
</programlisting>
|
|
This is basically the easiest and most minimal set of values you
|
|
could ever use. The module name is set to <literal>First
|
|
Module</literal>, then the function list is referenced, after which
|
|
all startup and shutdown functions are marked as being unused.
|
|
</para>
|
|
<para>
|
|
For reference purposes, you can find a list of the macros involved
|
|
in declared startup and shutdown functions in
|
|
<xref linkend='tab.init-shutdown'/>. These are
|
|
not used in our basic example yet, but will be demonstrated later
|
|
on. You should make use of these macros to declare your startup and
|
|
shutdown functions, as these require special arguments to be passed
|
|
(<literal>INIT_FUNC_ARGS</literal> and
|
|
<literal>SHUTDOWN_FUNC_ARGS</literal>), which are automatically
|
|
included into the function declaration when using the predefined
|
|
macros. If you declare your functions manually and the PHP
|
|
developers decide that a change in the argument list is necessary,
|
|
you'll have to change your module sources to remain compatible.
|
|
</para>
|
|
<table id='tab.init-shutdown'>
|
|
<title>Macros to Declare Startup and Shutdown Functions</title>
|
|
<tgroup cols="2">
|
|
<colspec colnum="1" colname="col1" colwidth="1.00*"/>
|
|
<colspec colnum="2" colname="col2" colwidth="1.41*"/>
|
|
<tbody>
|
|
<row>
|
|
<entry colname="col1">Macro</entry>
|
|
<entry colname="col2">Description</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><literal>ZEND_MINIT(module)</literal></entry>
|
|
<entry colname="col2">
|
|
Declares a function for module startup. The generated name will
|
|
be <literal>zend_minit_<module></literal> (for example,
|
|
<literal>zend_minit_first_module</literal>). Use in
|
|
conjunction with <literal>ZEND_MINIT_FUNCTION</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><literal>ZEND_MSHUTDOWN(module)</literal></entry>
|
|
<entry colname="col2">
|
|
Declares a function for module shutdown. The generated name
|
|
will be <literal>zend_mshutdown_<module></literal> (for
|
|
example, <literal>zend_mshutdown_first_module</literal>). Use
|
|
in conjunction with <literal>ZEND_MSHUTDOWN_FUNCTION</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><literal>ZEND_RINIT(module)</literal></entry>
|
|
<entry colname="col2">
|
|
Declares a function for request startup. The generated name
|
|
will be <literal>zend_rinit_<module></literal> (for
|
|
example, <literal>zend_rinit_first_module</literal>). Use in
|
|
conjunction with <literal>ZEND_RINIT_FUNCTION</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><literal>ZEND_RSHUTDOWN(module)</literal></entry>
|
|
<entry colname="col2">
|
|
Declares a function for request shutdown. The generated name
|
|
will be <literal>zend_rshutdown_<module></literal> (for
|
|
example, <literal>zend_rshutdown_first_module</literal>). Use
|
|
in conjunction with <literal>ZEND_RSHUTDOWN_FUNCTION</literal>.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry colname="col1"><literal>ZEND_MINFO(module)</literal></entry>
|
|
<entry colname="col2">
|
|
Declares a function for printing module information, used when
|
|
<function>phpinfo</function> is called. The generated name will
|
|
be <literal>zend_info_<module></literal> (for example,
|
|
<literal>zend_info_first_module</literal>). Use in conjunction
|
|
with <literal>ZEND_MINFO_FUNCTION</literal>.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</sect2>
|
|
|
|
<sect2 id="zend.structure.get-module">
|
|
<title>Creation of <function>get_module</function></title>
|
|
<para>
|
|
This function is special to all dynamic loadable modules. Take a
|
|
look at the creation via the <literal>ZEND_GET_MODULE</literal>
|
|
macro first:
|
|
</para>
|
|
<programlisting>
|
|
#if COMPILE_DL_FIRSTMOD
|
|
ZEND_GET_MODULE(firstmod)
|
|
#endif
|
|
</programlisting>
|
|
<para>
|
|
The function implementation is surrounded by a conditional
|
|
compilation statement. This is needed since the function
|
|
<function>get_module</function> is only required if your module is
|
|
built as a dynamic extension. By specifying a definition of
|
|
<literal>COMPILE_DL_FIRSTMOD</literal> in the compiler command
|
|
(see above for a discussion of the compilation instructions
|
|
required to build a dynamic extension), you can instruct your
|
|
module whether you intend to build it as a dynamic extension or as
|
|
a built-in module. If you want a built-in module, the
|
|
implementation of <function>get_module</function> is simply left
|
|
out.
|
|
</para>
|
|
<para>
|
|
<function>get_module</function> is called by Zend at load time
|
|
of the module. You can think of it as being invoked by the
|
|
<function>dl</function> call in your script. Its purpose is to pass the
|
|
module information block back to Zend in order to inform the engine about the
|
|
module contents.
|
|
</para>
|
|
<para>
|
|
If you don't implement a <function>get_module</function> function in
|
|
your dynamic loadable module, Zend will compliment you with an error message
|
|
when trying to access it.
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 id="zend.structure.implementation">
|
|
<title>Implementation of All Exported Functions</title>
|
|
<para>Implementing the exported functions is the final step. The
|
|
example function in <literal>first_module</literal> looks like this:
|
|
<programlisting>
|
|
ZEND_FUNCTION(first_module)
|
|
{
|
|
long parameter;
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &parameter) == FAILURE) {
|
|
return;
|
|
}
|
|
|
|
RETURN_LONG(parameter);
|
|
}
|
|
</programlisting>
|
|
The function declaration is done
|
|
using <literal>ZEND_FUNCTION</literal>, which corresponds
|
|
to <literal>ZEND_FE</literal> in the function entry table (discussed
|
|
earlier).
|
|
</para>
|
|
<para>
|
|
After the declaration, code for checking and retrieving the function's
|
|
arguments, argument conversion, and return value generation follows (more on
|
|
this later).
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 id="zend.structure.summary">
|
|
<title>Summary</title>
|
|
<para>
|
|
That's it, basically - there's nothing more to implementing PHP modules.
|
|
Built-in modules are structured similarly to dynamic modules, so, equipped
|
|
with the information presented in the previous sections, you'll be able to
|
|
fight the odds when encountering PHP module source files.
|
|
</para>
|
|
<para>
|
|
Now, in the following sections, read on about how to make use of PHP's
|
|
internals to build powerful extensions.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"../../../manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|