1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
|
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision: 297078 $ -->
<sect2 xml:id="internals2.ze1.zendapi.layout" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Source Layout</title>
<note>
<para>
Prior to working through the rest of this chapter, you should retrieve
clean, unmodified source trees of your favorite Web server. We're working with
Apache (available at
<link xlink:href="&url.apache;"/>)
and, of course, with PHP (available at
<link xlink:href="&url.php;"/> - does
it need to be said?).
</para>
<para>
Make sure that you can compile a working PHP environment by
yourself! We won't go into this issue here, however, as you should
already have this most basic ability when studying this chapter.
</para>
</note>
<para>
Before we start discussing code issues, you should familiarize
yourself with the source tree to be able to quickly navigate
through PHP's files. This is a must-have ability to implement and
debug extensions.
</para>
<!-- <para>
After extracting the PHP archive, you'll see a directory layout similar to that in <xref linkend='fig.dir-layout'/>.
</para>
<figure xml:id='fig.dir-layout'>
<title>Main directory layout of the PHP source tree.</title>
<graphic fileref="en/internals2/ze1/zendapi/figures/Extending_Zend_1a_Directory_Layout.png"/>
</figure> -->
<para>
The following table describes the contents of the major directories.
</para>
<informaltable>
<tgroup cols="2">
<colspec colnum="1" colname="col1" colwidth="1.00*"/>
<colspec colnum="2" colname="col2" colwidth="3.74*"/>
<tbody>
<row>
<entry colname="col1">Directory</entry>
<entry colname="col2">Contents</entry>
</row>
<row>
<entry colname="col1"><filename>php-src</filename></entry>
<entry colname="col2">
Main PHP source files and main header files; here you'll find
all of PHP's API definitions, macros, etc. (important).
Everything else is below this directory.
</entry>
</row>
<row>
<entry colname="col1"><filename>php-src/ext</filename></entry>
<entry colname="col2">
Repository for dynamic and built-in modules; by default, these
are the "official" PHP modules that have been integrated into
the main source tree. From PHP 4.0, it's possible to compile
these standard extensions as dynamic loadable modules (at
least, those that support it).
</entry>
</row>
<row>
<entry colname="col1"><filename>php-src/main</filename></entry>
<entry colname="col2">
This directory contains the main php macros and definitions. (important)
</entry>
</row>
<row>
<entry colname="col1"><filename>php-src/pear</filename></entry>
<entry colname="col2">
Directory for the PHP Extension and Application Repository. This directory contains
core PEAR files.
</entry>
</row>
<row>
<entry colname="col1"><filename>php-src/sapi</filename></entry>
<entry colname="col2">
Contains the code for the different server abstraction layers.
</entry>
</row>
<row>
<entry colname="col1"><filename>TSRM</filename></entry>
<entry colname="col2">
Location of the "Thread Safe Resource Manager" (TSRM) for Zend
and PHP.
</entry>
</row>
<row>
<entry colname="col1"><filename>ZendEngine2</filename></entry>
<entry colname="col2">
Location of the Zend Engine files; here you'll
find all of Zend's API definitions, macros, etc. (important).
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>
Discussing all the files included in the PHP package is beyond the
scope of this chapter. However, you should take a close look at the
following files:<itemizedlist>
<listitem>
<para>
<filename>php-src/main/php.h</filename>, located in the main PHP directory.
This file contains most of PHP's macro and API definitions.
</para>
</listitem>
<listitem>
<para>
<filename>php-src/Zend/zend.h</filename>, located in the main Zend directory.
This file contains most of Zend's macros and definitions.
</para>
</listitem>
<listitem>
<para>
<filename>php-src/Zend/zend_API.h</filename>, also located in the Zend
directory, which defines Zend's API.
</para>
</listitem>
</itemizedlist> You should also follow some sub-inclusions from
these files; for example, the ones relating to the Zend executor,
the PHP initialization file support, and such. After reading these
files, take the time to navigate around the package a little to see
the interdependencies of all files and modules - how they relate to
each other and especially how they make use of each other. This
also helps you to adapt to the coding style in which PHP is
authored. To extend PHP, you should quickly adapt to this style.
</para>
<sect3 xml:id="internals2.ze1.zendapi.layout.conventions">
<title>Extension Conventions</title>
<para>
Zend is built using certain conventions; to avoid breaking its
standards, you should follow the rules described in the following
sections.
</para>
</sect3>
<sect3 xml:id="internals2.ze1.zendapi.layout.macros">
<title>Macros</title>
<para>
For almost every important task, Zend ships predefined macros that
are extremely handy. The tables and figures in the following
sections describe most of the basic functions, structures, and
macros. The macro definitions can be found mainly in
<filename>zend.h</filename> and <filename>zend_API.h</filename>.
We suggest that you take a close look at these files after having
studied this chapter. (Although you can go ahead and read them
now, not everything will make sense to you yet.)
</para>
</sect3>
<sect3 xml:id="internals2.ze1.zendapi.layout.memory-management">
<title>Memory Management</title>
<para>
Resource management is a crucial issue, especially in server
software. One of the most valuable resources is memory, and memory
management should be handled with extreme care. Memory management
has been partially abstracted in Zend, and you should stick to
this abstraction for obvious reasons: Due to the abstraction, Zend
gets full control over all memory allocations. Zend is able to
determine whether a block is in use, automatically freeing unused
blocks and blocks with lost references, and thus prevent memory
leaks. The functions to be used are described in the following
table:
<informaltable>
<tgroup cols="2">
<colspec colnum="1" colname="col1" colwidth="1.00*"/>
<colspec colnum="2" colname="col2" colwidth="1.62*"/>
<tbody>
<row>
<entry colname="col1">Function</entry>
<entry colname="col2">Description</entry>
</row>
<row>
<entry colname="col1"><function>emalloc</function></entry>
<entry colname="col2">Serves as replacement for
<function>malloc</function>.</entry>
</row>
<row>
<entry colname="col1"><function>efree</function></entry>
<entry colname="col2">Serves as replacement for
<function>free</function>.</entry>
</row>
<row>
<entry colname="col1"><function>estrdup</function></entry>
<entry colname="col2">Serves as replacement for
<function>strdup</function>.</entry>
</row>
<row>
<entry colname="col1"><function>estrndup</function></entry>
<entry colname="col2">Serves as replacement for
<function>strndup</function>. Faster than
<function>estrdup</function> and binary-safe. This is the
recommended function to use if you know the string length
prior to duplicating it.</entry>
</row>
<row>
<entry colname="col1"><function>ecalloc</function></entry>
<entry colname="col2">Serves as replacement for
<function>calloc</function>.</entry>
</row>
<row>
<entry colname="col1"><function>erealloc</function></entry>
<entry colname="col2">Serves as replacement for
<function>realloc</function>.</entry>
</row>
</tbody>
</tgroup>
</informaltable> <function>emalloc</function>,
<function>estrdup</function>, <function>estrndup</function>,
<function>ecalloc</function>, and <function>erealloc</function>
allocate internal memory; <function>efree</function> frees these
previously allocated blocks. Memory handled by the
<function>e*</function> functions is considered local to the
current process and is discarded as soon as the script executed by
this process is terminated.
<warning>
<para>
To allocate resident memory that survives termination of
the current script, you can use <function>malloc</function> and
<function>free</function>. This should only be done with extreme
care, however, and only in conjunction with demands of the Zend
API; otherwise, you risk memory leaks.
</para>
</warning>
Zend also features a thread-safe resource manager to
provide better native support for multithreaded Web servers. This
requires you to allocate local structures for all of your global
variables to allow concurrent threads to be run. Because the
thread-safe mode of Zend was not finished back when this was written,
it is not yet extensively covered here.
</para>
</sect3>
<sect3 xml:id="internals2.ze1.zendapi.layout.dir-and-file">
<title>Directory and File Functions</title>
<para>
The following directory and file functions should be used in Zend
modules. They behave exactly like their C counterparts, but
provide virtual working directory support on the thread level.
<informaltable>
<tgroup cols="2">
<colspec colnum="1" colname="col1" colwidth="*"/>
<colspec colnum="2" colname="col2" colwidth="*"/>
<tbody>
<row>
<entry colname="col1">Zend Function</entry>
<entry colname="col2">Regular C Function</entry>
</row>
<row>
<entry colname="col1"><function>V_GETCWD</function></entry>
<entry colname="col2"><function>getcwd</function></entry>
</row>
<row>
<entry colname="col1"><function>V_FOPEN</function></entry>
<entry colname="col2"><function>fopen</function></entry>
</row>
<row>
<entry colname="col1"><function>V_OPEN</function></entry>
<entry colname="col2"><function>open</function></entry>
</row>
<row>
<entry colname="col1"><function>V_CHDIR</function></entry>
<entry colname="col2"><function>chdir</function></entry>
</row>
<row>
<entry colname="col1"><function>V_GETWD</function></entry>
<entry colname="col2"><function>getwd</function></entry>
</row>
<row>
<entry
colname="col1"><function>V_CHDIR_FILE</function></entry>
<entry colname="col2">
Takes a file path as an argument and changes the current
working directory to that file's directory.
</entry>
</row>
<row>
<entry colname="col1"><function>V_STAT</function></entry>
<entry colname="col2"><function>stat</function></entry>
</row>
<row>
<entry colname="col1"><function>V_LSTAT</function></entry>
<entry colname="col2"><function>lstat</function></entry>
</row>
</tbody>
</tgroup>
</informaltable></para>
</sect3>
<sect3 xml:id="internals2.ze1.zendapi.layout.string-handling">
<title>String Handling</title>
<para>
Strings are handled a bit differently by the Zend engine
than other values such as integers, Booleans, etc., which don't require
additional memory allocation for storing their values. If you want to
return a string from a function, introduce a new string variable to the symbol
table, or do something similar, you have to make sure that the memory the
string will be occupying has previously been allocated, using the
aforementioned <function>e*</function> functions for allocation. (This might
not make much sense to you yet; just keep it somewhere in your head for now - we'll get
back to it shortly.)
</para>
</sect3>
<sect3 xml:id="internals2.ze1.zendapi.layout.complex-types">
<title>Complex Types</title>
<para>
Complex types such as arrays and objects require
different treatment. Zend features a single API for these types - they're
stored using hash tables.
</para>
<note>
<para>
To reduce complexity in the following source examples, we're only
working with simple types such as integers at first. A discussion about
creating more advanced types follows later in this chapter.
</para>
</note>
</sect3>
</sect2>
<!-- 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:"~/.phpdoc/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
-->
|