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

<channel>
	<title>Query7 &#187; Kishore Nallan</title>
	<atom:link href="http://query7.com/author/kishore/feed" rel="self" type="application/rss+xml" />
	<link>http://query7.com</link>
	<description>PHP, Javascript, Python and Web Development</description>
	<lastBuildDate>Sat, 25 Jun 2011 21:29:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Using Facebook Connect for your web application</title>
		<link>http://query7.com/using-facebook-connect-for-your-web-application</link>
		<comments>http://query7.com/using-facebook-connect-for-your-web-application#comments</comments>
		<pubDate>Wed, 13 Jan 2010 17:53:11 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook-connect]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=546</guid>
		<description><![CDATA[<p>With the exponential growth of Facebook over the past few years, it&#8217;s safe to say that quite a large number of active web users today own and use a Facebook account regularly. Facebook connect, which Facebook launched late 2008, is a set of APIs which allow you to integrate your users&#8217; Facebook profile into your web application. Apart from allowing your visitors to login to your site using their Facebook identity (hence negating the registration process), it also allows you to leverage on the various social features of Facebook. Let&#8217;s take a overview of Facebook Connect, and how we can integrate it into our web application.</p>
<p><strong>Facebook APIs</strong></p>
<p>Facebook provides both RESTFUL and Javascript APIs. A <a href="http://wiki.developers.facebook.com/index.php/User:Client_Libraries">great number of client libraries</a> are available for creating your web application, though Facebook provides official support for only a handful of them. We will be using Facebook&#8217;s official <a href="http://wiki.developers.facebook.com/index.php/PHP">PHP 5 client</a> and <a href="http://wiki.developers.facebook.com/index.php/JavaScript_Client_Library">Javascript</a> libraries.</p>
<p><strong>FQL and XFBML </strong></p>
<p>Before we look delve deeper into Facebook connect integration, let&#8217;s look at FQL and XFBML &#8211; the two essential components of the Facebook connect platform.</p>
<p><a href="http://wiki.developers.facebook.com/index.php/FQL">FQL</a> (yes, Facebook Query Language!) allows you to query data from Facebook easily using a SQL like&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>With the exponential growth of Facebook over the past few years, it&#8217;s safe to say that quite a large number of active web users today own and use a Facebook account regularly. Facebook connect, which Facebook launched late 2008, is a set of APIs which allow you to integrate your users&#8217; Facebook profile into your web application. Apart from allowing your visitors to login to your site using their Facebook identity (hence negating the registration process), it also allows you to leverage on the various social features of Facebook. Let&#8217;s take a overview of Facebook Connect, and how we can integrate it into our web application.</p>
<p><strong>Facebook APIs</strong></p>
<p>Facebook provides both RESTFUL and Javascript APIs. A <a href="http://wiki.developers.facebook.com/index.php/User:Client_Libraries">great number of client libraries</a> are available for creating your web application, though Facebook provides official support for only a handful of them. We will be using Facebook&#8217;s official <a href="http://wiki.developers.facebook.com/index.php/PHP">PHP 5 client</a> and <a href="http://wiki.developers.facebook.com/index.php/JavaScript_Client_Library">Javascript</a> libraries.</p>
<p><strong>FQL and XFBML </strong></p>
<p>Before we look delve deeper into Facebook connect integration, let&#8217;s look at FQL and XFBML &#8211; the two essential components of the Facebook connect platform.</p>
<p><a href="http://wiki.developers.facebook.com/index.php/FQL">FQL</a> (yes, Facebook Query Language!) allows you to query data from Facebook easily using a SQL like syntax. This can be a substitute to invoking specific API methods using the client library. As a quick example, if we want to retrieve the name of a particular user, we could do:</p>
<pre>SELECT name FROM user WHERE uid=12345</pre>
<p>Simple isn&#8217;t it?  It&#8217;s important to note here that though FQL is very similar to SQL, it doesn&#8217;t fully conform to all aspects of SQL that you might come to expect. Take a look at the <a href="http://wiki.developers.facebook.com/index.php/FQL">FQL documentation</a> to find out about syntax support, and the <a href="http://wiki.developers.facebook.com/index.php/FQL_Tables">various tables</a> provided by FQL.</p>
<p><a href="http://wiki.developers.facebook.com/index.php/XFBML">XFBML</a> is a markup language provided by Facebook which allows you to embed Facebook based widgets and information into your page. By using XFBML tags, it&#8217;s much easier to embed information into the page, than having to query for it first (using FQL or an API call) and then displaying it in the application. For example, to display the user&#8217;s name, we do that simply by using the tag:</p>
<pre>&lt;fb:name uid="12345" /&gt;</pre>
<p>With the basics out of the way, let&#8217;s get started on building a simple Facebook connect application using PHP.</p>
<p><strong>Getting the API key</strong></p>
<p>The very first thing you need to do when you are looking to make use of Facebook Connect is to apply for an API key. To get that, you need to sign in to the <a href="http://www.facebook.com/developers/">Facebook Developer app</a> and create a profile for your web application.</p>
<p><img src="http://www.webdevelopmentbits.com/demo/facebook-login/fb1.gif" alt="screenshot 1" /></p>
<p>Once you have chosen a name for your Facebook Connect application, and create the application, a profile will be created for your connect application within the Facebook Developer app. You can edit this profile to add in additional information about your application. Also, note that Facebook provides you with an <strong>API Key</strong> and a <strong>Secret</strong>, both of which you need to use while calling any FB Connect API method (for authenticating your request).</p>
<p><img src="http://www.webdevelopmentbits.com/demo/facebook-login/fb2.gif" alt="screenshot 2" /></p>
<p>Although there are many fields, options and settions, you just  need to provide Facebook with the URL of your Facebook Connect application, and you can get your application up and running! This can be done by clicking on the &#8220;Connect&#8221; link and filling in the &#8220;Connect URL&#8221; field:</p>
<p><img src="http://www.webdevelopmentbits.com/demo/facebook-login/fb3.gif" alt="screenshot 3" /></p>
<p>When you are testing your application, it&#8217;s a good idea to place it under a sandbox such that only the developers have access to it. You can do that by going to &#8220;Advanced&#8221; tab and enabling the sandbox mode:</p>
<p><img src="http://www.webdevelopmentbits.com/demo/facebook-login/fb4.gif" alt="screenshot 4" /></p>
<p>That&#8217;s it, we are ready to use Facebook Connect!</p>
<p><strong>Creating the web app</strong></p>
<p>Our sample Facebook Connect application will be really simple. Here&#8217;s the <a href="http://www.webdevelopmentbits.com/demo/facebook-login/">link to the demo</a> (login using you FB account).</p>
<p>When the user visits the web app, we detect whether the user is already signed into Facebook. Facebook uses a single-on system &#8211; which means that if the user is alreadt signed into his Facebook account, we can detect that in our web application, and we can directly send the user along to the internal pages. In case the user is not logged in onto Facebook, we will give an overview of what our web application is about, and ask the user to login using Facebook Connect. Once the user is logged in, we will just display a list of his friends.</p>
<p>There are various ways of achieving this, but we will be using a mixture of XFBML, FQL and API calls to illustrate those concepts.</p>
<p>In our <strong>index.php</strong>, what we first need to do is to include the the official PHP client library for the REST API provided by Facebook. If you have not already download the PHP library, <a href="http://svn.facebook.com/svnroot/platform/clients/packages/facebook-platform.tar.gz">download it right here</a>.</p>
<pre>require_once 'facebook-platform/php/facebook.php';</pre>
<p>The file <strong>facebook.php</strong> contains a class that we will be using to make all our Facebook API calls. As I have already mentioned, the API Key, and the Secret (which we obtained during the application registration above) are compulsory parameters for all API requests. So, for convenience, we can store this information on a <strong>config.php</strong> file, which we can include from all our application pages.</p>
<pre>// config.php
// enter your application's API key and secret here:

$ApiKey = '12345667890';
$AppSecret = 'ABCDEFGHIJKLMNOPQRST';</pre>
<p>Ok, with that out of the way, our next step is to initialise the Facebook class:</p>
<pre>$facebook = new Facebook($ApiKey, $AppSecret);</pre>
<p>If your $ApiKey and $AppSecret credentials match, we will subsequently be able to make calls to the Facebook API invoking the methods of the $facebook object. As we have discussed, we need to first check if the user is already logged into Facebook. We do that by checking the &#8216;user&#8217; property of the $facebook object is set. If the user is logged in,  $facebook-&gt;user will contain the logged in user&#8217;s Facebook ID.</p>
<pre>if( !$facebook-&gt;user )
{
   // the user does NOT have a valid Facebook session
   // (i.e. not logged onto Facebook)
   // we will show some information about our app and ask the user
   // to login using FB connect:

   echo '&lt;h2&gt;Hey, this application will list all your friends on Facebook!
                But, you need to login using your Facebook account
                to continue!';
   echo '&lt;fb:login-button onlogin="javascript:location.reload(true)"&gt;
           &lt;/fb:login-button&gt;';
}
else {
   // show the user's list of friends (let's use FQL for this):

   $fqlQuery = "SELECT name FROM user WHERE uid IN (SELECT uid2 FROM
                       friend WHERE uid1 = $facebook-&gt;user)";
   $fbFriends = $facebook-&gt;api_client-&gt;fql_query($fqlQuery);

   if( $fbFriends == NULL )
   {
     echo "&lt;p&gt;Oh no, you don't have any friends on Facebook! &lt;/p&gt;";
   }
   else {
     echo "&lt;h3&gt;Your friends are: &lt;/h3&gt;";
     foreach ($fbFriends as $fbFriend)
     {
       echo $fbFriend['name'] . "&lt;br /&gt;";
     }
   }
}</pre>
<p>The above code block encompasses most of our simple application logic! It also goes to show how straightforward Facebook Connect really is, once you get the hang of it. We have used both FQL and XFBML in the code snippet. Let&#8217;s break it down and see what each code segment does.</p>
<pre>echo '&lt;fb:login-button onlogin="javascript:location.reload(true)"&gt;
               &lt;/fb:login-button&gt;';</pre>
<p>We are using XFBML above to render a Facebook connect login button for users who are not presently logged in. This button, when clicked, will open a pop-up window, which will allow the users to enter their Facebook credentials and log in.</p>
<p><img src="http://www.webdevelopmentbits.com/demo/facebook-login/fb5.gif" alt="screenshot 5" /></p>
<p>Once they login, the current page will automatically refresh, and since the user has a valid Facebook session this time, <strong>$facebook-&gt;user</strong> will return the user&#8217;s Facebook ID. To enable XFBML, we need to include two Javascript snippets to be embedded onto the page:</p>
<pre>&lt;script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/
                            FeatureLoader.js.php" type="text/javascript"&gt;
&lt;/script&gt;</pre>
<p><a href="http://wiki.developers.facebook.com/index.php/FeatureLoader.js.php">FeatureLoader.js.php</a> is a lightweight file that helps bootstrap the rest of the Connect library. It&#8217;s required for any XFBML functionality, and must be placed before any other  Facebook Connect scripts or API calls. We can either place it in the HEAD tag, or right after the BODY tag.</p>
<p>The other Javascript snippet that&#8217;s needed is:</p>
<pre>&lt;script type="text/javascript"&gt;
 FB_RequireFeatures(["XFBML"], function(){
 FB.Facebook.init("YOUR_API_KEY", "xd_receiver.htm");
 });
 &lt;/script&gt;</pre>
<p>This code snippet can be placed anywhere after the <strong>FeatureLoader.js.php</strong>. The snippet enables the use of XFBML. The file<strong> xd_receiver.htm</strong> creates a Cross Domain Communication Channel between third-party Web pages and Facebook pages. We need to create a xd_receiver.htm page with the following contents, and place it in the same directory as the main<strong> index.php</strong> file:</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;
&lt;head&gt;
    &lt;title&gt;Cross-Domain Receiver Page&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script src="http://static.ak.connect.facebook.com
                   /js/api_lib/v0.4/XdCommReceiver.js?2"
              type="text/javascript"&gt;
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>For logged-in users, we use FQL to retrieve the user&#8217;s friends.</p>
<pre>$fqlQuery = "SELECT name FROM user WHERE uid IN (SELECT uid2 FROM
                         friend WHERE uid1 = $user)";
$fbFriends = $facebook-&gt;api_client-&gt;fql_query($fqlQuery);</pre>
<p>$fbFriends will return a NULL, if no result is found. If the query produces results, an array of resulting users is returned. We can traverse this associative array and retrieve the various properies which we have queried for. In our case we have only queried for &#8216;name&#8217;, so we can print the names as:</p>
<pre>foreach ($fbFriends as $fbFriend)
{
    echo $fbFriend['name'] . "&lt;br /&gt;";
}</pre>
<p>Of course, we can retrieve lots of other details about the users (including a URL to a profile picture).</p>
<p>With that, we come to the end of our quick Facebook connect tutorial. Although our sample application is ridiculously simple in functionality, and we only scratched the basics of the Facebook Connect platform, Facebook Connect does allow developers to harness the full power of Facebook&#8217;s social features right from our application. You should check out the <a href="http://wiki.developers.facebook.com/index.php/Main_Page">Facebook API documentation</a>, and follow their <a href="http://developers.facebook.com/news.php">development blog</a> if you are serious about going for deeper levels of integration with Facebook.</p>
<p>You can download our demo files <a href="http://www.webdevelopmentbits.com/demo/facebook-login/fbconnect_sample.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/using-facebook-connect-for-your-web-application/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Writing web applications with CodeIgniter – Part 3</title>
		<link>http://query7.com/writing-web-applications-with-codeigniter-part-3</link>
		<comments>http://query7.com/writing-web-applications-with-codeigniter-part-3#comments</comments>
		<pubDate>Mon, 26 Oct 2009 05:06:29 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=539</guid>
		<description><![CDATA[<p>We built a simple to-do list application <a href="http://www.webdevelopmentbits.com/writing-web-applications-with-codeigniter-part-2">last week</a> by implementing the CI basics we learnt in <a href="http://www.webdevelopmentbits.com/writing-web-applications-with-codeigniter-part-1">first part</a> of this tutorial. Today, let&#8217;s go over some of the things that will allow you to customise and extend the CI framework for your specific needs. </p>
<p><strong> Changing the default URL routing</strong></p>
<p>As we have already seen, CI parses the URLs in the following format:</p>
<pre>example.com/className/functionName/variable1/variable2</pre>
<p>While this suits most of the times, sometimes we might want to tweak CI to handle things different. With a reference to the blog example we saw in the first part, say, we want to display the entries of a blog by accessing a URL along the lines of &#34;example.com/post/postID&#34;. Here, we actually want the &#34;postID&#34; to be parsed as a variable rather than a function name. </p>
<p>CI allows us to make such tweaks by allowing us to write our own routing rules. These rules are defined in <strong>application/config/routes.php</strong> file in an associative array called <strong>$route</strong> . The key of the associative array will define the URI to be matched, and its corresponding value will be the destination URI to which the request to be routed to. Apart from providing two&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>We built a simple to-do list application <a href="http://www.webdevelopmentbits.com/writing-web-applications-with-codeigniter-part-2">last week</a> by implementing the CI basics we learnt in <a href="http://www.webdevelopmentbits.com/writing-web-applications-with-codeigniter-part-1">first part</a> of this tutorial. Today, let&#8217;s go over some of the things that will allow you to customise and extend the CI framework for your specific needs. </p>
<p><strong> Changing the default URL routing</strong></p>
<p>As we have already seen, CI parses the URLs in the following format:</p>
<pre>example.com/className/functionName/variable1/variable2</pre>
<p>While this suits most of the times, sometimes we might want to tweak CI to handle things different. With a reference to the blog example we saw in the first part, say, we want to display the entries of a blog by accessing a URL along the lines of &quot;example.com/post/postID&quot;. Here, we actually want the &quot;postID&quot; to be parsed as a variable rather than a function name. </p>
<p>CI allows us to make such tweaks by allowing us to write our own routing rules. These rules are defined in <strong>application/config/routes.php</strong> file in an associative array called <strong>$route</strong> . The key of the associative array will define the URI to be matched, and its corresponding value will be the destination URI to which the request to be routed to. Apart from providing two wildcard types &quot;:num&quot; (matches only number) and &quot;:any&quot; (matches any character), CI also allows you to use regular expressions to define the URI to be matched. </p>
<p>For example, to achieve the routing we discussed above, we simply do:</p>
<pre>$route['post/(:num)'] = &quot;post/show_post/$1&quot;;</pre>
<p>The above rule routes any request to the URL &quot;post/postID&quot; (where postID is a number), to the standard CI URL &quot;post/show_post/$1&quot; where show_post is a function of the post controller class.</p>
<p><strong>Graceful error handling</strong></p>
<p>CodeIgniter allows you to generate custom error messages, which calls specific error templates. </p>
<p>CodeIgniter automatically shows a 404 error message for a missing controller. But, for generating a custom 404 error message for a missing page internally, we can do that by calling:</p>
<pre>show_404('path_to_missing_page');</pre>
<p>One place where you might be needing this is when you are serving images via a controller that parses the image ID passed as a paramter and fetches it from a secure storage to display it. The template for the 404 error page is found in <strong>application/errors/error_404.php</strong> file. </p>
<p>If you want a more generic error message, you can use the <strong>show_error</strong> function for that. We can specify both the error message, and the HTTP status code when we call this function. For example,</p>
<pre>show_error('Hey, this is a 500 error message!', 500);&nbsp;</pre>
<p>The template for this error message is found in <strong>application/errors/error_general.php</strong> file.  </p>
<p><strong>Managing multiple applications</strong></p>
<p>Although so far, we have used CI to handle just a single application, we can indeed have multiple applications using the same CI installation. To do this, we need to create a folder for each of our applications &#8211; currently our application resides within the &quot;application&quot; folder. So, say we have two applications called &quot;app1&quot; and &quot;app2&quot;, we can structure the folders this way:</p>
<pre>path_to_codeigniter/app1/
path_to_codeigniter/app2/ </pre>
<p>Copy the contents of the &quot;application&quot; folder (containing the views, controller, etc.) to these new folders. In addition, each of our application will need an &quot;index.php&quot; file that defines the path to the system and the application folders. So, we have to copy the &quot;index.php&quot; file from CI&#8217;s root folder to the app1 and app2 folders, and change the $system_folder and $application_folder variables to:</p>
<pre>$system_folder = &quot;../system&quot;; 
$application_folder = &quot;../app1&quot;;    // (use &quot;../app2&quot; for app2)</pre>
<p><strong>Caching</strong></p>
<p>To achieve better performance, it&#8217;s important we use caching effectively. This is especially true for high traffic, content oriented websites. To reduce the strain on our server, CI allows us to serve a static version of a page. Caching can be enabled on a per-page basis. Once we have enabled caching for a page, the first time the page is loaded, a static version of the file will be stored in <strong>system/cache</strong> folder. On subsequent page refreshes, this static version of the page will be served. </p>
<p>To enable caching of a particular page, we simply call this function from a controller:</p>
<pre>$this-&gt;output-&gt;cache($num_minutes); </pre>
<p>$num_minutes defines how long (in minutes) we want the cached page to be served. The function can be called from anywhere within your controller. One the $num_minutes has expired, a new version of the cached page will be written to the cache. </p>
<p><strong>Benchmarking your application</strong></p>
<p>If you are interested in measuring the performance of various parts of your application, CI&#8217;s benchmarking class will be handy. The benchmarking class is automatically loaded by CI. To calculate the elapsed time between two points, we simply do:</p>
<pre>$this-&gt;benchmark-&gt;mark('time_start');  // start timing

 //...all the code goes here...

$this-&gt;benchmark-&gt;mark('time_end'); // end timing
echo $this-&gt;benchmark-&gt;elapsed_time('time_start', 'time_end'); </pre>
<p>To find out the total elapsed time, we can use the same elapsed_time function without any parameters: </p>
<pre>echo $this-&gt;benchmark-&gt;elapsed_time();</pre>
<p><strong>Extending CI&#8217;s helper classes</strong></p>
<p>CodeIgniter provides various helper classes, some of which we used in our to-do list application. To extend (redefining existing methods or adding new methods) a helper class, we have to create a file in the <strong>application/helpers</strong> folder with the exact name of the existing helper class (in the system/helpers folder), but prefixing it with a &quot;MY_&quot;. So for e.g., if we want to extend the URL helper class (which is named url_helper.php), we have to create a file named &quot;MY_url_helper.php&quot; in the application/helpers folder. </p>
<p>Once we have done that, we can add either new methods to the file, or redefine an existing method (by using the same function name and parameters), which will then over-ride the default method defined in the helper class. </p>
<p><strong>Beyond CodeIgniter</strong> <strong>- Kohana framework</strong> </p>
<p>Although CodeIgniter is an extremely agile and light-weighted framework, CI&#8217;s support for PHP 4 means that quite a few &quot;hacks&quot; were used to make it work in PHP4. With the emergence of PHP5, many of these hacks (such as for auto loading of classes), have become unnecessary as PHP5 supports them cleanly, out of the box.  <a href="http://www.kohanaphp.com/">Kohana</a>, which began as a fork of CodeIgniter, is a PHP framework built exclusively for PHP5. It is also an entirely community driver project (unlike CodeIgniter, which is managed by EllisLab). If you don&#8217;t need support for PHP4, you really should take a look at <a href="http://www.kohanaphp.com/">Kohana</a>. It&#8217;s very similar to CodeIgniter, and you should not have too much trouble finding your feet in it. </p>
<p>With that, we come to the end of our three part series on CodeIgniter. If there is something I have left out, or was unclear about, please do mention them in the comments. </p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/writing-web-applications-with-codeigniter-part-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing web applications with CodeIgniter &#8211; Part 2</title>
		<link>http://query7.com/writing-web-applications-with-codeigniter-part-2</link>
		<comments>http://query7.com/writing-web-applications-with-codeigniter-part-2#comments</comments>
		<pubDate>Mon, 12 Oct 2009 11:01:45 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[todo]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=525</guid>
		<description><![CDATA[<p>Last week, we covered the basic structure of a CodeIgniter application. Let&#8217;s now jump right into developing a simple todo list application using CodeIgniter. We will be keeping the actual functionality of the application itself simple here, as the goal here is to give a good overview on what it takes to build a CI application from scratch.</p>
<p>Okay, the first thing you have to do is to download and extract the <a href="http://codeigniter.com/download.php">latest build</a> of <a href="http://codeigniter.com/">CodeIgniter</a>. Next, download the controllers, models and views that I have used in this <a href="http://download.sourcebits.com/web/todoapp_files.zip">sample todo list application</a>. You should refer to these files as you read the tutorial. Here is the <a href="http://todo.publishy.com/">demo</a> of the sample application (use &#8220;demo&#8221; as username and password). </p>
<p><strong>Directory structure</strong></p>
<p>All the files related to our application will be placed in the <strong>&#34;system/application&#34;</strong> folder:</p>
<p><img src="http://query7.com/wp-content/uploads/dirStructure.png" align="CI directory structure" /></p>
<p>As you can see, we have to place our controllers, views and models in their correspondng /controllers, /views and /models directories. Initially, we will have a sample controller (Welcome) in the /controllers directory, and its corresponding Welcome view in the /views directory. The model directory will be empty. </p>
<p>The /config directory consists of various files which will help us&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Last week, we covered the basic structure of a CodeIgniter application. Let&#8217;s now jump right into developing a simple todo list application using CodeIgniter. We will be keeping the actual functionality of the application itself simple here, as the goal here is to give a good overview on what it takes to build a CI application from scratch.</p>
<p>Okay, the first thing you have to do is to download and extract the <a href="http://codeigniter.com/download.php">latest build</a> of <a href="http://codeigniter.com/">CodeIgniter</a>. Next, download the controllers, models and views that I have used in this <a href="http://download.sourcebits.com/web/todoapp_files.zip">sample todo list application</a>. You should refer to these files as you read the tutorial. Here is the <a href="http://todo.publishy.com/">demo</a> of the sample application (use &#8220;demo&#8221; as username and password). </p>
<p><strong>Directory structure</strong></p>
<p>All the files related to our application will be placed in the <strong>&quot;system/application&quot;</strong> folder:</p>
<p><img src="http://query7.com/wp-content/uploads/dirStructure.png" align="CI directory structure" /></p>
<p>As you can see, we have to place our controllers, views and models in their correspondng /controllers, /views and /models directories. Initially, we will have a sample controller (Welcome) in the /controllers directory, and its corresponding Welcome view in the /views directory. The model directory will be empty. </p>
<p>The /config directory consists of various files which will help us fine-tune the CI framework to our development environment. We will ignore the other directories in the /application directory for the time being. </p>
<p><strong>Some basic configuration first</strong></p>
<p>We need to modify some of the configuration files in the /config folder to set up the framework: </p>
<ul>
<li><strong>database.php</strong> &#8211; this is where we will be filling up our database connectivity details. The file has ample comments to help you  fill in all the necessary details correctly! </li>
<li><strong>config.php</strong> &#8211; we have to fill in the path to our CI root folder here in the variable: <em>$config['base_url']</em></li>
<li><strong>autoload.php</strong> &#8211; this file allows us to autoload any libraries or helpers that CodeIgniter provides us so that they are available across the entire system. We will be using the session library and the url helper class, so initialise the <em>$autoload['libraries']</em> and <em>$autoload['helper']</em> variables to:<br />
    </p>
<ul>
<li><strong>$autoload['libraries'] = array(&#8216;database&#8217;,'session&#8217;);</strong></li>
<li><strong>$autoload['helper'] = array(&#8216;url&#8217;); </strong></li>
</ul>
</li>
</ul>
<p>By default, all CI URLs will have a &quot;.index.php&quot; included in them. E.g. <strong>example.com/index.php/blog/edit</strong></p>
<p>To remove this, we can optionally place a<strong> .htaccess</strong> file in your CI root folder with the following content:</p>
<pre>RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|scripts|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L] </pre>
<p>With the above rule in place, all requests other than those for index.php, images, css, scripts and robots.txt are treated as  a request for your index.php file.</p>
<p><strong>CodeIgniter session class </strong></p>
<p>Before we go further, let&#8217;s have a brief review of CodeIgniter&#8217;s sessions class, which will be using in this application to keep track of the user&#8217;s session. CI&#8217;s session class can handle user session data stored using either cookies or in a database. CodeIgniter&#8217;s session class does not utilize native PHP sessions. To make use of the session class in our application, we must either initialize it in a controller&#8217;s constructor, or we have to auto-load it so that it will run in the background, and will be available for us across the entire system. To load the session class manually in the controller&#8217;s constructor, we do that by calling:</p>
<pre>$this-&gt;load-&gt;library('session');</pre>
<p>To auto-load the session class, we have to open the file <strong>&quot;application/config/autoload.php</strong>&quot; and add the item to the &quot;autoload&quot; array as I have mentioned in configuration step above. </p>
<p>Reading and writing data to the session class is a breeze! To write data to a user&#8217;s session, we simply do:</p>
<pre>$this-&gt;session-&gt;set_userdata('some_variable', 'some_value'); </pre>
<p>And, to retrieve the data again, we just call:</p>
<pre>$item = $this-&gt;session-&gt;userdata('item');</pre>
<p>Apart from that, CI&#8217;s session class by default, provides us with the following information:</p>
<ul>
<li>user&#8217;s unique Session ID</li>
<li>user&#8217;s IP Address</li>
<li>user&#8217;s User Agent data (the first 50 characters of the browser data string)</li>
<li>user&#8217;s &quot;last activity&quot;  time stamp </li>
</ul>
<p><strong>Our application features: </strong></p>
<p>With that, out of the way, let&#8217;s get started. Our to-do-list application will have the following &quot;features&quot;:</p>
<ul>
<li>a simple user sign up and login system</li>
<li>session management using CI&#8217;s session class </li>
<li>a single to-do list which allows multiple users to add and delete items using AJAX</li>
</ul>
<p><strong>Database schema</strong></p>
<p>Given the rather simple nature of our application, it&#8217;s not too difficult to identify what database tables we will be needing upfront. We will need two tables:</p>
<ul>
<li><strong>users</strong> : stores the user id, username and the hashed password.</li>
<li><strong>items</strong> : stores the to-do list items and their attributes like item_id, user_id (ID of the user who created it)</li>
</ul>
<pre>CREATE TABLE IF NOT EXISTS `items` (
 `item_id` bigint(20) NOT NULL auto_increment,
 `user_id` bigint(20) NOT NULL,
 `item_text` varchar(255) NOT NULL, `is_done` int(11) NOT NULL,
 PRIMARY KEY  (`item_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `users` (
 `user_id` bigint(20) NOT NULL auto_increment,
 `username` varchar(100) NOT NULL,
 `password` varchar(100) NOT NULL,
 PRIMARY KEY  (`user_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
</pre>
<p>Setting up the above tables in the database which you have mentioned in your database.php configuration file above. </p>
<p>Here is a breakdown of all the controllers, views and model we will be needing for this application. I will explain the purpose of each of them, as we go about tackling them. </p>
<p><img src="http://query7.com/wp-content/uploads/file_overview.png" alt="Overview of all the CI files" />&nbsp;</p>
<p><strong>The login controller</strong></p>
<p>The login controller first checks whether the user is already logged in &#8211; in which case, we simply redirect him to the dashboard. This, we do by checking whether the &quot;logged_in&quot; field exists in the user&#8217;s session data. We are using CI&#8217;s session class for this: </p>
<pre>if( $this-&gt;session-&gt;userdata('logged_in') )	// user already logged in
{
	header(&quot;Location: &quot; . base_url() . &quot;index.php&quot; );
	die();
}</pre>
<p>The login controller serves two needs:</p>
<ul>
<li>render the login form initially for a user who wants to sign in to the system </li>
<li>when the user submits the login form, authenticate the user and either redirect him to the dashboard or show an error message</li>
</ul>
<p>When the controller is called, we can find out whether we should render the login form, or treat the request as a login form submission by checking for the POST variable &#8216;login&#8217;, which is the name of the &quot;login&quot; submit button in the login form. </p>
<pre>if( $this-&gt;input-&gt;post('login') )
{
	// treat this as a login form submission
}

else {
	// render the login form
}
</pre>
<p>If it&#8217;s NOT a login form submission, we simply load the <strong>login_view</strong> defined in <strong>application/views/login_view.php. </strong>This file will render the login form. </p>
<p>On the other hand, if its is a login form submission, we first retrieve the username and password variable from the POST request. We then load the Users_model class, and use its validate() function to authenticate the user. If the user&#8217;s username and password match, his user_id field from the database is returned. Else, a -1 is returned. For a valid user, we initialise his session by:</p>
<pre>$newdata = array(
 'user_id'  =&gt; $user_id,
 'username'  =&gt; $username,
 'logged_in' =&gt; TRUE
 );

 $this-&gt;session-&gt;set_userdata($newdata);</pre>
<p>We then redirect him to the dashboard. If the username and password provided do not match, we load the <strong>login_view</strong> by passing a variable &#8216;$message&#8217; that contains the error to be displayed.</p>
<p><strong>The Dashboard </strong></p>
<p>The welcome controller is the default controller for CodeIgniter. It will already be found in the /application/controllers directory, and this is the controller that will be called when you access our application&#8217;s URL directly without using any URL segments, as discussed in the previous article. Let us just make use of this controller for our application&#8217;s dashboard. Assuming the user has already logged in successfully, let&#8217;s build our application&#8217;s dashboard &#8211; the page the visitor first sees after logging in. In our case, it will be a page which will display a set of to-do items, and in addition, provide a way to enter a new to-do item or modify the done/not-done status of any existing item using AJAX. Here is the index() function of the welcome controller. </p>
<pre>function index()
{

	if( !$this-&gt;session-&gt;userdata('logged_in') )	// user NOT logged in
	{
		header(&quot;Location: &quot; . base_url() . &quot;index.php/login&quot; );
		die();
	}

 	$this-&gt;load-&gt;model('items_model','items');
        $data['all_items'] =
$this-&gt;items-&gt;fetch_all_items($this-&gt;session-&gt;userdata('user_id'));
 	$this-&gt;load-&gt;view('dashboard_view',$data);
 }</pre>
<p>The welcome controller will check whether the user is logged in (using the session data set earlier in the login controller).  If the user is not logged in, or his session has expired, we will redirect him to the login page.  The <strong>base_url()</strong> function belongs to the URL helper that we autoloaded in our configuration, and it returns the base URL of our application (including the &quot;/&quot; at the end of the URL). Otherwise, we will load the Items_model class which will be used to interact with the items table in the database. The fetch_all_items() function of the item_model class will fetch all the todo items of this particular logged in user from the &quot;items&quot; table. The only other thing to note here is that we are using the session class to retrieve the user id of the user that we have stored as session data when the user successfully logs in to the system.  </p>
<pre>function fetch_all_items($user_id)
{
  // fetch the to-do items of the user identified by $user_id:
  $query = $this-&gt;db-&gt;query(&quot;SELECT * FROM items WHERE user_id = $user_id&quot;);
  return $query-&gt;result();
} </pre>
<p> The index() function of the Welcome controller then loads the view &quot;<strong>dashboard_view</strong>&quot;, defined in &quot;dashboard_view.php&quot; in the <strong>system/application/views</strong> directory. When the view is loaded, we are passing to it the todo items we fetched from the database using the Items_model class. The view then renders all the to-do items on the page. </p>
<p><strong>dashboard_view.php</strong> links to an external stylesheet (todoapp.css) and a JavaScript file (todoapp.js). The AJAX functionality is defined in the JavaScript file. In our application, we are using AJAX to add a new todo item to the list, and also update the done/not-done status of any of the todo items. The function addNewItem() in the JavaScript file is bound to the click event of the &quot;Add&quot; button. </p>
<p>The addNewItem() function, when fired, makes an AJAX POST request to the &quot;<strong>add</strong>&quot; controller which will handle the addition of a new todo item. The add controller will return the ID field of the newly added todo item in the database. If the operation is a success (if the ID returned in not -1), we simply append the new todo item (along with a checkbox) to the bottom of the existing items. We also clear the text in the textfield. </p>
<p>The updateItem() function is bound to the click event on each of the checkboxes. When fired, it checks whether the checkbox that the user clicked is selected or not, and it sends this information to the &quot;<strong>update</strong>&quot; controller. </p>
<p><strong> The add controller</strong></p>
<p>In all the controllers, we will have to first check if the user is logged in, before we carry out any action. For a valid user, we retrieve the text of the new todo item to be added (from the POST variable sent to the script) using: </p>
<pre>$this-&gt;input-&gt;post('item_text',TRUE)</pre>
<p>The second parameter is set &#8216;TRUE&#8217; to indicate that the input must be filtered to negate XSS (cross site scripting) attempts. XSS is a major problem faced by many web applications, and as a golden rule, any input which might potentially get rendered on the front end must be passed through an XSS filter that escapes/strips out the dangerous elements. As an added precaution we also check whether the todo item&#8217;s text is not empty, and if all is clear, we load the &quot;Items_model&quot; class once again, and call the add_item() function to add the todo item to the database. The add_item() function uses another handy function that CI provides, to escape the data by adding single quotes around the data: </p>
<pre>$item_text = $this-&gt;db-&gt;escape($item_text);</pre>
<p><strong>The update controller</strong></p>
<p>What the update controller does is similar to the add controller and also fairly straight forward. It simply retrieves the POST variables sent to it (the ID of the item which is to be updated, and its updated status). The update controller then loads the Items_model and invokes the update_item() function to peform the update. </p>
<p><strong>The logout controller</strong></p>
<p>The logout controller destroys the session data of the user, and then redirects him to the login page once again.</p>
<pre>$this-&gt;session-&gt;sess_destroy();
header(&quot;Location: &quot; . base_url() . &quot;index.php/login&quot; );</pre>
<p><strong>User registration</strong></p>
<p>Finally, let&#8217;s get to the user registration, which is handled by The Register controller. First off, I should mention here that for the sake of simplicity, I have implemented a very simple registration form, with absolutely no spam control! </p>
<p>The Register controller is similar to the Login controller in that &#8211; it again serves both the purposes of rendering the registration form, and as well as handling the form submission. The register_view simply asks the user to pick a username and password. The &lt;form&gt;&#8217;s action attribute points to the URL of the register controller. </p>
<p>When the form is submitted, the Register controller first checks to see that both the username and password fields are not empty. It then loads the &quot;Users_model&quot; which handles all database operations concerned with the &quot;Users&quot; table. We will invoke the is_valid_username() of the Users_model to see whether the username that the user has chosen already exists (the function returns a -1 if no such username is found on the system). If it a username is indeed found (in which case the function will return the ID of the user), we will initialise a $message variable with the text &quot;That username already exists.&quot; and load the register view again, by passing the $message variable for rendering. </p>
<pre>if( $this-&gt;users-&gt;is_valid_username($this-&gt;db-&gt;escape($username)) != -1 )
{
	// username already exists
	$data['message'] = &quot;That username already exists.&quot;;
}
...
$this-&gt;load-&gt;view('register_view', $data); </pre>
<p>If the user has chosen a non-existing username, then we go ahead and add the user to the database by calling the Users_model&#8217;s add_user() function, by passing the username and his hashed password. We are simply using a plain SHA1 hash here to store the password (which is again considered not secure enough without <a href="http://en.wikipedia.org/wiki/Salt_(cryptography)">salting</a>, but enough for our simple application). Once the user is added to the MySQL database, we use the nifty &quot;<strong><a href="http://in.php.net/mysql_insert_id">mysql_insert_id()</a></strong>&quot; PHP function to retrieve the auto increment ID field of the user row just added to the &quot;users&quot; table. After a successful account creation, we initialise the user&#8217;s session and redirect him to the dashboard, so the user can start using the application right away.</p>
<p>With that, we come to the end of this second part of CodeIgniter tutorial. </p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/writing-web-applications-with-codeigniter-part-2/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Writing web applications with CodeIgniter: Part 1</title>
		<link>http://query7.com/writing-web-applications-with-codeigniter-part-1</link>
		<comments>http://query7.com/writing-web-applications-with-codeigniter-part-1#comments</comments>
		<pubDate>Tue, 29 Sep 2009 15:20:42 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=519</guid>
		<description><![CDATA[<p>CodeIgniter is a PHP framework that makes writing secure web applications a breeze. Being extremely light weighted, it&#8217;s an impressive toolkit which promotes the Model-View-Controller (MVC) approach to software development. CodeIgniter&#8217;s incredibly useful libraries, helpers and simplicity give you a sound foundation to quickly build your web apps on. This will be the first part of a series of tutorials focusing on CodeIgniter. Today, let&#8217;s get started with the basics of CodeIgniter and familiarize ourselves with the structure and semantics of a CI application. </p>
<p>I am assuming that you are already familiar with the <a href="http://en.wikipedia.org/wiki/Model&#8211;view&#8211;controller">MVC pattern</a>, so let&#8217;s briefly see how it applies to a typical CI application.</p>
<p><strong>View</strong> &#8211; A view is simply the content which a user sees rendered on a any page. It can be either a full web page, or even code snippets like the header or the footer of a web page. The view&#8217;s primary aim is to render data on the screen, which will be passed to it by a controller. </p>
<p><strong>Controller</strong> &#8211;  A controller handles the actual application logic. It acts as an intermediate between the View (front end) and the Model (the data). The controller, typically fetches records from&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>CodeIgniter is a PHP framework that makes writing secure web applications a breeze. Being extremely light weighted, it&#8217;s an impressive toolkit which promotes the Model-View-Controller (MVC) approach to software development. CodeIgniter&#8217;s incredibly useful libraries, helpers and simplicity give you a sound foundation to quickly build your web apps on. This will be the first part of a series of tutorials focusing on CodeIgniter. Today, let&#8217;s get started with the basics of CodeIgniter and familiarize ourselves with the structure and semantics of a CI application. </p>
<p>I am assuming that you are already familiar with the <a href="http://en.wikipedia.org/wiki/Model&ndash;view&ndash;controller">MVC pattern</a>, so let&#8217;s briefly see how it applies to a typical CI application.</p>
<p><strong>View</strong> &#8211; A view is simply the content which a user sees rendered on a any page. It can be either a full web page, or even code snippets like the header or the footer of a web page. The view&#8217;s primary aim is to render data on the screen, which will be passed to it by a controller. </p>
<p><strong>Controller</strong> &#8211;  A controller handles the actual application logic. It acts as an intermediate between the View (front end) and the Model (the data). The controller, typically fetches records from a database via a model class, and then passes it to a view for rendering. </p>
<p><strong>Model</strong> &#8211; A model is concerned with reading and writing data to and from a data souce &#8211; in our case, a database. It essentially consists of functions which help you isolate database operations from your core application logic. In CodeIgniter, a model is not necessary, should you wish to manipulate the database from a controller itself.</p>
<p><strong>The URL structure</strong></p>
<p>One great thing about CodeIgniter is that it generates URLs which is search engine friedly and also extremely logical for programmers. Instead of using query strings (like <em>index.php?action=display&amp;id=223</em>) to pass variables, it uses a very semantic segment based URL structure. By default, the CI URLs are parsed this way: </p>
<p><em>example.com/controller_class_name/function_name/ID1/ID2</em></p>
<p>As we can see, the first segment of the URL refers to the name of the controller class, the second part referring to the function in the controller that should be invoked, and the subsequent parts representing  various parameter values that can be passed to the function. Having understood that, it&#8217;s a good time to see the structure of a controller class. </p>
<p>Let&#8217;s take a simple example of a blog. Let us say we want a page where we want to show the entries of a blog, we can have a controller &quot;show&quot; which will be defined this way: </p>
<pre>class Show extends Controller {

	function index()
	{
		// access a model class to fetch all the blog posts
			...
		// invoke a view and pass to it the blog posts to render
	}
}
</pre>
<p>There are a couple of things to note here:</p>
<ul>
<li>all controller classes begin with a capital letter in CI &#8211; i.e <strong>S</strong>how</li>
<li>we will be saving the above file as &quot;show.php&quot; &#8211; the file name is essentially the same as the class name, except that the class name&#8217;s first character has to be in capital case. </li>
<li>the index() function will be the default function of the class &#8211; much like your main() function in a C program!</li>
<li>you will access the above controller with the following URL: example.com/show/index or just example.com/show</li>
</ul>
<p>Remember that the first segment refers to the controller name and the second segment refers to the function name. Since the index function is the default function for the controller, we can leave it out from the URL. We can add another function to the class, called <strong>entry</strong> &#8211; which will display a specific blog entry identified by an identifier: </p>
<pre>function entry($entry_id)
{
	// access a model class to fetch the blog post with ID $entry_id
		...
	// invoke a view and pass to it the blog post to render
} </pre>
<p>Now, to display a particular blog entry, we access the URL: example.com/show/entry/123 , where the &quot;123&quot; is (say) the ID of the blog entry to be rendered. Pretty easy, right ? </p>
<p>Now, let&#8217;s define a CI model class. Continuing with the same blog example, let&#8217;s say that the name of the model class which will handle our blog entries is &quot;Entry_model&quot;:</p>
<pre>class Entry_model extends Model {

	function Entry_mode()
	{
		parent:Model();
	}

	function fetch_post($entry_id)
	{
		// do your database query and return the record...
	}
}</pre>
<p>Now, to invoke the method fetch_post() from the controller, we do: </p>
<pre>$this-&gt;load-&gt;model(Entry_model');
$blog_entry = $this-&gt;Entry_model-&gt;fetch_post($entry_id); </pre>
<p>Again, it&#8217;s very intuitive. We load the model class, and then, invoke a method from the model class which will return the blog entry record. The naming convention for the model class is the same as that for a controller &#8211; the class name should start with a capital letter. Thus, the above model class is called &quot;Entry_model&quot; and it will be defined in the file &quot;entry_model.php&quot;. </p>
<p>Finally, let&#8217;s get to how CodeIgniter handles the View. As I have already stated above, CI is very flexible in how you want to define a view. A view can be a whole page, or page fragments like header, footer, navigation, sidebar etc. It&#8217;s always a good practise to logically break down the layout of a web page into a number of components, as it  promotes code reusabilty. </p>
<p>As for now, for simplicity, let&#8217;s just say that our blog entry will be rendered using a single view. So, we will basically have a .php file that contains the structure (design) of the blog and which will display the blog entry that is passed to it from the controller through the form of variables. Let&#8217;s say our view (which display a blog entry) is called &quot;entry_view.php&quot;: </p>
<pre>&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Showing a blog entry&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;?php
	echo &quot;&lt;h1&gt;$entry_title&lt;/h1&gt;&quot;;
	echo $entry_text;
?&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>When we invoke the view from the controller, we will pass in the variables $entry_title and $entry_text. Here is how we invoke the view we have defined above from a controller:</p>
<pre>$data['entry_title'] = &quot;A blog post title&quot;;$data['entry_text'] = &quot;Lorem ipsum dolor sit amet...&quot;;$this-&gt;load-&gt;view('entry_view', $data); </pre>
<p>I have shown a very simple example of how data is passed from the controller to a view above. The variables that will be used in the view are defined as elements of an associative array. To load a view, we call it by its filename &#8211; we don&#8217;t have to use &quot;.php&quot; extension unless we are using some other extension for the view files.</p>
<p>With that, I have covered the basic skeleton of a CI application. Stay tuned for the next article, in which I will walk you through on how to build a simple application using CodeIgniter, and also cover some more advanced concepts along the way! </p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/writing-web-applications-with-codeigniter-part-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating an inline contact form</title>
		<link>http://query7.com/creating-an-inline-contact-form</link>
		<comments>http://query7.com/creating-an-inline-contact-form#comments</comments>
		<pubDate>Mon, 07 Sep 2009 10:41:50 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=507</guid>
		<description><![CDATA[<p>Customer feedback is arguably one of the most critical factors determining the success of a product over a period of time. Hence, it&#8217;s not surprising that many websites have some form of contact form or another to encourage users to write back to them. Most of these &#8220;contact&#8221; pages tend to be on a separate page which is usually part of the navigation or is linked to with phrases like &#8220;we encourage your feedback&#8221; or &#8220;do get in touch with us&#8221;, etc.</p>
<p>However, I have often noticed that many people (unless they genuinely needed help), either back away from submitting their  comments (when they are confronted by a large  textarea on the contact page), or simply move away from the site as the contact page loads.</p>
<p>Today, let&#8217;s spice things up a bit by using jQuery to load a lightweight inline contact form. So, instead of loading a separate contact form page when the &#8220;contact us&#8221; link is clicked, we will just have a small textarea opens up dynamically right next to  the link &#8211; so that the user can type his feedback and it can be  submitted rightaway using AJAX. Our main aim here is to encourage more users&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Customer feedback is arguably one of the most critical factors determining the success of a product over a period of time. Hence, it&#8217;s not surprising that many websites have some form of contact form or another to encourage users to write back to them. Most of these &#8220;contact&#8221; pages tend to be on a separate page which is usually part of the navigation or is linked to with phrases like &#8220;we encourage your feedback&#8221; or &#8220;do get in touch with us&#8221;, etc.</p>
<p>However, I have often noticed that many people (unless they genuinely needed help), either back away from submitting their  comments (when they are confronted by a large  textarea on the contact page), or simply move away from the site as the contact page loads.</p>
<p>Today, let&#8217;s spice things up a bit by using jQuery to load a lightweight inline contact form. So, instead of loading a separate contact form page when the &#8220;contact us&#8221; link is clicked, we will just have a small textarea opens up dynamically right next to  the link &#8211; so that the user can type his feedback and it can be  submitted rightaway using AJAX. Our main aim here is to encourage more users to provide feedback and although I don&#8217;t have actual data to prove whether an inline form will be any more helpful, I have used it in a  couple of places, and it did appear to bring in more casual feedback  about the site, features etc. Ok, let&#8217;s get started. Here is the <strong><a href="http://www.webdevelopmentbits.com/temp/inline_form_demo.html">demo</a></strong> of how it will all look in the end.</p>
<p>Okay, first let&#8217;s have a hypothetical page in which we want to make use of the inline contact form. The call of action, is obviously the &#8220;We would love to hear your feedback&#8221; link, which has the id &#8220;a_inline_form&#8221;. Initially, this hyperlink will simply point to the default contact form page. We will have the inline form in a DIV with id &#8220;inline_form&#8221;, which will be hidden initially.</p>
<pre>#inline_form {
		/* keep the inline form hidden initially */
		display: none;

		position: relative;
		padding: 10px;
		width: 260px;
	}</pre>
<p>We will now use jQuery to &#8220;hijack&#8221; this link and fire our inline contact form into action:</p>
<pre> // toggle visibility of inline form when link is clicked
$("#a_inline_form").click( function() {

	$("#inline_form").toggle(200);

	$("#inline_form").css( "left", $("#a_inline_form").position().left +
                                                $("#a_inline_form").width() );

	$("#inline_form").css("top", "-40px");

	// get cursor to texarea, ready to receive keystrokes!
	$("#inlinecmt").focus();

	// return false to prevent default link behaviour
	return false;
});</pre>
<p>The above code is fairly self explanatory &#8211; I just want to describe how we are positioning the inline form. jQuery allows us to very easily retrieve the left offset position of an element (even when it&#8217;s not absolutely or relatively positioned!) using &#8220;$(elem).position().left&#8221; property.</p>
<p>In this example, I wanted to place the inline form right next to the comment link. To do that, we can simply set the &#8220;left&#8221; CSS property of the inline form to a value that&#8217;s the sum of the left offset of the feedback link and the width of the comment link &#8211; this will of course place the inline form right next to the feedback link. In addition, we also set the cursor focus to the inline form so that the textarea is ready to receive input right away.</p>
<p>We have a simple &#8220;ok&#8221; button underneath the textarea which will be used to submit the form. We will once again &#8220;hijack&#8221; the form submit event using jQuery and perform the form submission using AJAX. I have omitted the actual form submission and processing here.</p>
<pre>$("#inline_form").submit( function() {

	// make your ajax POST call here...

	$("#a_inline_form").after('&lt;span class="msg"&gt;Thanks for the comment!' +
                               '&lt;/span&gt;');
	$("#inline_form").hide(200);

	setTimeout( '$(".msg").hide()', 2000);

	// return false to prevent default form submission behavior
	return false;
});</pre>
<p>Now, once the AJAX call is successful, we need to notify that to the user and thank him for the feedback. I have chosen to do that by inserting a message right after the feedback link and hiding it (using setTimeout() ) after 2 seconds. Don&#8217;t forget to hide the inline form too. With that, our inline form is up and ready to go!</p>
<p>This is by no means a replacement for the traditional contact form, but it will be handy in places where one requires casual feedback from users. And as you would have already noticed, we have used JavaScript here unobtrusively &#8211; so in case the user has JavaScript disabled, the feedback link merely loads the <a href="http://www.webdevelopmentbits.com/temp/inline_form_contact.html">default contact page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/creating-an-inline-contact-form/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Avoiding long polling</title>
		<link>http://query7.com/avoiding-long-polling</link>
		<comments>http://query7.com/avoiding-long-polling#comments</comments>
		<pubDate>Sun, 26 Jul 2009 15:04:02 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[COMET]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[long polling]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[polling]]></category>
		<category><![CDATA[real time]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=500</guid>
		<description><![CDATA[Right from Twitter to Google Wave, real time information streaming via the browser seems to be the most "happening" thing on the web arena currently. However, feeding real time information as and when it is available to an user using your web application is not as straight forward as it is on a desktop environment.]]></description>
			<content:encoded><![CDATA[<p>Right from Twitter to Google Wave, real time information streaming via the browser seems to be the most &quot;happening&quot; thing on the web arena currently. However, feeding real time information as and when it is available to an user using your web application is not as straight forward as it is on a desktop environment. HTTP is a stateless protocol which does not currently support a two way communication link between the server and the user&#8217;s computer via the browser. </p>
<p>The simplest way to simulate  real time streaming of information is to poll the server every N seconds, and to display the information (if any). The number N will determine how real time the resulting stream of updates will look to a viewer. This model is simply called, polling. Now, polling is bad because it repeatedly connects and disconnects to the server, which when scaled across thousands of users, cause severe strain on your server. This problem becomes even more apparent in cases when the poller returns with empty data most of the times. </p>
<p>The jQuery snippet below polls the server every 3 seconds for new information and displays it in a simple alert box.</p>
<pre>
function callComplete(response) {
	alert("Response received is: "+response);
};

function connect() {
	// when the call completes, callComplete() will be called along with
	// the response returned
	$.post('/path/to/script.php', {}, callComplete, 'json');
};

$(document).ready( function() {
	setInterval(connect,3000);
}
</pre>
</p>
<p><strong>Long polling</strong></p>
<p>This technique is an optimisation of the traditional polling method. In long polling, once the client makes a connection with the server (via JavaScript), the server waits for the data requested by the client to become available. If it&#8217;s not immediately available, the server (being a PHP script for example) loops and sleeps. When the data is available, the server returns the data to the client and the connection closes. When this happens, the client again reconnects with the server (in the callback function of your original AJAX request). </p>
<p>This method is definitely an improvement over mindless polling, as we will avoid repeatedly opening and closing connections when data is not available for long periods of time. However, it is important to be aware of the server side technical limitations of long polling. Since connections might be kept alive for long durations of time, your web server must be capable of handling such large numbers of simultaneous connections. We talked about how certain light weight webservers outperformed Apache in this particular area in the last article. </p>
<p>Let&#8217;s look at a very simple jQuery/PHP long polling example:</p>
<pre>function callComplete(response) {
	alert("Response received is: "+response);
	// reconnect to the server
	connect();
};

function connect() {
	// when the call completes, callComplete() will be called along with
	// the response returned
	$.post('/path/to/script.php', {}, callComplete, 'json');
};

$(document).ready( function() {
	connect();
}
</pre>
</p>
<p>In the PHP end, we do:</p>
<pre>
while(1) {

	$data = &quot;some data fetched from the DB&quot;;

	// if we have new data, return it to the client
	if(!empty($data)) {
		echo json_encode($data);
		break;
	}

	sleep(3000);	// we sleep for 3s and check again for data
}
</pre>
<p><strong>COMET streaming </strong></p>
<p>COMET is a generic term that refers to the use a persistent HTTP connection for the web server to &quot;push&quot; data to the client as and when it arrives. If you have ever wondered how Gmail is able to notify you of a new email message seconds after it is sent, this is what they use to push the new email notifications to the front end. </p>
<p>However, as often is the case with JavaScript, the cross browser compatibility issues mean that a host of methods (targeting different browsers) are used to implement such an interaction. The upside is that these methods rely purely on JavaScript, and hence not dependent on any specific client side plugin. A detailed exploration of these different methods and their caveats is beyond the scope of this article, but let&#8217;s get a quick overview of these methods.</p>
<p><strong>Hidden iframe technique:</strong> A hidden iframe html element is embedded onto the page, which points to the URL on the server which handles the persistent connection. The server will then push the data as it arrives to the iframe, using &lt;script&gt; tags. This content is then channeled to the parent window using JavaScript. This method is based on the fact that many browsers evaluate JavaScript chunks as they are received, even if the complete page has not finished loading yet. However this method is prone to cause the &quot;loading&quot; icon or status bar message to appear all the time (since we are using a persistent HTTP connection, the browsers tend to believe that the page is yet to finish loading fully). </p>
<p><strong>XMLHttpRequest using Interactive readyState:</strong> This method is targetted towards Firefox, Safari and Chrome, which support the interactive readyState property of the XHR object, and fires events every time a chunk of data is received from the server. </p>
<p><strong>Server-Sent events: </strong>This is a feature (from the <a href="http://whatwg.org">WHATWG</a> Web Applications 1.0 specification) supported by Opera since v9, using which we can push events from the server directly to the visitor&#8217;s browser. Refer to <a href="http://my.opera.com/WebApplications/blog/show.dml/438711">this article</a> on how it&#8217;s used. </p>
<p>As you can see, it&#8217;s quite a mouthful, and hence implementing COMET streaming which works uniformly across all major browsers is not a task for the faint hearted (not forgetting that the webserver must also be able to handle a large number of persistent connection). The good news is that quite a lot of the hard work has already been done for you. There are various opensource COMET servers and client libraries which you can use to deploy a COMET application pretty safely. Here are a few of them for your exploration: </p>
<p><strong><a href="http://orbited.org">Orbited</a>:</strong> &quot;Orbited is an HTTP daemon that is optimized for long-lasting comet  connections. Orbited allows you to write real-time web  applications, such as a chat room or instant messaging client, without  using any external plugins like Flash or Java. &quot;</p>
<p><a href="http://cometdproject.dojotoolkit.org/"><strong>Cometd:</strong></a> &quot;Cometd is a scalable HTTP-based event routing bus that uses a Ajax Push technology pattern known as Comet.&quot; </p>
<p><strong><a href="http://meteorserver.org/">Meteor</a>:</strong> &quot;Meteor is an open source HTTP server, designed to offer developers a simple means of integrating streaming data into web applications without the need for page refreshes.&quot;</p>
<p><a href="http://pi.kodfabrik.com/documentation/plugin/pi.comet/"><strong>Comet Pi:</strong></a> This is a standalone JavaScript library which you can use to handle the various cross browser issues that COMET causes. You can use pi.comet with any serverside language. </p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/avoiding-long-polling/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Light weight alternatives to Apache</title>
		<link>http://query7.com/light-weight-alternatives-to-apache</link>
		<comments>http://query7.com/light-weight-alternatives-to-apache#comments</comments>
		<pubDate>Sun, 14 Jun 2009 18:12:44 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[web-server]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=487</guid>
		<description><![CDATA[When it comes to choosing a Linux web server, Apache, as we all know, is almost a de facto standard. There is even a chance that your web host does not even offer (or worse, know of) an alternative web server. So, it's not a big surprise that many developers don't know too much about what other alternatives are available to them.]]></description>
			<content:encoded><![CDATA[<p>When it comes to choosing a Linux web  server, Apache, as we all know, is almost a de facto standard. There is even a chance  that your web host does not even offer (or worse, know of) an alternative web  server. So, it&#8217;s not a big surprise that many developers don&#8217;t know too much  about what other alternatives are available to them.</p>
<p>There is of course no denying that Apache  is indeed an old war horse, and an extremely robust and mature one at that. But,  even as stable as Apache is, it has one main drawback &#8211; it occupies a large  memory footprint due to its request-per-process model, and is therefore mediocre  at handling multiple concurrent requests when you have a limited RAM. This can  be a problem when you are starting out small, with a rented 256 MB VPS for your  application. Even if you are a big player, light weight Apache alternatives can  help increase the throughput of your servers. Youtube, for instance, was using  Lighttpd, a light-weight web server to serve millions of videos everyday (prior  to their acquisition by Google).</p>
<p>Ok enough digressing, let’s now take a look  at some of the open source alternatives to Apache.</p>
<p><strong>Lighttpd</strong></p>
<p><a href="http://www.lighttpd.net/">Lighttpd</a>, pronounced as Lighty, is a single  threaded web server optimized for a large number of keep-alive connections,  which is often a requirement for high traffic web applications. It was  originally developed by the German programmer Jan Kneschke to solve the  <a href="http://www.kegel.com/c10k.html">C10k problem</a> (handle 10,000 parallel  connections using a single server). Apart from Youtube as I have already  mentioned, Wikipedia, Meebo and Sourceforge all use Lighttpd. Lighttpd is rich  with features, and offers mod_rewrite (URL rewriting), FastCGI support, HTTP  compression, amongst many other features. I was able to install and configure  Lighttpd in a few minutes, and it is extremely light-weight (less than 1MB). I  was able to get PHP/MySQL running in a couple of minutes, using the FastCGI  interface.</p>
<p>One drawback, which I have seen repeatedly  mentioned in many forums and blogs on the web (I could not verify these claims  with my own tests), is that Lighttpd seems to suffer from memory leaks &#8211;  which often required scheduled server restarts.</p>
<p><strong>Nginx</strong></p>
<p><a href="http://nginx.net/">Nginx</a>, pronounced as Engine-X, is a web  server originating from Russia, and is written by <a href="http://sysoev.ru/en/">Igor  Sysoev</a>. Unlike Lighttpd, Nginx is not a single  threaded webserver (it instead uses a single master process which delegates  work to a small number of worker processes), but is another popular light  weight web server alternative. It is supported by more than 20% of Russian  virtual hosts, and is gaining lots of attention these days in other parts of  the world too.</p>
<p>Nginx is excellent at serving static files  and also supports reverse proxying. Like Lighttpd, I was able to get Nginx up  and running in a few minutes. However, it does not come up with default FastCGI  support &#8211; so getting PHP/MySQL working was a little tricky. It involves  spawning a FastCGI process manually. I found <a href="http://bc-dev.net/2008/05/07/mysql-nginx-and-php-on-ubuntu-804/">this tutorial helpful</a>.</p>
<p><strong>Erlang based alternatives</strong></p>
<p>Erlang is a concurrent programming language  designed by Ericsson to support distributed, soft real time applications, which  has been opensourced since 1998. I definitely want to write more about how  scalable Erlang is, but this is not the article for that. So, let’s just say  that Erlang is tailor-made for high demand applications which need to handle  multiple concurrent connections &#8211; like a web server.</p>
<p><a href="http://yaws.hyber.org/">YAWS</a> (Yet Another Web Server) and <a href="http://code.google.com/p/mochiweb/">Mochiweb</a> are two Erlang based  web servers which I found to be highly scalable and light-weight.</p>
<p>A load test conducted matching Yaws against  Apache found that Apache failed at 4,000 concurrent connections, while Yaws  continued functioning with over 80,000 concurrent connections (<a href="http://www.sics.se/~joe/apachevsyaws.html">source</a>). I did have some trouble installing  and configuring YAWS though. The documentation is scarce, to say the least.</p>
<p>Mochiweb is actually an Erlang library for  building your own light-weight HTTP server. Don&#8217;t be put off by that statement!  A simple server can be built with just a few lines of code. I installed and  tested Mochiweb too, and I found it pretty easy. If you are interested, here is  <a href="http://beebole.com/en/blog/erlang/how-to-quickly-set-up-ubuntu-804-loaded-with-erlang-mochiweb-and-nginx/">a tutorial which I found helpful</a>.</p>
<p><strong> So should you ditch Apache?</strong></p>
<p>This decision depends on a number of  factors. Like I have already stated, if you want to make the best out of the  limited resources you have, then a light-weight web server is definitely  advantageous. However, from my experience with playing with the above  alternatives, if you do decide to go with one of them, you should be prepared to  roughen it out. Poor documentation and support (the mailing lists and forums  are generally helpful, but you can never completely rely on them when you are  suddenly facing an issue in a production environment) could end up making  things difficult for you. Don&#8217;t get me wrong, I am not saying that these servers are not  production-ready yet (they <em>are</em> pretty  stable), but there is always an off-chance you might just hit upon some snag.  In that case, you probably have to roughen it out.</p>
<p>A reasonable choice would be to front  Apache with one of these light weight web servers. In effect, you can use them  for load balancing. Using reverse-proxying, you can handle the static files  (like CSS and images) using a light weight web server, and route the dynamic  requests to Apache.</p>
<p>So, in future, I hope you will consider an  Apache alternative, should your needs be better satisfied by a light-er web  server. If you have experience using any of the above alternatives, do share  your views in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/light-weight-alternatives-to-apache/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dual form processing</title>
		<link>http://query7.com/dual-form-processing</link>
		<comments>http://query7.com/dual-form-processing#comments</comments>
		<pubDate>Tue, 14 Apr 2009 14:18:39 +0000</pubDate>
		<dc:creator>Kishore Nallan</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.webdevelopmentbits.com/?p=477</guid>
		<description><![CDATA[<p>Recently, a client of mine wanted a single web form, residing on the localhost to submit the form contents to a database in the localhost, and as well as to a web server simultaneously. Although this sounds like an unnecessary duplication of data, my client wanted some of the form data to be stored on the localhost for the intranet applications to use. Achieving this functionality <em>would have</em> been a piece of cake, if we were not handicapped by the unavailability of cross-domain AJAX. For those of us familiar with AJAX, we know that we cannot send an AJAX request to a remote server due to security reasons &#8211; atleast not in a reliable, hack-less way.</p>
<p>So, instead of looking for a pure AJAX solution, I decided to implement this functionality by using a combination of AJAX (for the localhost) and a traditional PHP POST request (for the web server). The trick here is to execute the AJAX call before the form is submitted &#8211; by catching the form submission event using JavaScript. Once the AJAX call is successful, we allow the default form submission to take place. In case there is an error with our AJAX call, we should&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Recently, a client of mine wanted a single web form, residing on the localhost to submit the form contents to a database in the localhost, and as well as to a web server simultaneously. Although this sounds like an unnecessary duplication of data, my client wanted some of the form data to be stored on the localhost for the intranet applications to use. Achieving this functionality <em>would have</em> been a piece of cake, if we were not handicapped by the unavailability of cross-domain AJAX. For those of us familiar with AJAX, we know that we cannot send an AJAX request to a remote server due to security reasons &#8211; atleast not in a reliable, hack-less way.</p>
<p>So, instead of looking for a pure AJAX solution, I decided to implement this functionality by using a combination of AJAX (for the localhost) and a traditional PHP POST request (for the web server). The trick here is to execute the AJAX call before the form is submitted &#8211; by catching the form submission event using JavaScript. Once the AJAX call is successful, we allow the default form submission to take place. In case there is an error with our AJAX call, we should stop the propogation of the traditional form submission too.</p>
<p>Ok, so let&#8217;s start off with a simple example &#8211; a no-frills form with a few fields.</p>
<pre>

&lt;form method="post" id="webform" action="http://www.example.com/path/to/PHPscript.php"&gt;

&lt;label for="firstname"&gt;first name:&lt;/label&gt;
&lt;input type="text" name="firstname" id="firstname" value="" /&gt;

&lt;label for="lastname"&gt;last name:&lt;/label&gt;
&lt;input type="text" name="lastname" id="lastname" value="" /&gt;

&lt;label for="email" id="l_email"&gt;email address:&lt;/label&gt;
&lt;input type="text" name="email" id="email" value="" /&gt;

&lt;input type="submit" name="Submit" id="submit_butt" value="Submit" /&gt;
&lt;input type="reset" /&gt;

&lt;/form&gt;
</pre>
<p>When the above form is submitted as it is, the form contents will be sent to the PHP script in the webserver. As I mentioned earlier, what we need to do now is &#8220;catch&#8221; this form submission event and insert our AJAX call before that. Let&#8217;s see how we can do that now. We will be using jQuery for our JavaScript needs.</p>
<pre>

$(document).ready(function(){
$("#webform").submit( function()
{
var success = -1;

$.post("localScript.php",
{
firstname: $("#firstname").val(),
lastname: $("#lastname").val(),
email: $("#email").val()
},

function(response){

if(response.status == "0")
success = false;
else
success = true;

}, "json");

var d = new Date();
var t = d.getSeconds();

while(success==-1)
{
var d = new Date();
if(d.getSeconds() - t &gt; 4)
{
success = false;
break;
}
}

return success;
});
});
</pre>
<p>We set-up an event handler using jQuery, which fires whenever the form is submitted. We then make an AJAX call to the localhost to submit the form contents. We have a callback function which checks the status of the AJAX call. In case, any error occurs on the localhost, an error code can be returned (in our case, the status value will be 0) and we have to stop the form submission by returning &#8220;false&#8221; from the event handler function. This will stop the default action of the submit button, i.e. it will prevent the HTTP form submission.</p>
<p>This is achieved using a hack. Since the script will not wait for the callback function to return, the next statement, i.e. the &#8220;return&#8221; statement will be executed immediately after the $.post() call is made to the server. However, we cannot return from the function without knowing whether the operation on the backend succeeded or not. Since, JavaScript does not natively have any sleep()-like function, we have to force our script to get into a blocked state using a while() loop. We then manually terminate the while loop if we did not hear back from the server within a &#8220;few&#8221; seconds. In our example we have defined the timeout to be 4 seconds. In case we don&#8217;t hear from the server within this time, we will terminate the form submission by returning a &#8220;false&#8221;. This elaborate hack is required to ensure that we do not proceed to the next stage without knowing what happened to the data we submitted to the localhost.</p>
<p>If everything goes well in the localhost, the contents of the form will be processed and stored in the localhost database by the PHP script we have called using AJAX. The submit event handler will then return &#8220;true&#8221;. This would in turn cause the form to be submitted to the PHP script on the remote server, as defined in the action attribute of the &lt;form&gt; tag. Once the form is submitted, the browser requests, and loads this PHP script. The PHP scripts recieves the form contents as POST variables and saves them (by perhaps, storing them in a database).</p>
<p>We are not done yet, though. We still have to send the user back to a page on the localhost once the PHP script has finished processing and storing the form contents. We do that by:</p>
<pre>
</pre>
<pre>$redirect_url = "http://localhost/path/to/some/page";
header( 'Location: ' . $redirect_url );
exit;</pre>
<p>It is important that the header() is called <em>before</em> any actual output is sent to the browser. For example, you should not have any echo statement, or raw HTML output before calling the header().</p>
<p>That&#8217;s about it! Now we are really done! In most cases, you will notice that this entire process is so slick that your user would hardly notice the redirection from the page on the webserver to the page on the localhost! I have put together a barebones HTML page containing the code fragments above, which you can download for your reference and use from <a href="http://labs.sourcebits.com/wdb/dual_form_processing_demo.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://query7.com/dual-form-processing/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

