<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Abhi&#039;s Weblog &#187; PHP Extension</title>
	<atom:link href="http://abhinavsingh.com/blog/tag/php-extension/feed/" rel="self" type="application/rss+xml" />
	<link>http://abhinavsingh.com/blog</link>
	<description>PHP, Memcached, XMPP and Web Development</description>
	<lastBuildDate>Sat, 04 Sep 2010 10:58:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP tokens and opcodes : 3 useful extensions for understanding the working of Zend Engine</title>
		<link>http://abhinavsingh.com/blog/2009/11/php-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine/</link>
		<comments>http://abhinavsingh.com/blog/2009/11/php-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 02:35:12 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Opcode]]></category>
		<category><![CDATA[PHP Core]]></category>
		<category><![CDATA[PHP Extension]]></category>
		<category><![CDATA[Zend Engine]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=552</guid>
		<description><![CDATA[
			
				
			
		
&#8220;PHP tokens and opcodes&#8221; &#8211; When a PHP script is executed it goes through a number of processes, before the final result is displayed. These processes are namely: Lexing, Parsing, Compiling and Executing. In this blog post, I will walk you through all these processes with a sample example. In the end I will list [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2009%2F11%2Fphp-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2009%2F11%2Fphp-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine%2F&amp;source=imoracle&amp;style=normal&amp;service=bit.ly&amp;service_api=R_f027b5a79a20a49b713f16282f1e0857&amp;hashtags=Opcode,PHP,PHP+Core,PHP+Extension,Zend+Engine" height="61" width="50" /><br />
			</a>
		</div>
<p>&#8220;PHP tokens and opcodes&#8221; &#8211; When a PHP script is executed it goes through a number of processes, before the final result is displayed. These processes are namely: Lexing, Parsing, Compiling and Executing. In this blog post, I will walk you through all these processes with a sample example. In the end I will list some useful PHP extensions, which can be used to analyze results of every intermediate process.</p>
<p>Lets take a sample PHP script as an example:</p>
<pre name="code" class="php">&lt;?php
	function increment($a) {
		return $a+1;
	}
	$a = 3;
	$b = increment($a);
	echo $b;
?&gt;
</pre>
<p>Try running this script through command line:</p>
<pre name="code" class="php">~ sabhinav$ php -r debug.php
4
</pre>
<p>This PHP script goes through the following processes before outputting the result:</p>
<ul>
<li><u>Lexing</u>: The php code inside debug.php is converted into tokens</li>
<li><u>Parsing</u>: During this stage, tokens are processed to derive at meaningful expressions</li>
<li><u>Compiling</u>: The derived expressions are compiled into opcodes</li>
<li><u>Execution</u>: Opcodes are executed to derive at the final result</li>
</ul>
<p>Lets see how a PHP script passes through all the above steps.</p>
<p><strong style="font-size:18px;"><u>Lexing:</u></strong><br />
During this stage human readable php script is converted into token. For the first two lines of our PHP script:
<pre class="php" name="code">&lt;?php
	function increment($a) {</pre>
<p>tokens will look like this (try to match the tokens below line by line with the above 2 lines of PHP code and you will get a feel):</p>
<pre class="php" name="code">~ sabhinav$ php -r 'print_r(token_get_all(file_get_contents("debug.php")));';
Array
(
    [0] => Array
        (
            [0] => 368             // 368 is the token number and it's symbolic name is T_OPEN_TAG, see below
            [1] => &lt;?php

            [2] => 1
        )

    [1] => Array
        (
            [0] => 371
            [1] =>
            [2] => 2
        )

    [2] => Array
        (
            [0] => 334
            [1] => function
            [2] => 2
        )

    [3] => Array
        (
            [0] => 371
            [1] =>
            [2] => 2
        )

    [4] => Array
        (
            [0] => 307
            [1] => increment
            [2] => 2
        )

    [5] => (
    [6] => Array
        (
            [0] => 309
            [1] => $a
            [2] => 2
        )

    [7] => )
    [8] => Array
        (
            [0] => 371
            [1] =>
            [2] => 2
        )

    [9] => {
    [10] => Array
        (
            [0] => 371
            [1] =>

            [2] => 2
        )
</pre>
<p>A list of parser tokens can be found here: <a href="http://www.php.net/manual/en/tokens.php">http://www.php.net/manual/en/tokens.php</a></p>
<p>Every token number has a symbolic name attached with it. Below is our PHP script with human readable code replaced by symbolic name for each generated token:</p>
<pre class="php" name="code">~ sabhinav$ php -r '$tokens = (token_get_all(file_get_contents("debug.php"))); foreach($tokens as $token) { if(count($token) == 3) { echo token_name($token[0]); echo $token[1]; echo token_name($token[2]);  }  }';
T_OPEN_TAG&lt;?php
UNKNOWNT_WHITESPACE	UNKNOWNT_FUNCTIONfunctionUNKNOWNT_WHITESPACE UNKNOWNT_STRINGincrementUNKNOWNT_VARIABLE$aUNKNOWNT_WHITESPACE UNKNOWNT_WHITESPACE
		UNKNOWNT_RETURNreturnUNKNOWNT_WHITESPACE UNKNOWNT_VARIABLE$aUNKNOWNT_LNUMBER1UNKNOWNT_WHITESPACE
	UNKNOWNT_WHITESPACE
	UNKNOWNT_VARIABLE$aUNKNOWNT_WHITESPACE UNKNOWNT_WHITESPACE UNKNOWNT_LNUMBER3UNKNOWNT_WHITESPACE
	UNKNOWNT_VARIABLE$bUNKNOWNT_WHITESPACE UNKNOWNT_WHITESPACE UNKNOWNT_STRINGincrementUNKNOWNT_VARIABLE$aUNKNOWNT_WHITESPACE
	UNKNOWNT_ECHOechoUNKNOWNT_WHITESPACE UNKNOWNT_VARIABLE$bUNKNOWNT_WHITESPACE
UNKNOWN
</pre>
<p><strong style="font-size:18px;"><u>Parsing and Compiling:</u></strong><br />
By generating the tokens in the above step, zend engine is able to recognize each and every detail in the script. Where the spaces are, where are the new line characters, where is a user defined function and what not. Over the next two stages, the generated tokens are parsed and then compiled into opcodes. Below is the compiled opcode for the complete sample script of ours:</p>
<pre class="php" name="code">~ sabhinav$ php -r '$op_codes = parsekit_compile_file("debug.php", $errors, PARSEKIT_SIMPLE); print_r($op_codes); print_r($errors);';
Array
(
    [0] => ZEND_EXT_STMT UNUSED UNUSED UNUSED
    [1] => ZEND_NOP UNUSED UNUSED UNUSED
    [2] => ZEND_EXT_STMT UNUSED UNUSED UNUSED
    [3] => ZEND_ASSIGN T(0) T(0) 3
    [4] => ZEND_EXT_STMT UNUSED UNUSED UNUSED
    [5] => ZEND_EXT_FCALL_BEGIN UNUSED UNUSED UNUSED
    [6] => ZEND_SEND_VAR UNUSED T(0) 0x1
    [7] => ZEND_DO_FCALL T(1) 'increment' 0x83E710CA
    [8] => ZEND_EXT_FCALL_END UNUSED UNUSED UNUSED
    [9] => ZEND_ASSIGN T(2) T(0) T(1)
    [10] => ZEND_EXT_STMT UNUSED UNUSED UNUSED
    [11] => ZEND_ECHO UNUSED T(0) UNUSED
    [12] => ZEND_RETURN UNUSED 1 UNUSED
    [function_table] => Array
        (
            [increment] => Array
                (
                    [0] => ZEND_EXT_NOP UNUSED UNUSED UNUSED
                    [1] => ZEND_RECV T(0) 1 UNUSED
                    [2] => ZEND_EXT_STMT UNUSED UNUSED UNUSED
                    [3] => ZEND_ADD T(0) T(0) 1
                    [4] => ZEND_RETURN UNUSED T(0) UNUSED
                    [5] => ZEND_EXT_STMT UNUSED UNUSED UNUSED
                    [6] => ZEND_RETURN UNUSED NULL UNUSED
                )

        )

    [class_table] =>
)</pre>
<p>As we can see above, Zend engine is able to recognize the flow of our PHP. For instance, <code>[3] => ZEND_ASSIGN T(0) T(0) 3</code> is a replacement for <code>$a = 3;</code> in our PHP code. Read on to understand what do these <code>T(0)</code> in the opcode means.</p>
<p><strong style="font-size:18px;"><u>Executing the opcodes:</u></strong><br />
The generated opcode is executed one by one. Below table shows various details as every opcode is executed:</p>
<pre class="php" name="code">~ sabhinav$ php -d vld.active=1 -d vld.execute=0 -f debug.php
Branch analysis from position: 0
Return found
filename:       /Users/sabhinav/Workspace/interview/facebook/peaktraffic/debug.php
function name:  (null)
number of ops:  13
compiled vars:  !0 = $a, !1 = $b
line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
   2     0  EXT_STMT
         1  NOP
   5     2  EXT_STMT
         3  ASSIGN                                                   !0, 3
   6     4  EXT_STMT
         5  EXT_FCALL_BEGIN
         6  SEND_VAR                                                 !0
         7  DO_FCALL                                      1          'increment'
         8  EXT_FCALL_END
         9  ASSIGN                                                   !1, $1
   7    10  EXT_STMT
        11  ECHO                                                     !1
   8    12  RETURN                                                   1

Function increment:
Branch analysis from position: 0
Return found
filename:       /Users/sabhinav/Workspace/interview/facebook/peaktraffic/debug.php
function name:  increment
number of ops:  7
compiled vars:  !0 = $a
line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
   2     0  EXT_NOP
         1  RECV                                                     1
   3     2  EXT_STMT
         3  ADD                                              ~0      !0, 1
         4  RETURN                                                   ~0
   4     5* EXT_STMT
         6* RETURN                                                   null

End of function increment.
</pre>
<p>First table represents the main loop run, while second table represents the run of user defined function in the php script. <code>compiled vars:  !0 = $a</code> tells us that internally while script execution <code>!0 = $a</code> and hence now we can relate <code>[3] => ZEND_ASSIGN T(0) T(0) 3</code> very well.</p>
<p>Above table also returns back the number of operations <code>number of ops:  13</code> which can be used to benchmark and performance enhancement of your PHP script.</p>
<p>If <a href="http://www.php.net/manual/en/ref.apc.php">APC</a> cache is enabled, it caches the opcodes and thereby avoiding repetitive lexing/parsing/compiling every time same PHP script is called.</p>
<p><strong style="font-size:18px;"><u>3 PHP extensions providing interface to Zend Engine:</u></strong><br />
Below are 3 very useful PHP extensions for geeky PHP developers. (Specially helpful for all <a href="http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/">PHP extension</a> developers)</p>
<ul>
<li><u>Tokenizer</u>: The <a href="http://www.php.net/manual/en/ref.tokenizer.php">tokenizer functions</a> provide an interface to the PHP tokenizer embedded in the Zend Engine. Using these functions you may write your own PHP source analyzing or modification tools without having to deal with the language specification at the lexical level.</li>
<li><u>Parsekit</u>: These <a href="http://www.php.net/manual/en/ref.parsekit.php">parsekit functions</a> allow runtime analysis of opcodes compiled from PHP scripts.</li>
<li><u>Vulcan Logic Disassembler (vld)</u>: Provides functionality to dump the internal representation of PHP scripts. Homepage of <a href="http://derickrethans.nl/vld.php">VLD project</a> for download instructions.</li>
</ul>
<p>Hope this is of some help for PHP geeks out there.<br />
Enjoy!</p>
<div id="paidTxtLinkAds">Whether you are professional or newbie to PHP, our <a href="http://www.testking.org/642-832.htm">testking 642-832</a> web development course will provide you complete knowledge about PHP basics using <a href="http://www.testking.org/350-030.htm">testking 350-030</a> php tutorials and <a href="http://www.testking.org/646-204.htm">testking 646-204</a> video demos.</div>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/api.tweetmeme.com\/share?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2009%2F11%2Fphp-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine%2F","http:\/\/www.php.net\/manual\/en\/tokens.php","http:\/\/www.php.net\/manual\/en\/ref.apc.php","http:\/\/www.php.net\/manual\/en\/ref.tokenizer.php","http:\/\/www.php.net\/manual\/en\/ref.parsekit.php","http:\/\/derickrethans.nl\/vld.php","http:\/\/www.testking.org\/642-832.htm","http:\/\/www.testking.org\/350-030.htm","http:\/\/www.testking.org\/646-204.htm"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wp-content/plugins/wordpress-toolbar/toolbar.php";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDA5LzExL3BocC10b2tlbnMtYW5kLW9wY29kZXMtMy11c2VmdWwtZXh0ZW5zaW9ucy1mb3ItdW5kZXJzdGFuZGluZy10aGUtd29ya2luZy1vZi16ZW5kLWVuZ2luZS88d3B0Yj5QSFAgdG9rZW5zIGFuZCBvcGNvZGVzIDogMyB1c2VmdWwgZXh0ZW5zaW9ucyBmb3IgdW5kZXJzdGFuZGluZyB0aGUgd29ya2luZyBvZiBaZW5kIEVuZ2luZTx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script><!-- Jaxl IM embed starts -->
<script type="text/javascript">
(function() {
var jaxlChat = document.createElement("script");
jaxlChat.type = "text/javascript";
jaxlChat.async = true;
jaxlChat.src = "http://im.jaxl.im/ui/jaxl.js";
(document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0]).appendChild(jaxlChat);
})();
</script>
<!-- Jaxl IM embed ends --><ul class="related_post"><li><a href="http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/" title="PHP Extensions &#8211; How and Why?">PHP Extensions &#8211; How and Why?</a> (23)</li><li><a href="http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/" title="How does PHP echo&#039;s a &quot;Hello World&quot;? &#8211; Behind the scene">How does PHP echo&#039;s a &quot;Hello World&quot;? &#8211; Behind the scene</a> (13)</li><li><a href="http://abhinavsingh.com/blog/2009/01/mysql-query-cache-wp-cache-apc-memcache-what-to-choose/" title="MySQL Query Cache, WP-Cache, APC, Memcache &#8211; What to choose">MySQL Query Cache, WP-Cache, APC, Memcache &#8211; What to choose</a> (40)</li><li><a href="http://abhinavsingh.com/blog/2010/08/php-code-setup-and-demo-of-jaxl-boshchat-application/" title="PHP Code, Setup and Demo of Jaxl boshchat application">PHP Code, Setup and Demo of Jaxl boshchat application</a> (10)</li><li><a href="http://abhinavsingh.com/blog/2010/08/releasing-jaxl-2-0-object-oriented-xmpp-framework-in-php/" title="Releasing Jaxl 2.0 &#8211; Object oriented XMPP framework in PHP">Releasing Jaxl 2.0 &#8211; Object oriented XMPP framework in PHP</a> (6)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2009/11/php-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>PHP Extensions &#8211; How and Why?</title>
		<link>http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/</link>
		<comments>http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 09:44:13 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[MINIT]]></category>
		<category><![CDATA[MSHUTDOWN]]></category>
		<category><![CDATA[PHP Core]]></category>
		<category><![CDATA[PHP Extension]]></category>
		<category><![CDATA[RINIT]]></category>
		<category><![CDATA[RSHUTDOWN]]></category>
		<category><![CDATA[Zend Engine]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=68</guid>
		<description><![CDATA[
			
				
			
		
In this short post we will quickly see:

 How to write PHP extensions?
Why to write PHP extensions?

However before you could understand what we are going to disucss, I will recommend you to read one of  my previous post How does PHP echo’s a “Hello World”? &#8211; Behind the scene . In this post I discussed [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F12%2Fphp-extensions-how-and-why%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F12%2Fphp-extensions-how-and-why%2F&amp;source=imoracle&amp;style=normal&amp;service=bit.ly&amp;service_api=R_f027b5a79a20a49b713f16282f1e0857&amp;hashtags=MINIT,MSHUTDOWN,PHP,PHP+Core,PHP+Extension,RINIT,RSHUTDOWN,Zend+Engine" height="61" width="50" /><br />
			</a>
		</div>
<p>In this short post we will quickly see:</p>
<ol>
<li> How to write PHP extensions?</li>
<li>Why to write PHP extensions?</li>
</ol>
<p>However before you could understand what we are going to disucss, I will recommend you to read one of  my previous post <a title="How does PHP echo’s a “Hello World”? - Behind the scene" href="http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/" target="_blank">How does PHP echo’s a “Hello World”? &#8211; Behind the scene</a> . In this post I discussed in brief the backend architecture of PHP.</p>
<p>Assuming you have read the previous post, lets discuss on how to build our first PHP extension:</p>
<ol>
<li>Every PHP extension is built out of minimum of 2 files.</li>
<li>Configuration file (config.m4) which tells us what files to build and what external libraries are needed.</li>
<li>Source File(s) which will contain the actual functionalities provided by the extension.</li>
</ol>
<p><strong style="color:#0066AA"><u>Building a sample extension skeleton</u></strong><br />
Lets start with building and understanding a sample extension skeleton. Then we will move ahead with building our first PHP extension:</p>
<p><strong>config.m4</strong></p>
<pre name="code" class="php">
PHP_ARG_ENABLE(sample,
        [Whether to enable the "sample" extension],
        [-enable-sample  Enable "sample" extension support])
if test $PHP_SAMPLE != "no"; then
        PHP_SUBST(SAMPLE_SHARED_LIBADD)
        PHP_NEW_EXTENSION(sample,sample.c,$ext_shared)  // 1st argument declares the module
                                                        // 2nd tells what all files to compile
                                                        // $ext_shared is counterpart of PHP_SUBST()
fi</pre>
<p>I found a number of articles on internet which gives you code for your first PHP extension but none of them go ahead and explain each and every word in those codes. Lets give an attempt in understanding every bit of this strange config file.</p>
<ol>
<li>This is a minimalistic config file which is required for an extension</li>
<li>The first parameter to PHP_ARG_ENABLE(), sets up a ./configure option called <strong>-enable-sample</strong></li>
<li>The second parameter to PHP_ARG_ENABLE() will be displayed during the ./configure process as it reaches this configuration file</li>
<li>Third parameter will be displayed as an option if end user issues <strong>./configure -help</strong></li>
</ol>
<p><em><strong>For Newbies</strong>: Wondering what is this ./configure option? Kindly read <a href="http://www.php.net/manual/en/install.unix.php" target="_blank">PHP: Installation on Unix System</a> for details.</em></p>
<p>Lets understand the remaining part of the config.m4 file:</p>
<ol>
<li>To compile an extension we follow 3 steps: (i) phpize (ii) ./configure -enable-sample (iii) make</li>
<li>When we call <em>./configure -enable-sample</em> in step (ii), a local environmental  variable $PHP_SAMPLE is set to yes. (PS: If our extension name was Hello, then $PHP_HELLO would have been set to yes)</li>
<li>PHP_SUBST() is a MACRO similar to AC_SUBST() in C and is necessary to build the extension as a shared module</li>
<li>PHP_NEW_EXTENSION() declares the module and tell source files that must be compiled as part of the extension. $ext_shared is a counterpart of PHP_SUBST() and is necessary for buildin an extension as a shared module</li>
</ol>
<p><em>(PS: We only have a single source file i.e. <strong>sample.c</strong> for this extension. If in case we had more than a single source file then last line of <strong>config.m4</strong> would have been something like this: <strong>PHP_NEW_EXTENSION(sample,sample1.c sample2.c sample3.c,$ext_shared)</strong> and so on)</em></p>
<p>Now lets build our source file skeleton. Let&#8217;s segregate certain type of data in a header file, which we will finally include in sample.c file. This is generally a good practice rather than maintaining a single source file.</p>
<p><strong>php_sample.h</strong></p>
<pre name="code" class="c">
#ifndef PHP_SAMPLE_H
  #define PHP_SAMPLE_H
  #define PHP_SAMPLE_EXTNAME "sample"
  #define PHP_SAMPLE_EXTVER "1.0"

  #ifdef HAVE_CONFIG_H
    #include "config.h"
  #endif

  #include "php.h"
  extern zend_module_entry sample_module_entry;
  #define phpext_sample_ptr &#038;sample_module_entry
#endif
</pre>
<p>Do not leave this page on seeing this code. It&#8217;s all very simple if you have ever written some code in C.<br />
All that this file wants to do is:</p>
<ol>
<li><strong>config.h</strong> file is included when compiled using <strong>phpize</strong> tool</li>
<li>It also includes <strong>php.h</strong> from the PHP source tree. With inclusion of php.h, many other .h files also gets included and hence making available a lot of PHP API&#8217;s, which can be used by this extension</li>
<li>The <strong>zend_module_entry</strong> struct is defined as extern so that it can be picked up by ZEND engine using <strong>dlopen()</strong> and <strong>dlsym()</strong> functions, when the module loads.</li>
</ol>
<p><strong>sample.c</strong></p>
<pre name="code" class="c">
#include "php_sample.h"

zend_module_entry sample_module_entry = {
  #if ZEND_MODULE_API_NO >= 20010901
    STANDARD_MODULE_HEADER,        // Roughly means if PHP Version > 4.2.0
  #endif
    PHP_SAMPLE_EXTNAME,        // Define PHP extension name
    NULL,        /* Functions */
    NULL,        /* MINIT */
    NULL,        /* MSHUTDOWN */
    NULL,        /* RINIT */
    NULL,        /* RSHUTDOWN */
    NULL,        /* MINFO */
  #if ZEND_MODULE_API_NO >= 20010901
    PHP_SAMPLE_EXTVER,        // Roughly means if PHP Version > 4.2.0
  #endif
    STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_SAMPLE
  ZEND_GET_MODULE(sample)      // Common for all PHP extensions which are build as shared modules
#endif
</pre>
<p><!-- ADSENSE LEFT TEXT AD --><br />
Thats it! We have our first PHP extension ready. Compile this module as discussed above i.e.<br />
(i) phpize<br />
(ii) ./configure -enable-sample<br />
(iii) make<br />
check your phpinfo() and see if you have an extension called &#8220;sample&#8221; loaded successfully or not.</p>
<p>Though this extension is capable of doing nothing, but the skeleton here is the base for every PHP extension. Lets recap in short what has happened till now:<br />
<br/><br/><br/><br/><br />
<strong><u>RECAP</u></strong></p>
<ol>
<li><strong>config.m4</strong> file is the configuration file for extension</li>
<li> It declared the extension, tells what all files are required for the extension to build, add a few ./configure -help options too</li>
<li>On the other hand <strong>sample.c</strong> and <strong>php_sample.h</strong> are the main source files.</li>
<li>The header file includes the <strong>config.h</strong> and <strong>php.h</strong> header files from PHP source tree, which additionally provides a number of PHP API&#8217;s which can be used</li>
<li>As discussed in last <a target="_blank" href="http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/">blog post</a>, every extension have the following modules: <strong>MINIT, RINIT, RSHUTDOWN, MSHUTDOWN</strong>. sample.c helps in telling PHP, which part of the code corresponds to the above module</li>
<li>For our <strong>extension &#8220;sample&#8221;</strong> we have defined <strong>NULL</strong> as MINIT, RINIT, RSHUTDOWN and MSHUTDOWN and hence this module isn&#8217;t capable of doing anything</li>
</ol>
<p><strong style="color:#0066AA"><u>Building a Hello World Extension</u></strong><br />
To build an extension which actually do something, we will need to just tweak the abiove skeleton. Here we are trying to build an extension which will provide us with a function called sample_hello_world(), which we can use directly in our php codes to output Hello World!</p>
<p>Quickest link between userspace and extension code is the <strong>PHP_FUNCTION()</strong>. Start by adding the following code block near the top of sample.c file just after<br />
#include &#8220;php_sample.h&#8221;</p>
<pre name="code" class="c">
PHP_FUNCTION(sample_hello_world) {
  php_printf("Hello World!\n");
}
</pre>
<p>PHP_FUNCTION() is basically a MACRO which expands internally. (I will skip this expansion as of now to keep this post as simple as possible)</p>
<p>But simply declaring the function isn&#8217;t enough. The ZE needs to know the address of the function as well as how the function name should be exported to the userspace. Place the following block of code immediately after PHP_FUNCTION() block:</p>
<pre class="c" name="code">
static function_entry php_sample_functions[] = {
    PHP_FE(sample_hello_world,NULL)
    {NULL,NULL,NULL}
};
</pre>
<p>The <strong>php_sample_functions</strong> vector is a NULL terminated vector that will grow as we continue to add more functionality to sample extension. Every function we export will appear as an item in this vector.</p>
<p><em>PHP_FE(sample_hello_world,NULL)</em> expands to <em>{sample_hello_world, zif_sample_hello_world, NULL}</em> and hence providing a name and an address to implement it.</p>
<p>Finally simply go to the sample_module_entry struct and replace:<br />
<strong>NULL        /* functions */</strong> with<br />
<strong>php_sample_functions        /* functions */</strong></p>
<p>Now simply rebuild the extension and then try this on command line:<br />
<strong>$ php -r &#8217;sample_hello_world();&#8217;</strong></p>
<p>If everything was done perfectly, you would see &#8220;Hello World!&#8221; output on the shell.</p>
<p><strong style="color:#FF0000">PS: In this tutorial I have tried to explain each and every line which is involved in making a hello world php extension. However I am sure that many questions are still un-answered. Feel free to ask any doubt or correct me in case I have made a blunder while penning this down.</strong></p>
<div id="paidTxtLinkAds">Sign up for professional <a href="http://www.testking.org/70-649.htm">testking 70-649</a> training to learn php basics and get thousands of <a href="http://www.testking.org/1Y0-A17.htm">testking 1Y0-A17</a> php tutorials and other <a href="http://www.testking.org/PMI-001.htm">testking PMI-001</a> resources for practice. We offer complete <a href="http://www.testking.org/642-825.htm">testking 642-825</a> resources for php tutorials, <a href="http://www.testking.org/70-647.htm">testking 70-647</a> manuals, scripts and <a href="http://www.testking.org/642-983.htm">testking 642-983</a> classes to help you become expert php developer.</div>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/api.tweetmeme.com\/share?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F12%2Fphp-extensions-how-and-why%2F","http:\/\/www.php.net\/manual\/en\/install.unix.php","http:\/\/www.testking.org\/70-649.htm","http:\/\/www.testking.org\/1Y0-A17.htm","http:\/\/www.testking.org\/PMI-001.htm","http:\/\/www.testking.org\/642-825.htm","http:\/\/www.testking.org\/70-647.htm","http:\/\/www.testking.org\/642-983.htm"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wp-content/plugins/wordpress-toolbar/toolbar.php";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDA4LzEyL3BocC1leHRlbnNpb25zLWhvdy1hbmQtd2h5Lzx3cHRiPlBIUCBFeHRlbnNpb25zICYjODIxMTsgSG93IGFuZCBXaHk%2FPHdwdGI%2BaHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZzx3cHRiPkFiaGkmIzAzOTtzIFdlYmxvZw%3D%3D";</script><!-- Jaxl IM embed starts -->
<script type="text/javascript">
(function() {
var jaxlChat = document.createElement("script");
jaxlChat.type = "text/javascript";
jaxlChat.async = true;
jaxlChat.src = "http://im.jaxl.im/ui/jaxl.js";
(document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0]).appendChild(jaxlChat);
})();
</script>
<!-- Jaxl IM embed ends --><ul class="related_post"><li><a href="http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/" title="How does PHP echo&#039;s a &quot;Hello World&quot;? &#8211; Behind the scene">How does PHP echo&#039;s a &quot;Hello World&quot;? &#8211; Behind the scene</a> (13)</li><li><a href="http://abhinavsingh.com/blog/2009/11/php-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine/" title="PHP tokens and opcodes : 3 useful extensions for understanding the working of Zend Engine">PHP tokens and opcodes : 3 useful extensions for understanding the working of Zend Engine</a> (9)</li><li><a href="http://abhinavsingh.com/blog/2010/08/php-code-setup-and-demo-of-jaxl-boshchat-application/" title="PHP Code, Setup and Demo of Jaxl boshchat application">PHP Code, Setup and Demo of Jaxl boshchat application</a> (10)</li><li><a href="http://abhinavsingh.com/blog/2010/08/releasing-jaxl-2-0-object-oriented-xmpp-framework-in-php/" title="Releasing Jaxl 2.0 &#8211; Object oriented XMPP framework in PHP">Releasing Jaxl 2.0 &#8211; Object oriented XMPP framework in PHP</a> (6)</li><li><a href="http://abhinavsingh.com/blog/2010/04/setting-nginx-php-fastcgi-and-xcache-on-a-new-ubuntu/" title="Setting Nginx, PHP Fastcgi and XCache on a new Ubuntu">Setting Nginx, PHP Fastcgi and XCache on a new Ubuntu</a> (5)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>How does PHP echo&#039;s a &quot;Hello World&quot;? &#8211; Behind the scene</title>
		<link>http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/</link>
		<comments>http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 16:53:55 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[MINIT]]></category>
		<category><![CDATA[MSHUTDOWN]]></category>
		<category><![CDATA[PHP Core]]></category>
		<category><![CDATA[PHP Extension]]></category>
		<category><![CDATA[RINIT]]></category>
		<category><![CDATA[RSHUTDOWN]]></category>
		<category><![CDATA[SAPI]]></category>
		<category><![CDATA[Zend]]></category>
		<category><![CDATA[Zend Engine]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/</guid>
		<description><![CDATA[
			
				
			
		
Have you ever wondered how PHP echo&#8217;s a &#8220;Hello World&#8221; for you on the browser? Even I didn&#8217;t until I read about the PHP internals and extensions. I thought may be a few out there will be interested in exploring the other side of PHP, so here we go.
In my last post I discussed in [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fhow-does-php-echos-a-hello-world-behind-the-scene%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fhow-does-php-echos-a-hello-world-behind-the-scene%2F&amp;source=imoracle&amp;style=normal&amp;service=bit.ly&amp;service_api=R_f027b5a79a20a49b713f16282f1e0857&amp;hashtags=Apache,MINIT,MSHUTDOWN,PHP,PHP+Core,PHP+Extension,RINIT,RSHUTDOWN,SAPI,Zend,Zend+Engine" height="61" width="50" /><br />
			</a>
		</div>
<p>Have you ever wondered how PHP echo&#8217;s a &#8220;Hello World&#8221; for you on the browser? Even I didn&#8217;t until I read about the PHP internals and extensions. I thought may be a few out there will be interested in exploring the other side of PHP, so here we go.</p>
<p>In my last post I discussed in brief <span style="font-style: italic;">&#8220;How your browser reaches to my server when you type </span><a style="font-style: italic;" href="http://abhinavsingh.com">http://abhinavsingh.com</a><span style="font-style: italic;"> in address bar?&#8221;</span>. <a href="http://abhinavsingh.com/blog/2008/11/what-happens-before-you-finally-viewed-this-page/">Read through</a> if you have missed out on that. Here I will discuss in brief <span style="font-style: italic;">&#8220;How does PHP churns out the content requested on the webpage?&#8221;</p>
<p></span><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);">An Overview</span><span style="font-style: italic;"><br />
</span>Here is what happens step-wise:</p>
<ol>
<li>We never start any PHP daemon or anything by ourself. When we start Apache, it starts the PHP interpreter along itself</li>
<li>PHP is linked to Apache (In general term SAPI i.e. a Server API) using mod_php5.so module</li>
<li>PHP as a whole consists of 3 modules (Core PHP, Zend Engine and Extension Layer)
</li>
<li>Core PHP is the module which handles the requests, file streams, error handling and other such operations</li>
<li>Zend Engine(ZE) is the one which converts human readable code into machine understandable tokens/op-codes. Then it executes this generate code into a Virtual Machine.</li>
<li>Extensions are a bunch of functions, classes, streams made available to the PHP scripts, which can be used to perform certain tasks. For example, we need mysql extension to connect to MySQL database using PHP.</li>
<li>While Zend Engine executes the generated code, the script might require access to a few extensions. Then ZE passes the control to the extension module/layer which transfer back the control to ZE after completion of tasks.</li>
<li>Finally Zend Engine returns back the result to PHP Core, which gives that to SAPI layer, and finally which displays it on your browser.</li>
</ol>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);">A Step Deeper</span><br />
But wait! This is still not over yet. Above was just a high level flow diagram. Lets dig a step deeper and see what more is happening behind the scenes:</p>
<ol>
<li>When we start Apache, it also starts PHP interpreter along itself</li>
<li>PHP startup happens in 2 steps</li>
<li>1st step is to perform initial setup of structures and values that persists for the life of SAPI</li>
<li>2nd step is for transient settings that only last for a single page request</li>
</ol>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);">Step 1 of PHP Startup</span><br />
Confused over what&#8217;s step 1 and 2 ? No worries, next we will discuss the same in a bit more detail. Lets first see step 1, which is basically the main stuff.<br />
Remember step 1 happens even before any page request is being made.</p>
<ol>
<li>As we start Apache, it starts PHP interpreter</li>
<li>PHP calls <span style="font-weight: bold;">MINIT method</span> of each extension, which is being enabled. View your php.ini file to see the modules which are being enabled by default</li>
<li>MINIT refers to Module Initialization. Each Module Initialization method initializes and define a set of functions, classes which will be used by future page requests</li>
</ol>
<p>A typical MINIT method looks like:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHP_MINIT_FUNCTION(extension_name) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Initialize functions, classes etc */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);">Step 2 of PHP Startup<br />
</span>
<ol>
<li><span style="color: rgb(0, 0, 0);">When a page request is being made, SAPI layer gives control to PHP layer. PHP then set up an environment to execute the PHP page requested. In turn it also create a symbol table which will store various variables being used while executing this page.</span></li>
<li><span style="color: rgb(0, 0, 0);"></span>PHP then calls the <span style="font-weight: bold;">RINIT method</span> of each module. RINIT refers to Request Initialization Module. Classic example of RINIT module implementation is the Session&#8217;s module. If enabled in php.ini, the RINIT method of Sessions module will pre-populate the $_SESSION variable and save in the symbol table.
</li>
<li>RINIT method can be thought as an <span style="font-style: italic;">auto_prepend_file directive</span>, which is pre-appended to every PHP script before execution.</li>
</ol>
<p>A typical RINIT method looks like:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHP_RINIT_FUNCTION(extension_name) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Initialize session variables, pre-populate variables, redefine global variables etc */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);">Step 1 of PHP Shutdown<br />
</span><span style="color: rgb(0, 0, 0);">Just like PHP startup, shutdown also happens in 2 steps.<br />
</span>
<ol>
<li>After the page execution is complete either by reaching the end of the script or by call of any exit() or die() function, PHP starts the cleanup process. In turn it calls <span style="font-weight: bold;">RSHUTDOWN method</span> of every extension. RSHUTDOWN can be thought as <span style="font-style: italic;">auto_append_file directive</span> to every PHP script, which no matter what happens, is always executed.</li>
<li>RSHUTDOWN method, destroys the symbols table (memory management) by calling <span style="font-weight: bold;">unset()</span> on all variables in the symbols table</li>
</ol>
<p>A typical RSHUTDOWN method looks like:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHP_RSHUTDOWN_FUNCTION(extension_name) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Do memory management, unset all variables used in the last PHP call etc */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);">Step 2 of PHP Shutdown<br />
</span><span style="color: rgb(102, 51, 255);"><span style="color: rgb(0, 0, 0);">Finally when all requests has been made and SAPI is ready to shutdown, PHP call its 2nd step of shutdown process.<br />
</span></span>
<ol>
<li>PHP calls the <span style="font-weight: bold;">MSHUTDOWN method</span> of every extension, which is basically the last chance for every extension to unregister handlers and free any persistent memory allocated during the MINIT cycle.</li>
</ol>
<p>A typical RSHUTDOWN method looks like:</p>
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHP_MSHUTDOWN_FUNCTION(extension_name) {</p>
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Free handlers and persistent memory etc */</p>
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>And that brings us to the end of what we can call as PHP Lifecycle. Important point to note is that Step 1 of Startup and Step 2 of Shutdown happens when no request is being made to the web servers.</p>
<p>I hope this post will clear many doubts and un-answered questions which you might have.</p>
<p>Do leave a comment and feedbacks.</p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/api.tweetmeme.com\/share?url=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fhow-does-php-echos-a-hello-world-behind-the-scene%2F","http:\/\/abhinavsingh.com"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wp-content/plugins/wordpress-toolbar/toolbar.php";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDA4LzExL2hvdy1kb2VzLXBocC1lY2hvcy1hLWhlbGxvLXdvcmxkLWJlaGluZC10aGUtc2NlbmUvPHdwdGI%2BSG93IGRvZXMgUEhQIGVjaG8mIzAzOTtzIGEgJnF1b3Q7SGVsbG8gV29ybGQmcXVvdDs%2FICYjODIxMTsgQmVoaW5kIHRoZSBzY2VuZTx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script><!-- Jaxl IM embed starts -->
<script type="text/javascript">
(function() {
var jaxlChat = document.createElement("script");
jaxlChat.type = "text/javascript";
jaxlChat.async = true;
jaxlChat.src = "http://im.jaxl.im/ui/jaxl.js";
(document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0]).appendChild(jaxlChat);
})();
</script>
<!-- Jaxl IM embed ends --><ul class="related_post"><li><a href="http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/" title="PHP Extensions &#8211; How and Why?">PHP Extensions &#8211; How and Why?</a> (23)</li><li><a href="http://abhinavsingh.com/blog/2009/11/php-tokens-and-opcodes-3-useful-extensions-for-understanding-the-working-of-zend-engine/" title="PHP tokens and opcodes : 3 useful extensions for understanding the working of Zend Engine">PHP tokens and opcodes : 3 useful extensions for understanding the working of Zend Engine</a> (9)</li><li><a href="http://abhinavsingh.com/blog/2008/07/how-to-get-started-with-web-development/" title="How to get started with web development?">How to get started with web development?</a> (9)</li><li><a href="http://abhinavsingh.com/blog/2008/05/how-to-configure-ubuntu-and-lamp-on-windows/" title="How to configure Ubuntu and LAMP on Windows">How to configure Ubuntu and LAMP on Windows</a> (2)</li><li><a href="http://abhinavsingh.com/blog/2008/05/web-development-part-1-apache-mysql-php/" title="Web Development &#8211; Part 1: Apache, MySQL, PHP">Web Development &#8211; Part 1: Apache, MySQL, PHP</a> (4)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
