<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss 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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Abhi's Weblog</title>
	
	<link>http://abhinavsingh.com/blog</link>
	<description>PHP, Apache, MySQL, XMPP and Web Development</description>
	<pubDate>Fri, 02 Jan 2009 21:25:02 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/abhinavsingh" type="application/rss+xml" /><feedburner:emailServiceId>1929000</feedburner:emailServiceId><feedburner:feedburnerHostname>http://www.feedburner.com</feedburner:feedburnerHostname><item>
		<title>Behind the scenes - How and What XML’s are exchanged by JAXL</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/501274125/</link>
		<comments>http://abhinavsingh.com/blog/2009/01/behind-the-scenes-how-and-what-xmls-are-exchanged-by-jaxl/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 21:23:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[Gtalk]]></category>

		<category><![CDATA[Jabber]]></category>

		<category><![CDATA[JAXL]]></category>

		<category><![CDATA[XMPP]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=71</guid>
		<description><![CDATA[Pre-requisite
Though it&#8217;s not mandatory but will be helpful if you have given a casual reading to the following RFC&#8217;s:

Extensible Messaging and Presence Protocol(XMPP):Core
Extensible Messaging and Presence Protocol(XMPP):Instant Messaging and Presence

Case Study: Google Talk Server

JAXL Sends >>



Gtalk Acknowledges With >>



  
    
  
  
    X-GOOGLE-TOKEN
  


JAXL [...]]]></description>
			<content:encoded><![CDATA[<p><strong style="font-size:20px;">Pre-requisite</strong><br />
Though it&#8217;s not mandatory but will be helpful if you have given a casual reading to the following RFC&#8217;s:</p>
<ul>
<li><a href="http://xmpp.org/rfcs/rfc3920.html">Extensible Messaging and Presence Protocol(XMPP):Core</a></li>
<li><a href="http://xmpp.org/rfcs/rfc3921.html">Extensible Messaging and Presence Protocol(XMPP):Instant Messaging and Presence</a></li>
</ul>
<p><strong style="font-size:18px;">Case Study: Google Talk Server</strong></p>
<ul>
<li>JAXL Sends >>
<pre class="xml" name="code"><?xml version="1.0"?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="gmail.com" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace"></pre>
</li>
<li>Gtalk Acknowledges With >>
<pre class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="981E0522D7363BDF" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
  <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">
    <required/>
  </starttls>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-GOOGLE-TOKEN</mechanism>
  </mechanisms>
</stream:features></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/></pre>
</li>
<li>Gtalk Acknowledges With >>
<pre class="xml" name="code">
<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code"><?xml version="1.0"?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="gmail.com" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace"></pre>
</li>
<li>Gtalk Acknowledges With >>
<pre class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="C01610C43D6A37A2" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>PLAIN</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
  </mechanisms>
</stream:features></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code"><auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AGFjY192nbRbm3J1cGvxYWRzAG15QVRNcGlukT9zcpMxAjI=</auth></pre>
</li>
<li>Gtalk Acknowledge With >>
<pre class="xml" name="code"><success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code"><?xml version="1.0"?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="gmail.com" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace"></pre>
</li>
<li>Gtalk Acknowledge With >>
<pre class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="1DA3DFD778DA0116" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code"><iq type="set" id="1">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <resource>jaxl</resource>
  </bind>
</iq></pre>
</li>
<li>Gtalk Acknowledge With >>
<pre class="xml" name="code"><iq id="1" type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>myproductionuser@gmail.com/jaxl25C3CD9A</jid>
  </bind>
</iq></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code"><iq type="get" to="gmail.com">
  <query xmlns="http://jabber.org/protocol/disco#info"/>
</iq></pre>
</li>
<li>Gtalk Acknowledge With >>
<pre class="xml" name="code"><iq to="myproductionuser@gmail.com/jaxl25C3CD9A" from="gmail.com" type="result">
  <query xmlns="http://jabber.org/protocol/disco#info">
    <identity category="server" type="im" name="Google Talk"/>
    <feature var="http://jabber.org/protocol/disco#info"/>
    <feature var="google:jingleinfo"/>
    <feature var="google:roster"/>
    <feature var="google:nosave"/>
    <feature var="google:setting"/>
    <feature var="google:shared-status"/>
    <feature var="http://jabber.org/protocol/archive#otr"/>
    <feature var="google:mail:notify"/>
    <feature var="http://jabber.org/protocol/archive#save"/>
  </query>
</iq></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code"><iq type="get" id="2">
  <query xmlns="jabber:iq:roster"/>
</iq></pre>
</li>
<li>Gtalk Acknowledge With >>
<pre class="xml" name="code"><iq to="myproductionuser@gmail.com/jaxl25C3CD9A" id="2" type="result">
  <query xmlns="jabber:iq:roster">
    <item jid="friend_1@gtalkbots.com" subscription="both"><group>Buddies</group></item>
    <item jid="friend_2@gmail.com" subscription="both"/>
    <item jid="friend_3@gmail.com" subscription="both"><group>Buddies</group></item>
    <item jid="friend_4@gmail.com" subscription="both" name="Abhinav Singh"/>
    <item jid="friend_5@gmail.com" subscription="both"><group>Buddies</group></item>
    <item jid="friend_6@yahoo.co.in" subscription="none" ask="subscribe"/>
  </query>
</iq></pre>
</li>
<li>JAXL Sends >>
<pre class="xml" name="code">
<presence from="myproductionuser@gmail.com/jaxl25C3CD9A" to="friend_6@yahoo.co.in" type="subscribed"/>
<presence>
  <show>chat</show>
  <status>Online using JAXL - Jabber XMPP Library</status>
</presence></pre>
</li>
<li>Gtalk Acknowledge With >>
<pre class="xml" name="code">
<presence from="friend_1@gtalkbots.com/gtalkbots.BCFBAC47" to="myproductionuser@gmail.com/jaxl25C3CD9A">
  <status>I am online using Gtalkbot&#8217;s Client Library (JAXL)</status>
  <x xmlns="vcard-temp:x:update">
<photo>7d29d807158fd64820b109b4b42b2a23ca5a9d5a</photo>
  </x>
</presence></pre>
</li>
</ul>
<p>And in this fashion JAXL Client and Gtalk Server keeps exchanging XML Streams when ever there is a new message or an update in friend&#8217;s status message.</p>
<p>For more detail and in-depth knowledge kindly refer to the RFC documents linked at the top.</p>
<p><script type="text/javascript">var dzone_url = '';var dzone_title = '';var dzone_blurb = '';var dzone_style = '1';</script><br />
<script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script> </p>
<p><script type="text/javascript"><!--
digg_url = 'http://abhinavsingh.com/blog/2009/01/behind-the-scenes-how-and-what-xmls-are-exchanged-by-jaxl/';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=0EZtrC"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=0EZtrC" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/501274125" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2009/01/behind-the-scenes-how-and-what-xmls-are-exchanged-by-jaxl/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2009%2F01%2Fbehind-the-scenes-how-and-what-xmls-are-exchanged-by-jaxl%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2009/01/behind-the-scenes-how-and-what-xmls-are-exchanged-by-jaxl/</feedburner:origLink></item>
		<item>
		<title>Introducing JAXL - Open Source Jabber XMPP Library</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/501203696/</link>
		<comments>http://abhinavsingh.com/blog/2009/01/introducing-jaxl-open-source-jabber-xmpp-library/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 19:38:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[Gtalk]]></category>

		<category><![CDATA[Gtalkbots]]></category>

		<category><![CDATA[Jabber]]></category>

		<category><![CDATA[JAXL]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[XMPP]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=70</guid>
		<description><![CDATA[Introduction
JAXL stands for &#8220;Jabber XMPP Library&#8220;. For fun, it stands for &#8220;Just Another XMPP Library&#8221;
This library currently supports following features:

Connect to a Jabber Server (e.g. Gtalk)
TLS Encryption
DIGEST-MD5 and PLAIN authentication mechanisms
Roster Support

Library comes with the following class files:

config.ini.php : Holds your jabber account and mysql connection information
mysql.class.php : Basic MySQL connection class used to insert [...]]]></description>
			<content:encoded><![CDATA[<p><strong style="font-size:20px;"><span style="text-decoration: underline;">Introduction</span></strong></p>
<p><strong>JAXL</strong> stands for &#8220;<strong>Jabber XMPP Library</strong>&#8220;. For fun, it stands for &#8220;<strong>Just Another XMPP Library</strong>&#8221;</p>
<p>This library currently supports following features:</p>
<ul>
<li>Connect to a Jabber Server (e.g. Gtalk)</li>
<li>TLS Encryption</li>
<li>DIGEST-MD5 and PLAIN authentication mechanisms</li>
<li>Roster Support</li>
</ul>
<p>Library comes with the following class files:</p>
<ol>
<li><strong>config.ini.php</strong> : Holds your jabber account and mysql connection information</li>
<li><strong>mysql.class.php</strong> : Basic MySQL connection class used to insert received messages and presence into MySQL database</li>
<li><strong>logger.class.php</strong> : A very basic logger class which allows you to log all XML stanza&#8217;s send and received from jabber server</li>
<li><strong>xmpp.class.php</strong> : Base XMPP class library which implements the XMPP protocol</li>
<li><strong>jaxl.class.php</strong> : JAXL class which extends XMPP class library. Should be the starting point for your application.</li>
<li><strong>index.php</strong> : After building your application in jaxl.class.php, you finally initializa and call your methods here</li>
</ol>
<p><strong style="font-size:20px;"><span style="text-decoration: underline;">Source Code</span></strong><br />
JAXL is hosted at Google Code. Checkout full source code from here:<br />
<a href="http://code.google.com/p/jaxl" target="_blank">http://code.google.com/p/jaxl</a></p>
<table style="background-color: #fff; padding: 5px;border:1px dotted #999999" cellspacing=0>
<tr>
<td>
  <img src="http://groups.google.com/groups/img/3nb/groups_bar.gif" height=26 width=132 alt="Google Groups">
  </td>
</tr>
<tr>
<td style="padding-left: 5px;font-size: 125%">
  <b>jaxl</b>
  </td>
</tr>
<tr>
<td style="padding-left: 5px">
  <a href="http://groups.google.com/group/jaxl" target="_blank">Visit this group</a>
  </td>
</tr>
</table>
<p><strong style="font-size:20px;"><span style="text-decoration: underline;">How to use JAXL:</span></strong><br />
JAXL Client Library is highly structured. There is a base <em>XMPP class library (xmpp.class.php)</em> and a <em>JAXL class library (jaxl.class.php)</em> which is derived from the base XMPP class library.</p>
<p>Base XMPP class library implements the XMPP protocol and it also provides you with two extendable methods named <em>eventMessage()</em> and <em>eventPresence()</em>. These methods are internally called when a message or presence XML Stanza is received from the Jabber server.</p>
<p>Jaxl.class.php must be the starting point for all your applications. Simply customize the eventMessage() and eventPresence() Method for your application. Other methods which might interest you while customizing them are:</p>
<ol>
<li>sendMessage($jid,$message) : For sending message to a particular Jid</li>
<li>sendStatus() : To set your status message</li>
<li>roster(&#8217;get&#8217;) : To get list of roster</li>
<li>roster(&#8217;add&#8217;,$jid) : Add a new contact in roster list</li>
<li>roster(&#8217;remove&#8217;,$jid) : Remove a contact from roster list</li>
<li>roster(&#8217;update&#8217;,$jid,$name,$groups) : Update a particular contact in roster</li>
<li>subscribe($jid) : Subscribe for presence of a particular $jid</li>
</ol>
<p>This library includes the following files:</p>
<p><strong>Config File (config.ini.php)</strong><br />
You specify all your jabber account username and password in this file. For development environment keep <em>$env = &#8220;devel&#8221;</em> and for production simply change it to <em>$env = &#8220;prod&#8221;</em></p>
<pre class="php" name="code">  // Set an enviornment
  $env = "prod";

  // Log Level for logger class
  $logEnable = TRUE;

  // Log in MySQL database
  $logDB = FALSE;

  $key = array("prod"=>array("user"=>"myproductionuser",
                             "pass"=>"password",
                             "host"=>"talk.google.com",
                             "port"=>5222,
                             "domain"=>"gmail.com"
                            ),
              "devel"=>array("user"=>"mydevelopmentuser",
                             "pass"=>"password",
                             "host"=>"localhost",
                             "port"=>5222,
                             "domain"=>"localhost"
                            )
              );

  $db = array("prod"=>array("dbuser"=>"root",
                            "dbpass"=>"password",
                            "dbhost"=>"localhost",
                            "dbname"=>"jaxl"
                           ),
             "devel"=>array("dbuser"=>"root",
                            "dbpass"=>"password",
                            "dbhost"=>"localhost",
                            "dbname"=>"jaxl"
                           )
             );</pre>
<p><strong>MySQL Class (mysql.class.php)</strong><br />
This is a basic MySQL connection class used to insert received messages and presence into MySQL database </p>
<p><strong>Base XMPP Class (xmpp.class.php)</strong><br />
You should not worry about this class. Until and unless you are aware of what are you trying to achieve you should not touch this class file. </p>
<p><strong>Logger Class (logger.class.php)</strong><br />
This is a basic logger class. It help you log XML send to and received from jabber server. Might prove helpful in debugging and if you are interested in learning the core of XMPP Protocol. </p>
<p><strong>Extended JAXL Class (jaxl.class.php)</strong><br />
You will be customizing eventMessage() and eventPresence() methods here. </p>
<pre class="php" name="code">    function eventMessage($fromJid, $content, $offline = FALSE) {
      if($offline) {
        $this->sendMessage($fromJid,"Hi, Thanks for your offline message");
      }
      else {
        $this->sendMessage($fromJid,"Hi, Thanks for your message");
      }

      if($this->logDB) {
        // Save the message in the database
        $timestamp = date('Y-m-d H:i:s');
        $query = "INSERT INTO message (FromJid,Message,Timestamp) value ('$fromJid','$content','$timestamp')";
        $this->mysql->setData($query);
      }
    }

    function eventPresence($fromJid, $status, $photo) {
      // Change your status message to your friend's status
      $this->sendStatus($status);

      if($this->logDB) {
        // Save the presence in the database
        $timestamp = date('Y-m-d H:i:s');
        $query = "INSERT INTO presence (FromJid,Status,Timestamp) value ('$fromJid','$status','$timestamp')";
        $this->mysql->setData($query);
      }
    }</pre>
<p>In above example I have done 4 things: </p>
<ul>
<li>Sends back a message saying &#8220;Hi, Thanks for your offline message&#8221;, when I receive a offliner.</li>
<li>Sends back a message saying &#8220;Hi, Thanks for your message&#8221;, when I receive an IM from my friend.</li>
<li>Change my status message, as and when I receive a status update from my friends. </li>
<li>Save messages and presence into database if $logDB = TRUE in config.ini.php</li>
</ul>
<p><strong>Final Call (index.php)</strong></p>
<pre class="php" name="code">  /* Include Key file */
  include_once("config.ini.php");

  /* Include JAXL Class */
  include_once("jaxl.class.php");

  /* Create an instance of XMPP Class */
  $jaxl = new JAXL($key[$env]['host'],    // Jabber Server Hostname
                   $key[$env]['port'],    // Jabber Server Port
                   $key[$env]['user'],    // Jabber User
                   $key[$env]['pass'],    // Jabber Password
                   $key[$env]['domain'],  // Jabber Domain
                   $db[$env]['dbhost'],   // MySQL DB Host
                   $db[$env]['dbname'],   // MySQL DB Name
                   $db[$env]['dbuser'],   // MySQL DB User
                   $db[$env]['dbpass'],   // MySQL DB Pass
                   $logEnable,            // Enable Logging
                   $logDB                 // Enable MySQL Inserts
                  );

  try {
    /* Initiate the connection */
    $jaxl->connect();

    /* Communicate with Jabber Server */
    while($jaxl->isConnected) {
      $jaxl->getXML();
    }
  }
  catch(Exception $e) {
    die($e->getMessage());
  }</pre>
<p><strong style="font-size:20px;"><span style="text-decoration: underline;">Disclaimer</span></strong><br />
Currently this library is being developed and used at <a href="http://gtalkbots.com" target="_blank">Gtalkbots.com</a> . Though it is thoroughly tested and being used, I still recommend not to use it on production servers. Mainly, since it is heavily customized for Gtalkbot&#8217;s usage. I am releasing it, as I see it of use for the community worldwide. If you want to use it, use at your own risk. Let me know of any changes you make to this library. In future I look to make this library more generic. </p>
<p>Enjoy and let me know of any bugs, feedbacks, enhancements or any abuse you may want to pass through if it doesn&#8217;t work for you <img src='http://abhinavsingh.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p style="color:#FF0000;font-weight:bold;">You should be running index.php using command line and not browser (recommended). This class is currently highly customized for Gtalkbots usage and works perfectly with Gtalk Servers.</p>
<p><script type="text/javascript">var dzone_url = '';var dzone_title = '';var dzone_blurb = '';var dzone_style = '1';</script><br />
<script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script> </p>
<p><script type="text/javascript"><!--
digg_url = 'http://abhinavsingh.com/blog/2009/01/introducing-jaxl-open-source-jabber-xmpp-library/';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=wQoikE"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=wQoikE" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/501203696" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2009/01/introducing-jaxl-open-source-jabber-xmpp-library/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2009%2F01%2Fintroducing-jaxl-open-source-jabber-xmpp-library%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2009/01/introducing-jaxl-open-source-jabber-xmpp-library/</feedburner:origLink></item>
		<item>
		<title>PHP Extensions - How and Why?</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/479600040/</link>
		<comments>http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 15:14:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[MINIT]]></category>

		<category><![CDATA[MSHUTDOWN]]></category>

		<category><![CDATA[PHP]]></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”? - Behind the scene . In this post I discussed [...]]]></description>
			<content:encoded><![CDATA[<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”? - 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>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:</p>
<p><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>
<p><script type="text/javascript"><!--
digg_url = 'http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></strong></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=CokAmx"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=CokAmx" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/479600040" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F12%2Fphp-extensions-how-and-why%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/12/php-extensions-how-and-why/</feedburner:origLink></item>
		<item>
		<title>How to integrate Google Friend Connect - In Pictures</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/472920718/</link>
		<comments>http://abhinavsingh.com/blog/2008/12/how-to-integrate-google-friend-connect-in-pictures/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 21:40:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Friend Connect]]></category>

		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/12/how-to-integrate-google-friend-connect-in-pictures/</guid>
		<description><![CDATA[I am probably one of the luckiest (if this is the case) to have got google friend connect invitation a couple of minutes back. And it really took me a few minutes (&#60; 10) to setup Google Friend connect on Gtalkbots.
In Pictures:








http://google.com/friendconnect
Try out, if it clicks for your and others, you might get loads of [...]]]></description>
			<content:encoded><![CDATA[<p>I am probably one of the luckiest (if this is the case) to have got google friend connect invitation a couple of minutes back. And it really took me a few minutes (&lt; 10) to setup Google Friend connect on <a href="http://Gtalkbots.com">Gtalkbots</a>.</p>
<p><span style="font-weight: bold; text-decoration: underline;">In Pictures:</span></p>
<p><img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-1.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /><br />
<img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-2.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /><br />
<img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-3.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /><br />
<img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-4.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /><br />
<img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-5.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /><br />
<img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-6.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /><br />
<img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-7.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /><br />
<img src="http://abhinavsingh.com/library/images/GoogleFriendConnect-8.png" style="border: 1px solid rgb(119, 119, 119); padding: 5px; margin-bottom: 20px;" /></p>
<p><a href="http://google.com/friendconnect">http://google.com/friendconnect</a></p>
<p>Try out, if it clicks for your and others, you might get loads of traffic.</p>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/programming/How_to_integrate_Google_Friend_Connect_In_Pictures';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></p>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>
<p><!-- technorati tags begin -->
<p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/Google" rel="tag">Google</a>, <a href="http://technorati.com/tag/Google%20Friend%20Connect" rel="tag">Google Friend Connect</a>, <a href="http://technorati.com/tag/%20Friend%20Connect" rel="tag"> Friend Connect</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=YOz8Tz"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=YOz8Tz" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/472920718" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/12/how-to-integrate-google-friend-connect-in-pictures/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F12%2Fhow-to-integrate-google-friend-connect-in-pictures%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/12/how-to-integrate-google-friend-connect-in-pictures/</feedburner:origLink></item>
		<item>
		<title>How to create a social networking website in 5 minutes</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/470292322/</link>
		<comments>http://abhinavsingh.com/blog/2008/11/how-to-create-a-social-networking-website-in-5-minutes/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 14:33:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[Elgg]]></category>

		<category><![CDATA[Framework]]></category>

		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[Social Network]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/11/how-to-create-a-social-networking-website-in-5-minutes/</guid>
		<description><![CDATA[Hello Friends,
Social media is the way to go now-a-days. After Orkut, Facebook and My Space we saw hundreds of social networking site making their mark in the market. However now a days socialness is not only restricted to social networking sites. Now every company wants to include some amount of socialness into their website, product [...]]]></description>
			<content:encoded><![CDATA[<p>Hello Friends,</p>
<p>Social media is the way to go now-a-days. After Orkut, Facebook and My Space we saw hundreds of social networking site making their mark in the market. However now a days socialness is not only restricted to social networking sites. Now every company wants to include some amount of socialness into their website, product or whatever it is. </p>
<p>However the features which any of the social networking site provide are same and restricted to a certain extent. 3 of the sites which I have developed so far, all have socialness as a base component. (<a href="http://gtalkbots.com" target="_blank">Gtalkbots</a>, <a href="http://altertunes.com" target="_blank">Altertunes</a>,<a href="http://iitgalumni.org" target="_blank"> IITG Alumni</a>) However after I saw <a href="http://elgg.org" target="_blank">Elgg</a> a few days back, I was just wondering how much time I wasted in building social features in all the 3 sites. I just wish I could have found this before. </p>
<p>Here in 5 minutes we will see how to build a full fledged social networking site using Elgg:</p>
<ol>
<li>Download Elgg setup from the download page <a href="http://elgg.org/downloads.php" target="_blank">here</a> or directly using this link <a href="http://elgg.org/getelgg.php?forward=elgg1.1.zip" target="_blank">http://elgg.org/getelgg.php?forward=elgg1.1.zip</a></li>
<li>Lets name our social networking site as <span style="font-weight: bold;">Snizr</span>.</li>
<li>Extract the downloaded zip file in your Apache Document Root and name the folder as snizr. In my case it is <span style="font-weight: bold;">C:\Workspace\snizr&nbsp;</span></li>
<li>Now just<span style="font-weight: bold;"> </span>open the url <a href="http://localhost/snizr" target="_blank">http://localhost/snizr</a> and you will see a page like this:
<p><img src="http://abhinavsingh.com/library/images/400x1000-elgg1.gif" style="border: 1px solid rgb(119, 119, 119); padding: 5px;" /></li>
<li>Create a database named <span style="font-weight: bold;">snizr</span> in mysql and enter the details in the form above. Press enter and you will come to the system settings page. If for some reasons this configuration page doesn&#8217;t take you to the system settings page, manually go to <span style="font-weight: bold;">engine/settings.example.php</span> and rename it to <span style="font-weight: bold;">engine/settings.php</span> and enter the details inside.
<p><img src="http://abhinavsingh.com/library/images/400x1000-elgg2.gif" style="border: 1px solid rgb(119, 119, 119); padding: 5px;" /></p>
<p><img src="http://abhinavsingh.com/library/images/400x1000-elgg3.gif" style="border: 1px solid rgb(119, 119, 119); padding: 5px;" /></li>
<li>Now enter the details of your social network here. Create a upload folder outside the installation directory e.g. C:\Workspace\snizr-uploads\ . You will be asked to enter this path in the system settings above.
</li>
<li>After you are done you are taken to the registration page. The first registered user is admin by default.
<p><img src="http://abhinavsingh.com/library/images/400x1000-elgg4.gif" style="border: 1px solid rgb(119, 119, 119); padding: 5px;" /></li>
<li>Thats it. You have a full social networking available for you. After registration you come to the login page and after loggin in you come to your dashboard.</li>
</ol>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);">Features provided by Elgg:</span><br />
You just got a feel of how easy it is and its not even 5 minutes as per my watch. Still 2 min to go <img src='http://abhinavsingh.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
Quickly lets see what else does Elgg offer.</p>
<ol>
<li>Click on <a href="http://localhost/snizr/pg/admin/statistics/" target="_blank">Administration</a> link at the top navigation bar and you will be amazed to see the kind of admin panel it provides.
</li>
<li>Next go to <a href="http://localhost/snizr/pg/admin/plugins/" target="_blank">Tool Administration</a> and you can see about 10 plugins at your service. From Blog, API, Bookmarks, Friends, Groups, Messages, Status, UserValidationByEmail and what not.</li>
<li>Enable a few and go to your profile pages to see them being reflected immediately.</li>
</ol>
<p>Now I will leave to explore rest of it yourself. 5 minutes are almost over <img src='http://abhinavsingh.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>I hope you enjoyed discovering Elgg.</p>
<ol>
</ol>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/programming/How_to_create_a_social_networking_website_in_5_minutes';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></strong></p>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>
<p><!-- technorati tags begin -->
<p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/Elgg" rel="tag">Elgg</a>, <a href="http://technorati.com/tag/Social%20Network" rel="tag">Social Network</a>, <a href="http://technorati.com/tag/%20Open%20Source" rel="tag"> Open Source</a>, <a href="http://technorati.com/tag/%20Framework" rel="tag"> Framework</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=6p9Tw3"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=6p9Tw3" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/470292322" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/11/how-to-create-a-social-networking-website-in-5-minutes/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fhow-to-create-a-social-networking-website-in-5-minutes%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/11/how-to-create-a-social-networking-website-in-5-minutes/</feedburner:origLink></item>
		<item>
		<title>How does PHP echo’s a “Hello World”? - Behind the scene</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/466678236/</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 22:23:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[Apache]]></category>

		<category><![CDATA[MINIT]]></category>

		<category><![CDATA[MSHUTDOWN]]></category>

		<category><![CDATA[PHP]]></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[<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>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/programming/How_does_PHP_echo_s_a_Hello_World_Behind_the_scene';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></p>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);"></span><span style="color: rgb(0, 0, 0);"></p>
<p></span><span style="font-weight: bold; text-decoration: underline; color: rgb(102, 51, 255);"><br />
</span><span style="font-style: italic;"></span>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>
<p><!-- technorati tags begin -->
<p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/PHP" rel="tag">PHP</a>, <a href="http://technorati.com/tag/PHP%20Core" rel="tag">PHP Core</a>, <a href="http://technorati.com/tag/%20SAPI" rel="tag"> SAPI</a>, <a href="http://technorati.com/tag/%20Zend%20Engine" rel="tag"> Zend Engine</a>, <a href="http://technorati.com/tag/%20PHP%20Extensions" rel="tag"> PHP Extensions</a>, <a href="http://technorati.com/tag/%20MINIT" rel="tag"> MINIT</a>, <a href="http://technorati.com/tag/%20RINIT" rel="tag"> RINIT</a>, <a href="http://technorati.com/tag/%20RSHUTDOWN" rel="tag"> RSHUTDOWN</a>, <a href="http://technorati.com/tag/%20MSHUTDOWN" rel="tag"> MSHUTDOWN</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=05a0Ph"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=05a0Ph" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/466678236" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fhow-does-php-echos-a-hello-world-behind-the-scene%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/11/how-does-php-echos-a-hello-world-behind-the-scene/</feedburner:origLink></item>
		<item>
		<title>What happens before you finally viewed this page?</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/465418439/</link>
		<comments>http://abhinavsingh.com/blog/2008/11/what-happens-before-you-finally-viewed-this-page/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 20:27:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[ARecord]]></category>

		<category><![CDATA[CNAME]]></category>

		<category><![CDATA[DNS]]></category>

		<category><![CDATA[Godaddy]]></category>

		<category><![CDATA[Google Apps]]></category>

		<category><![CDATA[Gtalkbots]]></category>

		<category><![CDATA[VPS]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/11/what-happens-before-you-finally-viewed-this-page/</guid>
		<description><![CDATA[Since past 1 week or so I am trying to make a small tiny light weight web server of my own, and for the same I have been referring to dozens of papers, websites, people and what not. I still haven&#8217;t finished making one, I am still toggling between Java and Python, since both seems [...]]]></description>
			<content:encoded><![CDATA[<p>Since past 1 week or so I am trying to make a small tiny light weight web server of my own, and for the same I have been referring to dozens of papers, websites, people and what not. I still haven&#8217;t finished making one, I am still toggling between Java and Python, since both seems to satisfy my needs and unfortunately I am master in none. While I was digging deep into the theory of how can I make a web server, I cleared many other concepts of mine, which finally leads to this post.</p>
<p><span style="font-weight: bold;">&#8220;What happens before you finally viewed this page/post of mine ?&#8221;</span> - Many of you might know behind the scene stories and many like me might have a vague idea. But for the good of all those who don&#8217;t know and for people like me who needs a reference, I thought of better penning it down.</p>
<p>Lets see what possibly is going in the background:</p>
<ol>
<li>Suppose you type in <a href="http://www.yahoo.com">http://www.yahoo.com</a> in your web browser or clicked this link on some other page.</li>
<li>Your browser see&#8217;s the above URL, and identifies it as a HTTP protocol.</li>
<li>Then it breaks the URL into <span style="font-weight: bold;">Protocol, Domain Name, File Name </span>(in above case no file name is specified)</li>
<li>Browser contacts its default <span style="font-weight: bold;">DNS</span> (Domain Name Server), which helps it with an IP Address. DNS is a huge distributed database which contains mapping of URL&#8217;s to IP Address. Your browser&#8217;s default DNS might or might not have the required mapping of URL to IPAddress.</li>
<li>If it don&#8217;t have the IPAddress corresponding to http://www.yahoo.com , it will try to contact other <span style="font-weight: bold;">root name servers</span> for the required IPAddress.</li>
<li>If it already have the IPAddress corresponding to http://www.yahoo.com (which is possible if a similar request has already been made recently) it will provide the required IPAddress to your browser.</li>
</ol>
<p>And finally your browser then connects to the IPAddress it received and servers you the page returned back by Yahoo!. If you are still not clear about the process, following practical example might help you.</p>
<p><img style="border: 1px solid #444444; padding: 5px;" src="http://abhinavsingh.com/library/images/DNS.gif" alt="" /></p>
<ol>
<li>I thought of starting a website and decided to name it as <a href="http://gtalkbots.com">http://gtalkbots.com</a></li>
<li>Firstly, I needed to register domain name with a registrant. For e.g. In my case I blocked the domain name gtalkbots.com with<a href="http://godaddy.com"> godaddy.com</a>.</li>
<li>Secondly, I needed to have a machine i.e. a place where I can have all my HTML, PHP files. So I bought a VPS (Virtual Private Server)</li>
<li>Thirdly, I had to link the above two i.e. when someone types in http://gtalkbots.com in his browser, it should come to my VPS where I have my HTML files.</li>
<li>For linking the domain name and my VPS, I simply make an <span style="font-weight: bold;">ARecord</span> entry at godaddy, telling it the IPAddress of my VPS. In turn when you type in http://gtalkbots.com in your browser, GoDaddy redirects you to my VPS. (Google for ARecord and CNAME for more details)</li>
<li>Last 4 entries in the image above are for linking my gtalkbots.com domain with my <a href="http://google.com/a">google apps</a> account, so that I can send and receive my gtalkbots.com email on google apps.</li>
</ol>
<p>There is a lot more to it, however the info above is more than sufficient to understand the basics of<br />
<span style="font-weight: bold;">&#8220;What happens before you finally viewed this page/post of mine ?&#8221;</span></p>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/programming/What_happens_before_you_finally_viewed_this_page';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></p>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a style="color: #999; font-weight: bold;" title="Flock Browser" href="http://www.flock.com/blogged-with-flock" target="_new">Flock Browser</a></div>
<p><!-- technorati tags begin --></p>
<p style="font-size:10px;text-align:right;">Tags: <a rel="tag" href="http://technorati.com/tag/DNS">DNS</a>, <a rel="tag" href="http://technorati.com/tag/Gtalkbots">Gtalkbots</a>, <a rel="tag" href="http://technorati.com/tag/%20Godaddy"> Godaddy</a>, <a rel="tag" href="http://technorati.com/tag/%20Google%20Apps"> Google Apps</a>, <a rel="tag" href="http://technorati.com/tag/%20ARecord"> ARecord</a>, <a rel="tag" href="http://technorati.com/tag/%20CNAME"> CNAME</a>, <a rel="tag" href="http://technorati.com/tag/%20VPS"> VPS</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=tqc6ox"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=tqc6ox" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/465418439" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/11/what-happens-before-you-finally-viewed-this-page/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fwhat-happens-before-you-finally-viewed-this-page%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/11/what-happens-before-you-finally-viewed-this-page/</feedburner:origLink></item>
		<item>
		<title>Symfony model layer tips and tricks - A PHP Framework - Part 3</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/448902004/</link>
		<comments>http://abhinavsingh.com/blog/2008/11/symfony-model-layer-tips-and-tricks-a-php-framework-part-3/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 22:00:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Database]]></category>

		<category><![CDATA[Model Layer]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Propel]]></category>

		<category><![CDATA[SQL]]></category>

		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/11/symfony-model-layer-tips-and-tricks-a-php-framework-part-3/</guid>
		<description><![CDATA[I had a tough time searching for examples over the net for all kind of symfony queries. Though symfony is well documented here, I didn&#8217;t find enough examples there. 
If you have landed up on this post straight and are new to symfony, you may want to first read previous posts:
Getting started with Symfony - [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: rgb(0, 0, 0);">I had a tough time searching for examples over the net for all kind of symfony queries. Though symfony is well documented <a href="http://www.symfony-project.org/book/1_0/08-Inside-the-Model-Layer">here</a>, I didn&#8217;t find enough examples there. </p>
<p>If you have landed up on this post straight and are new to symfony, you may want to first read previous posts:<br />
<a href="http://abhinavsingh.com/blog/2008/10/getting-started-with-symfony-a-php-framework-part-1/">Getting started with Symfony - A PHP Framework - Part 1</a><br />
<a href="http://abhinavsingh.com/blog/2008/10/how-to-build-a-login-registration-system-using-symfony-a-php-framework-part-2/">How to build a login-registration system using Symfony - A PHP Framework - Part 2</a><br />
</span><span style="font-weight: bold; color: rgb(51, 102, 255); text-decoration: underline;"><br />
</span><span style="color: rgb(0, 0, 0);">If you are well equipped with the basics, read on</span><span style="font-weight: bold; color: rgb(51, 102, 255); text-decoration: underline;"></p>
<p>Select Query:<br />
</span><span style="color: rgb(0, 0, 0);">Lets start with the few basic example queries.<br />
</span>
<ol>
<li><span style="color: rgb(0, 0, 0); text-decoration: underline;">Extract list of all users from the users table</span></p>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$c = new Criteria();<br />
$this-&gt;resultSet = UsersPeer::doSelect($c);
</p>
<p>Now lets see how can we use this $resultset within the model layer and in the template files.<br />
To use the resultset within model layer, we can do something like this:</p>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">foreach($this-&gt;resultset as $rs) {<br />
&nbsp;&nbsp;&nbsp; $uid = $ps-&gt;getId();<br />
&nbsp;&nbsp;&nbsp; $fname = $ps-&gt;getFirstName();<br />
&nbsp;&nbsp;&nbsp; $lname = $ps-&gt;getLastName();<br />
}
</p>
<p>To use the resultset in template files (viewer layer), we can do something like this:</p>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">foreach($resultset as $rs) {<br />
&nbsp;&nbsp;&nbsp; $uid = $ps-&gt;getId();<br />
&nbsp;&nbsp;&nbsp; $fname = $ps-&gt;getFirstName();<br />
&nbsp;&nbsp;&nbsp; $lname = $ps-&gt;getLastName();<br />
}
</p>
</li>
<li><span style="text-decoration: underline;">Extract list of first 10 users only</span>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$c = new Criteria();<br />
$c-&gt;setLimit(10);<br />
$this-&gt;resultSet = UsersPeer::doSelect($c);
</p>
</li>
<li><span style="text-decoration: underline;">Extract list of 10 users starting from 100th user</span>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$c = new Criteria();<br />
$c-&gt;setOffset(100);<br />
$c-&gt;setLimit(10);<br />
$this-&gt;resultSet = UsersPeer::doSelect($c);
</p>
</li>
<li><span style="text-decoration: underline;">Extract user data where username = &#8216;imoracle&#8217;</span>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$c = new Criteria();<br />
$c-&gt;add(UsersPeer::USERNAME,&#8221;imoracle&#8221;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Note USERNAME is all in caps, even if your column name is in small case<br />
$this-&gt;resultSet = UsersPeer::doSelect($c);
</p>
</li>
<li><span style="text-decoration: underline;">Another approach to do a select query</span>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$c = new Criteria();<br />
$c-&gt;add(UsersPeer::USERNAME,&#8221;imoracle&#8221;);<br />
$resultSet = UsersPeer::doSelectRS($c);
</p>
<p>To access this resultset in the model layer itself, we can do something like this:</p>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">while($resultSet-&gt;next()) {<br />
&nbsp;&nbsp;&nbsp; $uid = $resultSet-&gt;get(1);<br />
&nbsp;&nbsp;&nbsp; $fname = $resultSet-&gt;get(2);<br />
&nbsp;&nbsp;&nbsp; $lname = $resultSet-&gt;get(3);<br />
}
</p>
<p>Where get(1) fetches the 1st column for you of the resultset. Hence $resultSet-&gt;get(n) will fetch you the nth column of the resultSet.</li>
</ol>
<p><span style="font-weight: bold; color: rgb(51, 102, 255); text-decoration: underline;">Insert Query:<br />
</span><span style="color: rgb(0, 0, 0);">Lets see a few quick examples for inserting a new row in a table.</span><span style="font-weight: bold; color: rgb(51, 102, 255); text-decoration: underline;"><br />
</span>
<ol>
<li><span style="text-decoration: underline;">Insert a user entry in user table</span></p>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$new_user = new Users();<br />
$new_user-&gt;setUserName($uname);<br />
$new_user-&gt;setFirstName($fname);<br />
$new_user-&gt;setLastName($lname);<br />
$new_user-&gt;setPassword(md5($pass));</p>
<p>$new_user-&gt;save();<br />
$new_user_id = $new_user-&gt;getId();
</p>
<p>Finally we get the last inserted user row id.
</li>
</ol>
<p><span style="font-weight: bold; color: rgb(51, 102, 255); text-decoration: underline;">Update Query:<br />
</span><span style="color: rgb(0, 0, 0);">Symfony provides nothing special for the update queries. The same above format works for updating a row as well. Symfony is smart enough to analyze whether its a select or update query.<br />
</span>
<ol>
<li><span style="text-decoration: underline;">First Method for Update Query (Recommended)</span></p>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$c = new Criteria();<br />
$c-&gt;add(UsersPeer::USERNAME,&#8221;imoracle&#8221;);<br />
$c-&gt;add(UsersPeer::PASSWORD,$newpass);<br />
$res = UsersPeer::doUpdate($c);
</p>
<p>In the above example we chose to update the password for user with username &#8220;imoracle&#8221;.</li>
<li><span style="text-decoration: underline;">Another Method for Update Query</span>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$user = new User();<br />
$user-&gt;setNew(false);<br />
$user-&gt;setId($uid);<br />
$user-&gt;setPassword($newpass);<br />
$user-&gt;save();
</p>
<p>Important code in above 5 lines is the 2nd line. Without this line it will add a new row and not update. Also another drawback which I found in this approach is that in third line you need to give the PK (primary key) of the table. Like our 1st method you cannot give username in the third line. </p>
<p>Finally I haven&#8217;t tried and tested this method enough. So I will not recommend this.
</li>
</ol>
<p><span style="font-weight: bold; color: rgb(51, 102, 255); text-decoration: underline;">Delete Query:</span><br />
Its basically the same above methods, with change of final call.</p>
<ol>
<li><span style="text-decoration: underline;">Delete a user&#8217;s account where username = &#8216;imoracle&#8217;</span></p>
<p style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">$c = new Criteria();<br />
$c-&gt;add(UsersPeer::USERNAME,&#8217;imoracle&#8217;);<br />
$res = UsersPeer::doDelete($c);
</p>
</li>
</ol>
<p><span style="font-weight: bold; color: rgb(51, 102, 255); text-decoration: underline;">How to alter a table in symfony?<br />
</span>
<ol>
<li><span style="text-decoration: underline;">Method 1 (Non-standard)</span><br />
A drawback which I have seen in symfony till now is that, when you try to alter a table by adding new columns in your schema.yml, It flushes the data from the table and gives you an altered table with no data. This is really bad, if you don&#8217;t know this behavior and move ahead altering the table. Though Symfony provider propel-dump-data to handle alter tables, but it is still quite buggy and slow for big databases. The clean and smooth way to achieve this is:</p>
<div style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<ol>
<li>Take a mysql dump with following options:<br />
mysqldump -h hostname -u username -p password -c -t dbname &gt; dbname.sql<br />
Do not forget to use option -c and -t, without which it can land you in a problem
</li>
<li>Update your schema.yml file, with new columns which you want to add and run<br />
sudo symfony propel-build-all
</li>
<li>Restore the database content using following command:<br />
mysql -h hostname -u username -p password dbname &lt; dbname.sql
</li>
</ol>
</div>
<p>And you have your new altered table without any loss of data.</li>
<li><span style="text-decoration: underline;">Method 2 (Standard)</span><br />
If you are afraid of your data being flushed by the stupid symfony, then you may choose not to touch your database using propel at all. Here is what you can do in such a case.</p>
<div style="border: 1px solid rgb(221, 221, 221); padding: 5px; background: rgb(238, 238, 238) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<ol>
<li>Update your schema.yml file and run<br />
sudo symfony propel-build-model
</li>
<li>Then manually go and alter the table in the database.
</li>
</ol>
</div>
<p>Here propel-build-model will only rebuild the ORM layer to incorporate your schema.yml changes. However propel-build-all not only builds the ORM layer, but also actually creates the table in the database (flushing the data)</li>
</ol>
<p>In future I shall keep adding more SQL queries on this post, as and when I write them using symfony. So keep glued to this one <img src='http://abhinavsingh.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/programming/Symfony_model_layer_tips_and_tricks_PHP_Framework_Part_3';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></strong></p>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>
<p><!-- technorati tags begin -->
<p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/Symfony" rel="tag">Symfony</a>, <a href="http://technorati.com/tag/PHP" rel="tag">PHP</a>, <a href="http://technorati.com/tag/%20Framework" rel="tag"> Framework</a>, <a href="http://technorati.com/tag/%20Propel" rel="tag"> Propel</a>, <a href="http://technorati.com/tag/%20SQL%20Query" rel="tag"> SQL Query</a>, <a href="http://technorati.com/tag/%20Database" rel="tag"> Database</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=kshC1W"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=kshC1W" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/448902004" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/11/symfony-model-layer-tips-and-tricks-a-php-framework-part-3/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fsymfony-model-layer-tips-and-tricks-a-php-framework-part-3%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/11/symfony-model-layer-tips-and-tricks-a-php-framework-part-3/</feedburner:origLink></item>
		<item>
		<title>games@gtalkbots.com - Online gaming enabled on Gtalk</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/440205097/</link>
		<comments>http://abhinavsingh.com/blog/2008/11/gamesgtalkbotscom-online-gaming-enabled-on-gtalk/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 19:12:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Anagram]]></category>

		<category><![CDATA[Gtalk]]></category>

		<category><![CDATA[Gtalkbots]]></category>

		<category><![CDATA[Online Games]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/11/gamesgtalkbotscom-online-gaming-enabled-on-gtalk/</guid>
		<description><![CDATA[Anagram, many of you might be familiar with it or even played many a times back in school and colleges. Its a simple text based game, where you are given a jumbled word and you need to re-arrange it. E.g. You will be given huldos and you need to quickly identify that as should.
So getting [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-style: italic;">Anagram</span>, many of you might be familiar with it or even played many a times back in school and colleges. Its a simple text based game, where you are given a jumbled word and you need to re-arrange it. E.g. You will be given <span style="font-style: italic;">huldos</span> and you need to quickly identify that as <span style="font-style: italic;">should</span>.</p>
<p>So getting bored back in college or office, add <span style="font-weight: bold;">games@gtalkbots.com</span> and type <span style="font-weight: bold;">anagram</span> to start gaming. Play and score well. Your score will turn up on the Gtalkbots front page. They have kept this game open for the world i.e. one can play this game even without registering at Gtalkbots.</p>
<p>A few important points:</p>
<ol>
<li>Add <span style="font-weight: bold;">games@gtalkbots.com</span> as your friend in Gtalk Messenger.</li>
<li>Type <span style="font-weight: bold;">rules</span> to read them before you start gaming.<br />
<img src="http://1.bp.blogspot.com/_DRGeZF9Zbaw/SQo-zF5MZAI/AAAAAAAAALM/HAhuYryYs4k/s400/rules.bmp" style="border: 1px solid rgb(68, 68, 68); padding: 2px;" /></li>
<li>Type <span style="font-weight: bold;">anagram</span> to start gaming.</li>
<li>You will be given a jumbled word which you needs to rearrange and reply back.</li>
<li>If your answer is correct you get <span style="font-weight: bold;">10 Points</span>.</li>
<li>If your answer is not correct and you are finding it tough to solve it, Type <span style="font-weight: bold;">hint</span> to get a clue, and a clue will be sent to all users playing the game.<br />
<img src="http://1.bp.blogspot.com/_DRGeZF9Zbaw/SQpAOVdf6yI/AAAAAAAAALU/YoGCjXnrgH4/s400/anagram.bmp" style="border: 1px solid rgb(68, 68, 68); padding: 2px;" /></li>
<li><span style="font-weight: bold; color: rgb(255, 0, 0);">DO NOT FORGET</span> to type <span style="font-weight: bold;">exit</span> when you are finished gaming. If you forget to do so, you will be considered as a part of next round being played and eventually your average score decreases.</li>
<li>If total number of <span style="font-weight: bold;">wrong answers = 5 (including all users)</span>, the bot will automatically reply back with correct answer and moves to the next word.</li>
</ol>
<p>So try out and enjoy.</p>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/playable_web_games/games_gtalkbots_com_Online_gaming_enabled_on_Gtalk';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></strong></p>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>
<p><!-- technorati tags begin -->
<p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/Anagram" rel="tag">Anagram</a>, <a href="http://technorati.com/tag/Gtalk" rel="tag">Gtalk</a>, <a href="http://technorati.com/tag/%20Gtalkbot" rel="tag"> Gtalkbot</a>, <a href="http://technorati.com/tag/%20Gtalkbots" rel="tag"> Gtalkbots</a>, <a href="http://technorati.com/tag/%20Online%20Gaming" rel="tag"> Online Gaming</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=vwVr2E"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=vwVr2E" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/440205097" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/11/gamesgtalkbotscom-online-gaming-enabled-on-gtalk/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F11%2Fgamesgtalkbotscom-online-gaming-enabled-on-gtalk%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/11/gamesgtalkbotscom-online-gaming-enabled-on-gtalk/</feedburner:origLink></item>
		<item>
		<title>How to build a login-registration system using Symfony - A PHP Framework - Part 2</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/436261766/</link>
		<comments>http://abhinavsingh.com/blog/2008/10/how-to-build-a-login-registration-system-using-symfony-a-php-framework-part-2/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 21:21:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[Framework]]></category>

		<category><![CDATA[MVC]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Propel]]></category>

		<category><![CDATA[Symfony]]></category>

		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/10/how-to-build-a-login-registration-system-using-symfony-a-php-framework-part-2/</guid>
		<description><![CDATA[Hello again,
In the last tutorial we saw a very basic implementation which will simply print &#8220;Hello World&#8221; on your browser screen. For those who have landed up here straight here, you may want to go through this blog post. Getting started with Symfony - A PHP Framework - Part 1 By now if you have [...]]]></description>
			<content:encoded><![CDATA[<p>Hello again,</p>
<p>In the last tutorial we saw a very basic implementation which will simply print <span style="font-weight: bold;">&#8220;Hello World&#8221;</span> on your browser screen. For those who have landed up here straight here, you may want to go through this blog post. <a href="http://abhinavsingh.com/blog/2008/10/getting-started-with-symfony-a-php-framework-part-1/">Getting started with Symfony - A PHP Framework - Part 1</a> By now if you have decided to go ahead with symfony and use it for your site development, this is what you will be looking for next.</p>
<p>You can download the code for this tutorial from google code base.</p>
<pre style="border: 1px solid rgb(153, 153, 153); padding: 5px; background: rgb(204, 204, 204) none repeat scroll 0% 50%; width: 500px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">svn checkout http://abhinavsingh.googlecode.com/svn/trunk/PHP/<br/>Frameworks/Symfony/Authentication abhinavsingh-read-only
</pre>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);">A Registration-Login-Logout System for your site<br />
</span><span style="color: rgb(0, 0, 0);">This is mostly the first thing you end up building for your site. To be frank, I myself haven&#8217;t made this application. I will make it as I write this blog, and note down all my steps here, so that I don&#8217;t miss any detail.<br />
</span>
<ol>
<li>We will name our project as <span style="font-weight: bold;">Authentication</span></li>
<li>Create a folder called Authentication under the Symfony directory we made in the last tutorial. For me its here <span style="font-weight: bold;">C:\Workspace\Symfony\Authentication</span></li>
<li>Open your command line and point it to the above created folder</li>
<li>Type &#8220;<span style="font-weight: bold;">symfony init-project Authentication</span>&#8221; and it will create same directory structure that we discussed in last tutotial.</li>
<li>Lets create an application inside this, we will name it as <span style="font-weight: bold;">Auth</span></li>
<li>Type &#8220;<span style="font-weight: bold;">symfony init-app Auth</span>&#8221; and it will create an application named Auth under the apps folder. (<span style="font-weight: bold;">C:\Workspace\Symfony\Authentication\apps\Auth)</span></li>
<li>First we need a module called <span style="font-weight: bold;">Registration</span>, to allow our users to register.</li>
<li>Type &#8220;<span style="font-weight: bold;">symfony init-module Auth Registration</span>&#8221; and it will tell symfony to create a module named Registration inside our application Auth</li>
<li>As told in last tutorial copy the <span style="font-weight: bold;">C:\php5\pear\data\symfony\web\sf folder</span> to <span style="font-weight: bold;">C:\Workspace\Symfony\Authentication\web\sf</span>. At the end of this part, we will learn how can we skip this copying again and again</li>
<li>Open <span style="font-weight: bold;">C:\Workspace\Symfony\Authentication\apps\Auth\modules\Registration\actions\actions.class.php</span> and comment out the forwarding as discussed in last tutorial.</li>
<li>Go to your command line and type &#8220;<span style="font-weight: bold;">symfony clear-cache</span>&#8220;. Read why we do this in the last tutorial.</li>
<li>Open <a href="http://localhost/Symfony/Authentication/web/">http://localhost/Symfony/Authentication/web/</a> in your browser and you must get something like this.</li>
</ol>
<p><img src="http://abhinavsingh.com/library/images/symfony-2-1.gif" title="" alt="" style="border: 1px solid rgb(119, 119, 119); padding: 2px;" /><br />
Figure 1</p>
<p>OOPS! Did we missed something? Yes we did and intentionally. We could have gone to C:\Workspace\Symfony\Authentication\apps\Auth\config\routing.yml and redirected our Authentication application to our Registration Module by default. In that case we would have seen an empty page since indexSuccess.php file inside C:\Workspace\Symfony\Authentication\apps\Auth\modules\Registration\templates is empty. But since we didn&#8217;t modified the routing.yml file, it took us to the default module of symfony.</p>
<p>So how do we access our Registration module without modifying routing.yml file??<br />
<span style="font-weight: bold;">http://localhost/Symfony/Authentication/web/Registration/index</span> is the answer <img src='http://abhinavsingh.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>As a convention<br />
<span style="font-weight: bold;">http://localhost/Symfony/Authentication/web/&lt;Module&gt;/&lt;ModuleFile&gt;<br />
</span>this is the standard for symfony.</p>
<p>Hence it went to Registration module and then indexSuccess.php page inside that. Cool so we actually just followed up from our last tutorial till here. Lets now do the actual development.</p>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);">Defining a layout for our website<br />
</span><span style="color: rgb(0, 0, 0);">Before we do any backend stuff, lets atleast get our site out of that blank page (</span><span style="font-weight: bold;">http://localhost/Symfony/Authentication/web/Registration/index)</span><span style="color: rgb(0, 0, 0);">. However, If you view the source of that blank page, you will actually find that there are already some header, css, body tags in the source code. How is this coming? when we have an empty <span style="font-style: italic;">indexSuccess.php</span> file.</p>
<p>From our last tutorial we saw the flow which symfony follows to finally display a page on the browser. But then I actually skipped a step to ease down the tutorial. In symfony we follow the <span style="font-style: italic;">Decorator Design Patterns</span> (I hope i m not wrong here) , to get the front end stuff. Essentially Decorator Design Pattern consists of a Layout and a Content page.</p>
<p>In symfony our layout file is located under at <span style="font-weight: bold;">C:\Workspace\Symfony\Authentication\apps\Auth\templates\layout.php. </span>Open it up and you will know the answer to &#8220;How are those meta tags, head tags and body tags coming&#8221;.</p>
<p>Cool enough. Lets go back to our indexSuccess.php file of Registration module and design our website. With a little CSS and HTML, I came up with this design page for our site. Mostly inspired and stolen from my new site <a href="http://gtalkbots.com">Gtalkbots.com</a></p>
<p></span><img src="http://abhinavsingh.com/library/images/symfony-2-2.gif" title="" alt="" style="border: 1px solid rgb(119, 119, 119); padding: 2px;" /><br />
Figure 2</p>
<p>We will shift a bit of code from this page to our layout.php page later on so that we need now write the same modules again and again. Download all the code, from the my google code vault location given at the beginning and end of this tutorial.</p>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);">Designing the backend database:</span><br />
Now we need&nbsp; a databases schema which will save our registered user&#8217;s data.&nbsp; Lets create our database structure.</p>
<p>As talked about in last tutorial, symfony follows ORM programming technique. For this, they provide a method through which you actually need not go to your database and create tables. Symfony will do that for you. Not only this, Symfony will also allow you to skip most of the SQL queries. Lets see how.</p>
<ol>
<li>Open<span style="font-weight: bold;"> C:\Workspace\Symfony\Authentication\config\schema.yml</span> . From extension we know that symfony follows YAML structures which is similar to XML, but a bit easy to write. We will define our table structures in this file.</li>
<li>Type the following in the schema.yml file:
<pre style="border: 1px solid rgb(153, 153, 153); padding: 5px; background: rgb(204, 204, 204) none repeat scroll 0% 50%; width: 600px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Propel:
  users:
    id:        { type: integer, primaryKey: true, autoIncrement: true }
    username:  varchar(100)
    emailid:   varchar(100)
    password:  varchar(100)
</pre>
</li>
<li>Note the indentation, it is very very important when you are using YAML. Indentation actually decides how the YAML parsers will read and interpret the information you want to write in .yml files. In our case we have a very simple schema.yml file having only one table. We will learn about what that &#8220;<span style="font-weight: bold;">Propel</span>&#8221; is all about later, but lets focus from line 2.</li>
<li>We are trying to make a table called <span style="font-weight: bold;">users </span>having fields like id, username, emailid and password</li>
<li>Now before Symfony makes this table for you, we need to tell symfony the database username and password. For this we have a configuration file called propel.ini, located at <span style="font-weight: bold;">C:\Workspace\Symfony\yahoo\config\propel.ini</span></li>
<li><span style="font-weight: bold;"></span>Open it and change the lines as below:
<pre style="border: 1px solid rgb(153, 153, 153); padding: 5px; background: rgb(204, 204, 204) none repeat scroll 0% 50%; width: 600px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">propel.database.createUrl  = mysql://root@localhost/
propel.database.url        = mysql://root:password@localhost/authentication
</pre>
<p>Now go to your mysql database and create a database named <span style="font-weight: bold;">authentication,</span> which symfony will use from now on.
</li>
<li>Type &#8220;<span style="font-weight: bold;">symfony propel-build-all</span>&#8221; in your command line. This command will happily create a table named &#8220;users&#8221; in youy MySQL database &#8220;authentication&#8221;. Some of the possible errors which I got in the past are:
<ul>
<li>Your PHP must be compiled with XSLT, hence enable it by going in your php.ini file</li>
<li>In schema.yml file never use TABS. The YAML parsers don&#8217;t understand TABS. User SPACES intead of that.</li>
</ul>
</li>
<li>To cross verify check your database, if the table has been created. Now a bit about Propel.</li>
</ol>
<p>Propel is nothing but a third-party-vendor plugin which Symfony use. It helps in parsing the YAML files, creating and executing the whole ORM module including parsing of schema.yml , creating tables, creating ORM data objects. We will slowly and gradually learn a lot more about ORM.</p>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);">A look at the model layer<br />
</span><span style="color: rgb(0, 0, 0);">Another thing which the propel command did was, it created the whole ORM module. If you go to <span style="font-weight: bold;">C:\Workspace\Symfony\Authentication\lib\model</span> you can see 2 folders being created and a few files too.</p>
<p>For every table, propel build 5 files under the model folder. These files are basically the class files, which will provide use with a database object which we can use to select or insert data in the database.</p>
<p>C:\Workspace\Symfony\Authentication\lib\model\om\BaseUsers.php &amp;<br />
</span><span style="color: rgb(0, 0, 0);">C:\Workspace\Symfony\Authentication\lib\model\om\BaseUsersPeer.php are the only 2 files which will be re-created when you run the propel command again. </p>
<p>The file positioned at<br />
C:\Workspace\Symfony\Authentication\lib\model\Users.php &amp;<br />
</span><span style="color: rgb(0, 0, 0);">C:\Workspace\Symfony\Authentication\lib\model\UsersPeer.php will be as it is from this point in time. If you write your own methods in them, they will remain as it is even when you re-create your database schema.</p>
<p>We will use these created ORM files to insert, delete, select data from the databases. In symfony we can actually skip writing a SQL query (though we can always write a direct query too)</p>
<p></span><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);">Writing the backend Code:<br />
</span><span style="color: rgb(0, 0, 0);">With UI and database in shape, its time to write our backend code which will handle the registration form submission. If you notice the source code of our form, the action field is set as :</p>
<p>&lt;form id=&#8221;registration&#8221; action=&#8221;<span style="font-weight: bold;">&lt;?php echo url_for(&#8221;Registration/index&#8221;); ?&gt;</span>&#8221; method=&#8221;POST&#8221;&gt;</p>
<p>In symfony we have a lot of helper functions which we can use. In this case we users url_for helper function, which helps in generating a url with &lt;module&gt;/&lt;modulefile&gt; being passed as parameter.</p>
<p>So we have our form being submitted to indexSuccess.php itself, i.e. SELF.<br />
Hence lets go to executeIndex() method in action.class.php and write the code which will handle the submitted form.</p>
<p>Copy the modified action.class.php file from the vault location. I have documented every line inside the code, which will walk you through the code. Understand the flow and continue reading.</p>
<p>However before we insert any data in the database, we need to give the database parameters. Go to<br />
<span style="font-weight: bold;">C:\Workspace\Symfony\Authentication\config\databases.yml<br />
</span>and uncomment the lines of code in there. Finally it should be of the following structure:</span></p>
<pre style="border: 1px solid rgb(153, 153, 153); padding: 5px; background: rgb(204, 204, 204) none repeat scroll 0% 50%; width: 600px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">all:
  propel:
    class:          sfPropelDatabase
    param:
      dsn:          mysql://root:password@localhost/authentication
</pre>
<p>Lastly open:<br />
<span style="font-weight: bold;">C:\Workspace\Symfony\Authentication\apps\Auth\config\settings.yml<br />
</span>and go to the last line of the file. You will find<br />
<span style="font-weight: bold;"># compat_10&nbsp;&nbsp;&nbsp; off<br />
</span>being commented out<br />
Uncomment it and then turn on compat_10 i.e.<br />
<span style="font-weight: bold;">compat_10&nbsp;&nbsp;&nbsp; on</span><br />
<span style="font-weight: bold;"></span><span style="font-weight: bold;"></span><br />
Clear your cache, before submitting the form (<span style="font-weight: bold;">symfony clear-cache</span>) and then try to register.</p>
<p>If you have followed everything, you will be able to successfully able to register and visit mainSuccess.php of the module.</p>
<p>I have documented all the code which you can download from the vault location. Read it, try it, play with it.</p>
<p><span style="font-weight: bold; color: rgb(255, 0, 0);">PS: The best documentation is available at symfony-project website. This tutorial was intended to </span><br style="font-weight: bold; color: rgb(255, 0, 0);" /><span style="font-weight: bold; color: rgb(255, 0, 0);">build a real life scenario application using Symfony. Though I must admit that I still haven&#8217;t used 100% possible symfony </span><br style="font-weight: bold; color: rgb(255, 0, 0);" /><span style="font-weight: bold; color: rgb(255, 0, 0);">for this application, just to make it simple but still give you a feel of how things flow in symfony.</p>
<p></span><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 0, 0);">Leave a comment if you have any doubt or difficulty in implementing the code.</span><br style="color: rgb(0, 0, 0);" /><span style="color: rgb(0, 0, 0);">Do leave a comment even if you like the code <img src='http://abhinavsingh.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </span><br />
</span><span style="font-weight: bold; color: rgb(255, 0, 0);"></span></p>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/programming/How_to_build_a_login_registration_system_using_Symfony_A_P';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></strong></p>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>
<p><!-- technorati tags begin -->
<p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/Symfony" rel="tag">Symfony</a>, <a href="http://technorati.com/tag/PHP" rel="tag">PHP</a>, <a href="http://technorati.com/tag/%20Framework" rel="tag"> Framework</a>, <a href="http://technorati.com/tag/%20Tutorial" rel="tag"> Tutorial</a>, <a href="http://technorati.com/tag/%20MVC" rel="tag"> MVC</a>, <a href="http://technorati.com/tag/%20Propel" rel="tag"> Propel</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=ls1bDj"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=ls1bDj" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/436261766" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/10/how-to-build-a-login-registration-system-using-symfony-a-php-framework-part-2/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F10%2Fhow-to-build-a-login-registration-system-using-symfony-a-php-framework-part-2%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/10/how-to-build-a-login-registration-system-using-symfony-a-php-framework-part-2/</feedburner:origLink></item>
		<item>
		<title>Y!OS Developer Release is Live. Yahoo! is open!</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/435605286/</link>
		<comments>http://abhinavsingh.com/blog/2008/10/yos-developer-release-is-live-yahoo-is-open/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 08:27:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Open Social]]></category>

		<category><![CDATA[Yahoo]]></category>

		<category><![CDATA[YAP]]></category>

		<category><![CDATA[YDN]]></category>

		<category><![CDATA[YQL]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/10/yos-developer-release-is-live-yahoo-is-open/</guid>
		<description><![CDATA[Today, Yahoo opened the developer interfaces to our Y!OS platform stack through  the release of the Yahoo! Social Platform (YSP), Yahoo! Query Language (YQL),  Yahoo! Application Platform (YAP), and the YDN developer dashboard. &#160;This makes  Y!OS a reality for an essential constituency: developers. &#160;Now, anyone on the web has access to  [...]]]></description>
			<content:encoded><![CDATA[<p>Today, Yahoo opened the developer interfaces to our Y!OS platform stack through  the release of the Yahoo! Social Platform (YSP), Yahoo! Query Language (YQL),  Yahoo! Application Platform (YAP), and the YDN developer dashboard. &nbsp;This makes  Y!OS a reality for an essential constituency<font color="#1f497d"><span style="color: rgb(31, 73, 125);">: </span></font>developers.<font color="#1f497d"><span style="color: rgb(31, 73, 125);"> </span></font>&nbsp;Now, anyone on the web has access to  Yahoo!’s tools and data to start building applications for Yahoo!’s vast  audience and the web beyond. &nbsp;It’s a great step forward in rewiring Yahoo! with  a social dimension and a platform architecture that’s open like never  before.</p>
<p><b><span style="font-weight: bold;">Yahoo! Social Platform (YSP)<br />
</span></b>See: <u><font color="blue"><span style="color: blue;"><a title="http://developer.yahoo.com/social" href="http://developer.yahoo.com/social">http://developer.yahoo.com/social</a></p>
<p></span></font></u><b><span style="font-weight: bold;">Yahoo! Query Language (YQL)</span></b><u><font color="blue"><span style="color: blue;"><span style="text-decoration: underline;"><br />
</span></span></font></u><font style="color: rgb(0, 0, 0);" color="blue">See: </font><u><font color="blue"><span style="color: blue;"></span></font></u><u><font color="blue"><a title="http://developer.yahoo.com/yql" href="http://developer.yahoo.com/yql">http://developer.yahoo.com/yql</a></font></u></p>
<p><b><span style="font-weight: bold;">Yahoo! Application Platform (<st1:place w:st="on">YAP</st1:place>)<br />
</span></b>See: <u><font color="blue"><span style="color: blue;"><a title="http://developer.yahoo.com/yap" href="http://developer.yahoo.com/yap">http://developer.yahoo.com/yap</a></p>
<p></span></font></u><b><span style="font-weight: bold;">Caja, security, and user privacy<br />
</span></b>For more info on Caja: <u><font color="blue"><span style="color: blue;"><a title="http://developer.yahoo.com/yap/caja" href="http://developer.yahoo.com/yap/caja">http://developer.yahoo.com/yap/caja</a></span></font></u>  </p>
<p><b><span style="font-weight: bold;">OAuth</span></b><br />
See: <u><font color="blue"><span style="color: blue;"><a title="http://developer.yahoo.com/oauth" href="http://developer.yahoo.com/oauth">http://developer.yahoo.com/oauth</a></p>
<p></span></font></u><b><span style="font-weight: bold;">OpenSocial Support<br />
</span></b>This launch also marks Yahoo!’s first implementation of OpenSocial support.<br />
<u><font color="blue"><span style="color: blue;"><a title="http://opensocialapis.blogspot.com/2008/10/launched-yahoos-first-implementation-of.html" href="http://opensocialapis.blogspot.com/2008/10/launched-yahoos-first-implementation-of.html">http://opensocialapis.blogspot.com/2008/10/launched-yahoos-first-implementation-of.html</a></p>
<p></span></font></u><font style="color: rgb(0, 0, 0);" color="blue">Hats off to Yahoo!<br />
</font>Y!OS is out there. &nbsp;Yahoo! is Open.<br />
<u><font color="blue"><span style="color: blue;"></span></font></u></p>
<p><u><font color="blue"><span style="color: blue;"><span style="text-decoration: underline;"></span><br />
</span></font></u></p>
<p><script type="text/javascript"><!--
digg_url = 'http://digg.com/tech_news/Y_OS_Developer_Release_is_Live_Yahoo_is_open';
// --></script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>
<p><!-- AddThis Button BEGIN --><strong style="font-weight: normal;"><br />
<a title="Bookmark and Share" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=Altertunes&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" href="http://www.addthis.com/bookmark.php" target="_blank"><img src="http://s9.addthis.com/button1-bm.gif" border="0" alt="Bookmark and Share" width="125" height="16" /></a><br />
<!-- AddThis Button END --></strong></p>
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>
<p><!-- technorati tags begin -->
<p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/Yahoo" rel="tag">Yahoo</a>, <a href="http://technorati.com/tag/Open" rel="tag">Open</a>, <a href="http://technorati.com/tag/%20Open%20Social" rel="tag"> Open Social</a>, <a href="http://technorati.com/tag/%20OAuth" rel="tag"> OAuth</a>, <a href="http://technorati.com/tag/%20YSP" rel="tag"> YSP</a>, <a href="http://technorati.com/tag/%20YQL" rel="tag"> YQL</a>, <a href="http://technorati.com/tag/%20YAP" rel="tag"> YAP</a>, <a href="http://technorati.com/tag/%20Caja" rel="tag"> Caja</a></p>
<p><!-- technorati tags end --></p>

<p><a href="http://feeds.feedburner.com/~a/abhinavsingh?a=9YqfYb"><img src="http://feeds.feedburner.com/~a/abhinavsingh?i=9YqfYb" border="0"></img></a></p><img src="http://feeds.feedburner.com/~r/abhinavsingh/~4/435605286" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2008/10/yos-developer-release-is-live-yahoo-is-open/feed/</wfw:commentRss>
		<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=abhinavsingh&amp;itemurl=http%3A%2F%2Fabhinavsingh.com%2Fblog%2F2008%2F10%2Fyos-developer-release-is-live-yahoo-is-open%2F</feedburner:awareness><feedburner:origLink>http://abhinavsingh.com/blog/2008/10/yos-developer-release-is-live-yahoo-is-open/</feedburner:origLink></item>
		<item>
		<title>How to create a single button flash audio player using Openlaszlo?</title>
		<link>http://feeds.feedburner.com/~r/abhinavsingh/~3/431858379/</link>
		<comments>http://abhinavsingh.com/blog/2008/10/how-to-create-a-single-button-flash-audio-player-using-openlaszlo/#comments</comments>
		<pubDate>Sat, 25 Oct 2008 17:17:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Web Tutorials]]></category>

		<category><![CDATA[Audioplayer]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Flashplayer]]></category>

		<category><![CDATA[OpenLaszlo]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/2008/10/how-to-create-a-single-button-flash-audio-player-using-openlaszlo/</guid>
		<description><![CDATA[Hello Everyone,
I have been working on OpenLaszlo for quite sometime now and found it every easy to build custom flash widgets using it. In my first tutorial on OpenLaszlo, we will together learn a few specs of Openlaszlo and then code a tiny little flash media player.
Getting started with Openlaszlo:


Openlaszlo is a framework which allows [...]]]></description>
			<content:encoded><![CDATA[<p>Hello Everyone,</p>
<p>I have been working on <a href="http://OpenLaszlo.org">OpenLaszlo</a> for quite sometime now and found it every easy to build custom flash widgets using it. In my first tutorial on OpenLaszlo, we will together learn a few specs of Openlaszlo and then code a tiny little flash media player.</p>
<p><span style="font-weight: bold;"><span style="text-decoration: underline; color: rgb(51, 51, 255);">Getting started with Openlaszlo:</span><br />
</span>
<ol>
<li>Openlaszlo is a framework which allows you to build flash widgets easily and faster. Biggest advantage is that you need not write any action scripting for building your flash widget. In laszlo we write code in XML format (files saved with extension .lzx) and then Laszlo server compiles our .lzx files to output a flash .swf file. WOW!</li>
<li>Download your copy of laszlo from <a href="http://openlaszlo.org/download">http://openlaszlo.org/download</a> and install. If you are on windows, installation is simple. Just double click the downloaded .exe file and it will install everything for you. For me my installation is at <span style="font-weight: bold;">C:\OpenLaszlo Server 4.0.12</span>
</li>
<li>Create a directory <span style="font-weight: bold;">C:\OpenLaszlo Server 4.0.12\Server\lps-4.0.12\Workspace</span> . I generally do all my laszlo specific development under Workspace directory. (Adjust the path as per your installation)</li>
<li>Create a folder inside Workspace named <span style="font-weight: bold;">audioplayer</span></li>
<li>Start the laszlo server.</li>
</ol>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);">Building an audioplayer in laszlo:</p>
<p></span><span style="color: rgb(0, 0, 0);">Before we proceed you may checkout the code repository from Google Code Base:</span></p>
<div style="border: 1px dotted rgb(153, 153, 153); padding: 5px; background: rgb(221, 221, 221) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-top: 5px; margin-bottom: 5px;">svn checkout http://abhinavsingh.googlecode.com/svn/trunk/ abhinavsingh-read-only
</div>
<p><span style="font-weight: bold; text-decoration: underline; color: rgb(51, 51, 255);"></span>
<ol>
<li>As I wrote before, laszlo code files have an extension called .lzx . Lets first see a demo and then we will learn the syntaxes etc. You can find the explanation of the codes below within the code as comments
</li>
<li>Create a file called <span style="font-weight: bold;">main.lzx </span>and copy paste the following lines of code in it:
<div style="border: 1px dotted rgb(153, 153, 153); padding: 5px; background: rgb(221, 221, 221) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-top: 5px; margin-bottom: 5px;">&lt;canvas id=&#8221;miniplayer&#8221; medialoadtimeout=&#8221;120000&#8243; bgcolor=&#8221;#FFFFFF&#8221; debug=&#8221;true&#8221;&gt;<br />
&nbsp;<br />
&nbsp; &lt;!&#8211; This file takes care of toggling for the play/pause button &#8211;&gt;<br />
&nbsp; &lt;include href=&#8221;playpausemultibutton.lzx&#8221;/&gt;<br />
&nbsp;<br />
&nbsp; &lt;!&#8211; Include the MP3 player class &#8211;&gt;<br />
&nbsp; &lt;include href=&#8221;player.lzx&#8221;/&gt;<br />
&nbsp;<br />
&nbsp; &lt;!&#8211; Main view containing everything within it &#8211;&gt;<br />
&nbsp; &lt;view x=&#8221;5&#8243;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;simplelayout axis=&#8221;x&#8221; spacing=&#8221;5&#8243;/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; PLAY-PAUSE BUTTON PANEL &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;view name=&#8221;buttonpanel&#8221; id=&#8221;buttonpanel&#8221; y=&#8221;1&#8243; bgcolor=&#8221;#EEEEEE&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;multistatebutton id=&#8221;playpausetoggle&#8221; name=&#8221;playpausetoggle&#8221; bgcolor=&#8221;#EEEEEE&#8221;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resource=&#8221;playpause_rsrc&#8221; align=&#8221;center&#8221; statenum=&#8221;0&#8243; statelength=&#8221;2&#8243; maxstate=&#8221;1&#8243; onclick=&#8221;this.toggle()&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;method name=&#8221;toggle&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this.statenum == 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.setStateNum(1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; if players is already loaded with a song just play it, otherwise load it again with mp3url &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(audioplayer.nowplaying == false) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; audioplayer.setAttribute(&#8221;nowplaying&#8221;,true);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; audioplayer.setResource(global.mp3url);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; audioplayer.play();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.setStateNum(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; audioplayer.stop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/method&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/multistatebutton&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/view&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Include the audioplayer class &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;player id=&#8221;audioplayer&#8221; width=&#8221;100%&#8221; height=&#8221;100%&#8221;/&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp; &lt;/view&gt;<br />
&lt;/canvas&gt;
</div>
</li>
<li>Create a file called <span style="font-weight: bold;">playpausemultibutton.lzx</span> and copy paste the following lines of code in it:
<div style="border: 1px dotted rgb(153, 153, 153); padding: 5px; background: rgb(221, 221, 221) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-top: 5px; margin-bottom: 5px;">&lt;library&gt;<br />
&nbsp; &lt;resource name=&#8221;playpause_rsrc&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211;&nbsp; State: 0 &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; first&nbsp; frame of state 1 = mouseup&nbsp;&nbsp; image of the button &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;frame src=&#8221;icons/play_blue.png&#8221;/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; third&nbsp; frame of state 1 = mousedown image of the button &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;frame src=&#8221;icons/pause_blue.png&#8221;/&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211;&nbsp; State: 1 &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; first&nbsp; frame of state 2 = mouseup image of the button &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;frame src=&#8221;icons/pause_blue.png&#8221;/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211; third&nbsp; frame of state 2 = mousedown image of the button &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;frame src=&#8221;icons/play_blue.png&#8221;/&gt;<br />
&nbsp; &lt;/resource&gt;<br />
&lt;/library&gt;
</p></div>
</li>
<li>Create a file called <span style="font-weight: bold;">player.lzx</span> and copy paste the following lines of code in it:
<div style="border: 1px dotted rgb(153, 153, 153); padding: 5px; background: rgb(221, 221, 221) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-top: 5px; margin-bottom: 5px;">&lt;library&gt;<br />
&nbsp;<br />
&nbsp; &lt;!&#8211; THE AUDIOPLAYER PLAYING CLASS &#8211;&gt;<br />
&nbsp; &lt;class name=&#8221;player&#8221; extends=&#8221;view&#8221; visible=&#8221;true&#8221; play=&#8221;false&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Attribute which captures the player nowplaying stat &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;attribute name=&#8221;nowplaying&#8221; value=&#8221;false&#8221;/&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Attribute which captures the player loading stat &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;attribute name=&#8221;loading&#8221; value=&#8221;false&#8221;/&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;onlastframe&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;onlastframe&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.setAttribute(&#8221;nowplaying&#8221;,false);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.setAttribute(&#8221;loading&#8221;,false);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; playpausetoggle.toggle();<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;onloadperc&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;onloadperc&#8221; args=&#8221;p&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(p &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(p &amp;lt; 1) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; audioplayer.setAttribute(&#8221;loading&#8221;,true);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(p == 1) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; audioplayer.setAttribute(&#8221;loading&#8221;,&#8221;done&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;onunload&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;onunload&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(this.nowplaying) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.setAttribute(&#8221;nowplaying&#8221;,false);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.stop();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;onplay&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;onplay&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.setAttribute(&#8221;nowplaying&#8221;,true);<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;onload&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;onload&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;onframe&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;onframe&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;onstop&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;onstop&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!&#8211; Write &#8216;ontimeout&#8217; handler &#8211;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;handler name=&#8221;ontimeout&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/handler&gt;<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp; &lt;/class&gt;<br />
&nbsp;<br />
&lt;/library&gt;
</div>
</li>
<li>Create a file called <span style="font-weight: bold;">mediaplayer_dev.html </span>and copy paste the following lines of code in it: (This is development environment file, mediaplayer.html is the production environment file which you can find in code repository)
<div style="border: 1px dotted rgb(153, 153, 153); padding: 5px; background: rgb(221, 221, 221) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-top: 5px; margin-bottom: 5px;">&lt;html&gt;<br />
&nbsp; &lt;head&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;title&gt;Flash Audio Player&lt;/title&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;script type=&#8221;text/javascript&#8221; src=&#8221;swfobject.js&#8221;&gt;&lt;/script&gt;<br />
&nbsp; &lt;/head&gt;<br />
&nbsp; &lt;body&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;div id=&#8221;flashcontent&#8221; width=&#8221;100%&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This text is replaced by the Flash movie.<br />
&nbsp;&nbsp;&nbsp; &lt;/div&gt;