- Added new section ("Basic constructs") detailing stuff you don't have to look at more than once.

- Wrote section on declaring per-module globals


git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@259907 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Gwynne Raskind 2008-05-18 10:55:25 +00:00
parent fd8e60ae7e
commit ac82dd2889
3 changed files with 195 additions and 2 deletions

View file

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- $Revision: 1.1 $ -->
<sect1 xml:id="internals2.structure.basics" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Basic constructs</title>
<simpara>
C is a very low-level language by modern definitions. This means that it has
no built-in support for many features that PHP takes for granted, such as
reflection, dynamic module loading, bounds checking, threadsafe data
management and various useful data structures including linked lists and
hash tables. At the same time, C is a common denominator of language support
and functionality. Given enough work, none of these concepts are impossible;
the Zend Engine uses them all.
</simpara>
<simpara>
A lot of effort has gone into making the Zend API both extensible and
understandable, but C forces certain necessary declarations upon any
extension that to an inexperienced eye seem redundant or plain unnecessary.
All of those constructs, detailed in this section, are "write once and
forget" in Zend Engine 2 and 3. Here are some excerpts from the pregenerated
<filename>php_counter.h</filename> and <filename>counter.c</filename> files
created by PHP 5.3's <command>ext_skel</command>, showing the pregenerated
declarations:
</simpara>
<note>
<simpara>
The astute reader will notice that there are several delcarations in the
real files that aren't shown here. Those declaractions are specific to
various Zend subsystems and are discussed elsewhere as appropriate.
</simpara>
</note>
<screen>
<![CDATA[
extern zend_module_entry counter_module_entry;
#define phpext_counter_ptr &counter_module_entry
#ifdef PHP_WIN32
# define PHP_COUNTER_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
# define PHP_COUNTER_API __attribute__ ((visibility("default")))
#else
# define PHP_COUNTER_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
]]></screen>
<screen>
<![CDATA[
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_counter.h"
/* ... */
#ifdef COMPILE_DL_COUNTER
ZEND_GET_MODULE(counter)
#endif
]]></screen>
<itemizedlist>
<listitem>
<simpara>
The lines concerning <literal>counter_module_entry</literal> declare a
global variable, and a macroed pointer to it, which contains the
<literal>zend_module_entry</literal> for the extension. Despite the later
discussion regarding the drawbacks of "true" globals, this usage is
intentional; Zend takes precautions to avoid misusing this variable.
</simpara>
</listitem>
<listitem>
<simpara>
<constant>PHP_COUNTER_API</constant> is declared for use by non-PHP
functions the module intends to export for the use of other modules. The
counter extension doesn't declare any of these, and in the final version of
the header file, this macro has been removed. The
<constant>PHPAPI</constant> macro is declared identically elsewhere and is
used by the standard extension to make the <function>phpinfo</function>
utility functions available to other extensions.
</simpara>
</listitem>
<listitem>
<simpara>
The include of <filename>TSRM.h</filename> is skipped if PHP, or the
extension, isn't being compiled with thread-safety, since in that case TSRM
isn't used.
</simpara>
</listitem>
<listitem>
<simpara>
A standard list of includes, especially the extension's own
<filename>php_counter.h</filename>, is given. <filename>config.h</filename>
gives the extension access to determinations made by
<command>configure</command>. <filename>php.h</filename> is the gateway to
the entire PHP and Zend APIs. <filename>php_ini.h</filename> adds the APIs
for runtime configuration (INI) entries. Not all extensions will use this.
Finally, <filename>ext/standard/info.h</filename> imports the
aforementioned <function>phpinfo</function> utility API.
</simpara>
</listitem>
<listitem>
<simpara>
<constant>COMPILE_DL_COUNTER</constant> will only be defined by
<command>configure</command> if the counter extension is both enabled and
wants to be built as a dynamically loadable module instead of being
statically linked into PHP. <constant>ZEND_GET_MODULE</constant> defines a
tiny function which Zend can use to get the extension's
<literal>zend_module_entry</literal> at runtime.
</simpara>
<note>
<simpara>
The astute reader who has peeked into
<filename>main/php_config.h</filename> after trying to build with the
counter module enabled statically may have noticed that there is also a
<constant>HAVE_COUNTER</constant> constant defined that the source code
doesn't check for. There's a simple reason this check isn't done: It's
unnecessary. If the extension isn't enabled, the source file will never be
compiled.
</simpara>
</note>
</listitem>
</itemizedlist>
</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
-->

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- $Revision: 1.2 $ -->
<!-- $Revision: 1.3 $ -->
<sect1 xml:id="internals2.structure.globals" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Extension globals</title>
@ -69,6 +69,44 @@ PHP_FUNCTION(counter_get)
</sect2>
<sect2 xml:id="internals2.structure.globals.declaring">
<title>Declaring module globals</title>
<simpara>
Whether a module uses only a single global or dozens, they must be defined
in a structure, and that structure must be declared. There are some macros
that assist with doing so in a way that avoids name conflicts between
modules: <function>ZEND_BEGIN_MODULE_GLOBALS</function>,
<function>ZEND_END_MODULE_GLOBALS</function>, and
<function>ZEND_DECLARE_MODULE_GLOBALS</function>. All three take as a
parameter the short name of the module, which in the case of the counter
module is simply <literal>"counter"</literal>. Here is the global structure
declaration from <filename>php_counter.h</filename>:
</simpara>
<example xml:id="internals2.structure.globals.declaring.doth">
<title>The counter module's globals</title>
<programlisting role="c">
<![CDATA[
ZEND_BEGIN_MODULE_GLOBALS(counter)
long basic_counter_value;
ZEND_END_MODULE_GLOBALS(counter)
]]>
</programlisting>
</example>
<simpara>
And this is the declaration from <filename>counter.c</filename>:
</simpara>
<example xml:id="internals2.structure.globals.declaring.dotc">
<title>The counter module's global structure declaration</title>
<programlisting role="c">
<![CDATA[
ZEND_DECLARE_MODULE_GLOBALS(counter)
]]>
</programlisting>
</example>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- $Revision: 1.3 $ -->
<!-- $Revision: 1.4 $ -->
<chapter xml:id="internals2.structure" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Extension structure</title>
@ -14,6 +14,7 @@
</para>
&internals2.structure.files;
&internals2.structure.basics;
&internals2.structure.modstruct;
&internals2.structure.globals;
&internals2.structure.lifecycle;