<?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>Tony Bhimani&#039;s Blog &#187; PHP</title>
	<atom:link href="http://www.tonybhimani.com/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tonybhimani.com</link>
	<description>Where I Share my Linux + Mac + Programming Experiences</description>
	<lastBuildDate>Mon, 24 Oct 2011 05:00:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>AJAX: Learn The Basics Without Using Toolkit Libraries</title>
		<link>http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/</link>
		<comments>http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 05:00:28 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=408</guid>
		<description><![CDATA[AJAX is one of the popular acronym buzzwords in the world of web development technologies. It stands for Asynchronous JavaScript and XML. What it does is allow you to make your website far more dynamic by updating portions in realtime &#8230; <a href="http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>AJAX is one of the popular acronym buzzwords in the world of web development technologies. It stands for Asynchronous JavaScript and XML. What it does is allow you to make your website far more dynamic by updating portions in realtime without page reloads (refreshes). This beginners AJAX tutorial will teach you how to write JavaScript code to do some simple screen updates. It&#8217;ll focus on a low-level AJAX implementation meaning JavaScript toolkits like jQuery and script.aculo.us will not be used (future tutorials will make use of these high-level time-saving tools). In my opinion, learning AJAX in this manner is far better because you&#8217;ll grasp the concept and it will help you move in the direction of using toolkits to simplify your coding (<em>you must crawl before you can walk&#8230;</em>). Also, this AJAX tutorial will be the first post in a series I plan on publishing regarding this subject.</p>
<p><strong>Phase 1: Writing the AJAX JavaScript Code &#8211; Making the Call</strong></p>
<p>I first learned AJAX from the <a href="http://www.w3schools.com/" rel="nofollow" target="_blank">W3Schools</a> website and will be using their code base as the foundation for this AJAX tutorial. The first step in working with AJAX is to create an object of <code>XMLHttpRequest</code>. The Firefox, Opera, Safari, and Internet Explorer browsers all handle this differently, however code wise the first three are the same. Internet Explorer (yes, Microsoft) has to take a unique approach (putting it nicely) which is different than the other mainstream web browsers. Getting back on point now, the code below is a modified version of what you can find from the W3Schools AJAX Guide for creating a object for <code>XMLHttpRequest</code> (the interface to make AJAX music).</p>
<pre class="code">function GetXmlHttpObject() {
  var xmlHttp = null;
  try {
    // Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer
    try {
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  return xmlHttp;
}</pre>
<p>The code starts with creating a variable handle for the <code>XMLHttpRequest</code> object and making it null. Within a <code>try</code> and <code>catch</code> block the <code>XMLHttpRequest()</code> method is called. If an object is created then exit the function and return the object. If the object can&#8217;t be created then the ActiveX (Microsoft) route is taken by using <code>Msxml2.XMLHTTP</code> and <code>Microsoft.XMLHTTP</code>. If this part fails as well, AJAX isn&#8217;t possible with the browser for whatever reason, otherwise after having called this <code>GetXmlHttpObject()</code> function we&#8217;ll have an AJAX object to work with. Next we&#8217;ll build an AJAX request.</p>
<pre class="code">// create xml http object
var objXmlHttp = GetXmlHttpObject();
// open a connection and send the ajax request
objXmlHttp.open("GET", "http://www.domain.com/ajaxresponder.php", true);
objXmlHttp.send();</pre>
<p>The AJAX request is composed of a call to the <code>open</code> and <code>send</code> methods of the <code>XmlHttpRequest</code> object. The <code>open</code> method takes three parameters (type of request [GET or POST], URL of the file on the server, and boolean true [asynchronous] or false [synchronous]).</p>
<ul>
<li>
<p><strong>Type of Request:</strong> GET or POST? Well, it depends on your requirements but most of the time you will be using GET for your AJAX calls. AJAX is information dependent meaning that what you give it will determine what it gives back to you. For example, say you&#8217;re providing a weather service and want to get the temperature for a specific zip code. That zip code would be passed as part of the URL in the query string. The file on the server would accept that input and give the temperature as output.</p>
</li>
<li>
<p><strong>URL of file on the server:</strong> This URL is where the processing of your data happens. The type of file will be a dynamic server-side scripting language such as PHP that can take your input (via GET or POST), process it, and send back formatted output that you will present to the user&#8217;s browser. Using the weather example from above, this script would take the zip code and possibly do a database lookup to get the temperature and pass it back to the AJAX caller.</p>
</li>
<li>
<p><strong>Asynchronous or Synchronous:</strong> Once again, depending on your requirements you may choose one option over the other. A high percentage of the time your calls will be asynchronous, which means that once the AJAX call is issued your browser won&#8217;t be held up waiting on the response; it can continue doing other tasks and once the response does come in it can be processed. One instance when a synchronous call would be necessary is when the response of a first AJAX call is required by a second call. If you keep it asynchronous then once the first AJAX call is done the second would run right away. There is no guarantee that the first call would be fast enough to get the result to pass to the second call, hence keeping it synchronous forces the order of operations to follow through. Be careful though! If the synchronous call takes a long time processing it can appear that your browser window has locked up!</p>
</li>
</ul>
<p><strong>Phase 2: Crafting a Server-Side PHP Script to Process AJAX Requests</strong></p>
<p>With the JavaScript code in place for invoking the AJAX call the server-side script to handle that call needs to be written. The sole purpose of this script will be to listen for the AJAX call, process the request, and send back output. Because this is AJAX tutorial is being written in a manner with beginners in mind, the server-side script is going to be extremely basic. What it will do is send back a random quote from a famous author. In the next tutorial I&#8217;ll take it up a notch by showing you how to integrate a database and fetching data.</p>
<p>I&#8217;ll be using PHP to write this server-side script because that is my preferred language, however you can use Perl CGI, Cold Fusion, Microsoft&#8217;s Active Server Pages, ASP.NET or another language as long as the server that will be hosting the script can support it. If you don&#8217;t know PHP then try and follow along and I&#8217;ll explain the code as I go.</p>
<pre class="code">&lt;?php

/************************************************
      AJAX FAMOUS AUTHOR QUOTE SCRIPT
  Quotes Source: www.famousquotesandauthors.com
*************************************************/

// we use an array for the famous author quotes
$quotes_arr = array(
&quot;I know only that what is moral is what you feel good after and what is immoral is what you feel bad after. - Ernest Hemingway&quot;,
&quot;Eve left Adam, to meet the Devil in private. - Alexander Pope&quot;,
&quot;Democracy is based on the conviction that man has the moral and intellectual capacity, as well as the inalienable right, to govern himself with reason and justice. - Harry S. Truman&quot;,
&quot;Crime is a logical extension of the sort of behaviour that is often considered perfectly respectable in legitimate business. - Robert Rice&quot;,
&quot;By time and toil we sever What strength and rage could never. - Jean de la Fontaine&quot;,
&quot;Human history is in essence a history of ideas. - H. G. Wells&quot;
);

// the quotes are chosen randomly
$quote_choice = rand(0, sizeof($quotes_arr) - 1);

// echo the random quote
echo $quotes_arr[$quote_choice];

?&gt;
</pre>
<p>This is a very simple PHP script. All it does is define a six string array with the variable name of <code>$quotes_arr</code>. One of those six quotes is chosen at random using the PHP <code>rand()</code> function. What <code>rand()</code> will do is pick a random number between 0 and the size of the array less one (6 &#8211; 1 = 5) to serve as an index for choosing a string from the array. Note: PHP arrays are zero-based indexing meaning the first element begins at zero, not one. Finally, using PHP&#8217;s <code>echo</code> the chosen quote string is printed out to the browser.</p>
<p><strong>Phase 3: Putting All This AJAX &amp; PHP Coding Stuff Together</strong></p>
<p>The pieces to this AJAX puzzle are on the table, it&#8217;s time to fit them together. We&#8217;ve learned how to build an AJAX request and what an AJAX processing script can look like, the last step is to build the HTML page that makes use of them. The mechanics will be once the page loads the AJAX request will be made, the famous quote will be received from the server-side script, and the quote will be written to the HTML page. I&#8217;ve also included a button that can be clicked to load a new quote when clicked.</p>
<pre class="code">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;  dir=&quot;ltr&quot; lang=&quot;en-US&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;AJAX Tutorial: Random Famous Quotes&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function GetXmlHttpObject() {
  var xmlHttp = null;
  try {
    // Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer
    try {
      xmlHttp = new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;);
    } catch (e) {
      xmlHttp = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
    }
  }
  return xmlHttp;
}
// create xml http object
var objXmlHttp = GetXmlHttpObject();
// open a connection and send the ajax request
objXmlHttp.open(&quot;GET&quot;, &quot;http://www.tonybhimani.com/files/2011/10/ajax-quotes.php&quot;, true);
objXmlHttp.send();
objXmlHttp.onreadystatechange=function() {
  if (objXmlHttp.readyState == 4 &#038;&#038; objXmlHttp.status == 200) {
    document.getElementById(&quot;quotes&quot;).innerHTML = objXmlHttp.responseText;
  }
}
// --&gt;
&lt;/script&gt;
&lt;p&gt;&lt;strong&gt;Random Quote of the Day&lt;/strong&gt;&lt;/p&gt;
&lt;p id=&quot;quotes&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;input type=&quot;button&quot; name=&quot;reload&quot; value=&quot;Reload Page&quot; onclick=&quot;javascript:window.location.reload(true);&quot; /&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>You may notice I&#8217;ve added some extra code to the AJAX JavaScript section. Because this is an asynchronous call we have to declare an event handler. An event handler is a code block that sits around and waits for an event to occur before it executes its code. Our event handler (JavaScript function) is attached to the <code>onreadystatechange</code> event of the <code>XMLHttpRequest</code> object. It will get executed when the ready state changes. We check two <code>XMLHttpRequest</code> properties <code>readyState</code> and <code>status</code> for specific values. Once these values are attained (<code>readyState</code> of 4 meaning all data has been received and HTTP status of 200) we then use <code>getElementById</code> and change the HTML code between the start and end tags of the P with the id of quotes using this <code>innerHTML</code> property.</p>
<p>Okay, we&#8217;ve reached the end of this beginner&#8217;s AJAX tutorial. I&#8217;ve been talking about AJAX this whole time and I&#8217;m sure you&#8217;re eager to finally see the AJAX code in action. Below is a link to the sample page where you will see a randomly pulled quote from the PHP AJAX script. Click the Reload Page button to see another quote from the PHP array.</p>
<p><a href="http://www.tonybhimani.com/files/2011/10/famous-quotes.html" title="AJAX Tutorial for Beginners: Random Famous Author Quotes" target="_blank"><strong>AJAX Tutorial for Beginners: Random Famous Author Quotes</strong></a></p>
<p>Source Code Download: <a href="http://www.tonybhimani.com/files/2011/10/ajax-tutorial-1-no-toolkits1.zip" title="AJAX Tutorial for Beginners 1 [ No Toolkits ]">AJAX Tutorial for Beginners 1 [ No Toolkits ] (Zip)</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D408&count=vertical&related=&text=AJAX%3A%20Learn%20The%20Basics%20Without%20Using%20Toolkit%20Libraries' class='twitter-share-button' data-text='AJAX: Learn The Basics Without Using Toolkit Libraries' data-url='http://www.tonybhimani.com/?p=408' data-counturl='http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP: Checkbox Arrays with Javascript Usage</title>
		<link>http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/</link>
		<comments>http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 10:12:22 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Arrays]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[HTML Forms]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=314</guid>
		<description><![CDATA[If you&#8217;ve created HTML forms then you&#8217;ll have used checkboxes and radio buttons for gathering user input. Taking it a step further you would link your form with a server-side scripting language such as PHP to capture the user input &#8230; <a href="http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve created HTML forms then you&#8217;ll have used checkboxes and radio buttons for gathering user input. Taking it a step further you would link your form with a server-side scripting language such as PHP to capture the user input and process it. Things get a little tricky when you have groups of checkboxes or radio buttons in your form. Once you create a group of these same control types you form what is known as an array. An array is simply an integer-indexed collection of objects. When defining a checkbox or radio button you need to give it a name. This naming convention allows you to access the value of the control object and use it for whatever purpose you need (store it, email it, etc).</p>
<pre class="code">&lt;form action=&quot;#&quot;&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;English&quot; /&gt; I speak English&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;French&quot; /&gt; I speak French
&lt;/form&gt;
</pre>
<p>Above is an example of two checkboxes for choosing a spoken language. Notice how they both share the same name <em>language</em> to create an array (more precisely a nodelist of elements).</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices1() {
  var strChoices = &quot;&quot;
  var objCBarray = document.getElementsByName('language');
  for (i = 0; i &lt; objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += &quot;* &quot; + objCBarray[i].value + &quot;\n&quot;;
    }
  }
  if (strChoices.length &gt; 0) {
    var strMessage = &quot;You speak\n&quot; + strChoices;
    alert(strMessage);
  } else {
    alert(&quot;Please choose your spoken language(s).&quot;);
  }}
// --&gt;
&lt;/script&gt;
</pre>
<p>Next I have created a simple function called <em>showMyChoices1</em> that loops through the checkboxes, creates a message, and displays it using an alert. The variable <em>objCBarray</em> is a handle for the checkbox nodelist acquired by using <code>getElementsByName</code> Document Object Method. Using a for loop to iterate through each checkbox (the loop count is determined by the length property), the checked ones get added to a string called <em>strChoices</em>. After the for loop is finished the length of the string is tested for a value greater than zero. If it tests positive then an alert is shown with the checked values, otherwise a message prompting the user to select a language is shown.</p>
<p>Let&#8217;s put it all together (including a button) and see it in action. Try it below.<script type="text/javascript" language="JavaScript"><!--
function showMyChoices1() {
  var strChoices = "";
  var objCBarray = document.getElementsByName('language');
  for (i = 0; i < objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += "* " + objCBarray[i].value + "\n";
    }
  }
  if (strChoices.length > 0) {
    var strMessage = "You speak\n" + strChoices;
    alert(strMessage);
  } else {
    alert("Please choose your spoken language(s).");
  }
}
// --></script><br />
<form action="#">
<input type="checkbox" name="language" value="English" /> I speak English<br />
<input type="checkbox" name="language" value="French" /> I speak French<br />
<input type="button" value="Show My Choices" onclick="showMyChoices1();" /></form>
<p>Here is the code for the JavaScript only version.</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices1() {
  var strChoices = &quot;&quot;;
  var objCBarray = document.getElementsByName('language');
  for (i = 0; i &lt; objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += &quot;* &quot; + objCBarray[i].value + &quot;\n&quot;;
    }
  }
  if (strChoices.length &gt; 0) {
    var strMessage = &quot;You speak\n&quot; + strChoices;
    alert(strMessage);
  } else {
    alert(&quot;Please choose your spoken language(s).&quot;);
  }
}
// --&gt;
&lt;/script&gt;
&lt;form action=&quot;#&quot;&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;English&quot; /&gt; I speak English&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;French&quot; /&gt; I speak French&lt;br /&gt;
&lt;input type=&quot;button&quot; value=&quot;Show My Choices&quot; onclick=&quot;showMyChoices1();&quot; /&gt;
&lt;/form&gt;
</pre>
<p>If you plan on using PHP to process your form data then the way the checkboxes were named isn&#8217;t going to work. PHP requires you to name the variable in an array manner. It&#8217;s basically the same as before but you have to add trailing square brackets []. For example, I used <em>language</em> for the name of my checkboxes. To make this work with PHP I&#8217;ll need to use <em>language[]</em>. Having made this change the JavaScript function I&#8217;ve created won&#8217;t work because of the variable name in <code>getElementsByName</code> (be it with or without the brackets, no bueno). Square brackets in JavaScript have a special meaning so two changes need to be made to my code.</p>
<p>The first change is to add an id to the &lt;form&gt; tag so it can be accessed via <code>getElementById</code> (now I&#8217;ll be using this HTML DOM method in place of <code>getElementsByName</code>). The second change is in how I call the <code>getElementById</code>. Notice the notation of how I reference the id of my form and then my checkboxes (BTW, this second function version uses <em>food[]</em> checkboxes). The rest of the function remains the same.</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices2() {
  var strChoices = &quot;&quot;;
  var objCBarray = document.getElementById('myform')['food[]'];
</pre>
<p>Try out the PHP + JavaScript version below.<script type="text/javascript" language="JavaScript"><!--
function showMyChoices2() {
  var strChoices = "";
  var objCBarray = document.getElementById('myform')['food[]'];
  for (i = 0; i < objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += "* " + objCBarray[i].value + "\n";
    }
  }
  if (strChoices.length > 0) {
    var strMessage = "Your favorite food(s)\n" + strChoices;
    alert(strMessage);
  } else {
    alert("Please choose your favorite foods.");
  }
}
// --></script><br />
<form id="myform" action="#">
<p>My favorite food is?</p>
<input type="checkbox" name="food[]" value="Burgers" /> Burgers<br />
<input type="checkbox" name="food[]" value="Pizza" /> Pizza<br />
<input type="checkbox" name="food[]" value="Spaghetti" /> Spaghetti<br />
<input type="checkbox" name="food[]" value="Tamales" /> Tamales<br />
<input type="button" value="Show My Choices" onclick="showMyChoices2();" /></form>
<p>Here is the code for the PHP + JavaScript version.</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices2() {
  var strChoices = &quot;&quot;;
  var objCBarray = document.getElementById('myform')['food[]'];
  for (i = 0; i &lt; objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += &quot;* &quot; + objCBarray[i].value + &quot;\n&quot;;
    }
  }
  if (strChoices.length &gt; 0) {
    var strMessage = &quot;Your favorite food(s)\n&quot; + strChoices;
    alert(strMessage);
  } else {
    alert(&quot;Please choose your favorite foods.&quot;);
  }
}
// --&gt;
&lt;/script&gt;
&lt;form id=&quot;myform&quot; action=&quot;#&quot;&gt;
&lt;p&gt;My favorite food is?&lt;/p&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Burgers&quot; /&gt; Burgers&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Pizza&quot; /&gt; Pizza&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Spaghetti&quot; /&gt; Spaghetti&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Tamales&quot; /&gt; Tamales&lt;br /&gt;
&lt;input type=&quot;button&quot; value=&quot;Show My Choices&quot; onclick=&quot;showMyChoices2();&quot; /&gt;
&lt;/form&gt;
</pre>
<p>All that would be left to do is build a PHP script to process the form submission data and set the script&#8217;s file name as the action in the &lt;form&gt; tag. That&#8217;s beyond the scope of this post, however if you need help doing it, post a comment. Using this code you should now be able to use client-side JavaScript to preprocess form data before it hits the server using standard variable names and PHP array type ones.</p>
<p>Source Code Download: <a href='http://www.tonybhimani.com/files/2011/10/js-php-checkboxes.zip'>JavaScript PHP Checkbox Array Source Code (Zip)</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D314&count=vertical&related=&text=PHP%3A%20Checkbox%20Arrays%20with%20Javascript%20Usage' class='twitter-share-button' data-text='PHP: Checkbox Arrays with Javascript Usage' data-url='http://www.tonybhimani.com/?p=314' data-counturl='http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dovecot IMAP SquirrelMail Cannot Append Error</title>
		<link>http://www.tonybhimani.com/2008/05/31/dovecot-imap-squirrelmail-cannot-append-error/</link>
		<comments>http://www.tonybhimani.com/2008/05/31/dovecot-imap-squirrelmail-cannot-append-error/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 02:48:34 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[Dovecot]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SquirrelMail]]></category>
		<category><![CDATA[IMAP]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=29</guid>
		<description><![CDATA[If you&#8217;re a user of SquirrelMail and Dovecot 1.x, you may run across this error &#8220;ERROR: Bad or malformed request. Server responded: Error in IMAP command APPEND:&#8221; after sending a message. The composed email message still sends, but you get &#8230; <a href="http://www.tonybhimani.com/2008/05/31/dovecot-imap-squirrelmail-cannot-append-error/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a user of SquirrelMail and Dovecot 1.x, you may run across this error &#8220;<strong>ERROR: Bad or malformed request.  Server responded: Error in IMAP command APPEND:</strong>&#8221; after sending a message. The composed email message still sends, but you get that annoying error. I don&#8217;t know exactly what caused it other than a possible Dovecot upgrade, but nevertheless, this is how to alter SquirrelMail to resolve the issue.</p>
<p>In the <em>functions</em> directory of your SquirrelMail install, open the <strong>imap_general.php</strong> file.</p>
<p>Alter the <strong>sqimap_append</strong> PHP function by commenting out the line that starts with the fputs function and type in the replacement so it reads as:</p>
<pre class="code">function sqimap_append ($imap_stream, $sent_folder, $length) {
//    fputs ($imap_stream, sqimap_session_id() . " APPEND \"$sent_folder\" (\\Seen) \{$length}\r\n");
    fputs ($imap_stream, sqimap_session_id() . " APPEND \"$sent_folder\" (\\Seen) {" . $length . "}\r\n");
    $tmp = fgets ($imap_stream, 1024);
    sqimap_append_checkresponse($tmp, $sent_folder);
}</pre>
<p>Save the changes and the problem should be solved. FYI: Upgrading to the latest version of SquirrelMail will resolve this issue as well, but applying this code change is less of a hassle.</p>
<p><strong>Fix Source:</strong> <a href="http://xmailforum.homelinux.net/index.php?showtopic=3023" title="XMail Forum -&gt; dovecot imap cannot append">XMail Forum -&gt; dovecot imap cannot append</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D29&count=vertical&related=&text=Dovecot%20IMAP%20SquirrelMail%20Cannot%20Append%20Error' class='twitter-share-button' data-text='Dovecot IMAP SquirrelMail Cannot Append Error' data-url='http://www.tonybhimani.com/?p=29' data-counturl='http://www.tonybhimani.com/2008/05/31/dovecot-imap-squirrelmail-cannot-append-error/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2008/05/31/dovecot-imap-squirrelmail-cannot-append-error/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2008/05/31/dovecot-imap-squirrelmail-cannot-append-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problems upgrading old PEAR versions</title>
		<link>http://www.tonybhimani.com/2008/04/30/problems-upgrading-old-pear-versions/</link>
		<comments>http://www.tonybhimani.com/2008/04/30/problems-upgrading-old-pear-versions/#comments</comments>
		<pubDate>Thu, 01 May 2008 04:37:33 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PEAR]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=28</guid>
		<description><![CDATA[On some old servers I&#8217;ve had problems upgrading PEAR. I don&#8217;t remember the exact error message but I used it for a quick Google search to find one solution. If you have problems upgrading old versions of PEAR, you can &#8230; <a href="http://www.tonybhimani.com/2008/04/30/problems-upgrading-old-pear-versions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>On some old servers I&#8217;ve had problems upgrading PEAR. I don&#8217;t remember the exact error message but I used it for a quick Google search to find one solution. If you have problems upgrading old versions of PEAR, you can try these steps to force an upgrade from PEAR 1.3.2 and up.</p>
<p>You can use these commands to force the upgrade.</p>
<pre class="code">pear upgrade --force http://pear.php.net/get/Archive_Tar http://pear.php.net/get/XML_Parser http://pear.php.net/get/Console_Getopt-1.2.2
pear upgrade --force http://pear.php.net/get/PEAR-1.3.3 (use only if your PEAR is older than v1.3.3)
pear upgrade --force http://pear.php.net/get/PEAR-1.4.3
pear upgrade PEAR</pre>
<p>Here you can see the upgrade in action (fun fun fun).</p>
<pre class="code">[root@linux ~]# pear upgrade --force http://pear.php.net/get/Archive_Tar http://pear.php.net/get/XML_Parser http://pear.php.net/get/Console_Getopt-1.2.2
downloading Archive_Tar-1.3.2.tgz ...
Starting to download Archive_Tar-1.3.2.tgz (17,150 bytes)
......done: 17,150 bytes
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
downloading XML_Parser-1.2.8.tgz ...
Starting to download XML_Parser-1.2.8.tgz (13,476 bytes)
...done: 13,476 bytes
downloading Console_Getopt-1.2.2.tgz ...
Starting to download Console_Getopt-1.2.2.tgz (4,252 bytes)
...done: 4,252 bytes
Did not download optional dependencies: pear/XML_RPC, use --alldeps to download automatically
warning: pear/PEAR dependency package "pear/Console_Getopt" downloaded version 1.2.2 is not the recommended version 1.2.3
downloading PEAR-1.7.1.tgz ...
Starting to download PEAR-1.7.1.tgz (302,377 bytes)
...done: 302,377 bytes
upgrade ok: channel://pear.php.net/PEAR-1.7.1
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
upgrade ok: channel://pear.php.net/Console_Getopt-1.2.2
upgrade ok: channel://pear.php.net/XML_Parser-1.2.8
upgrade ok: channel://pear.php.net/Archive_Tar-1.3.2
To install use "pear install pear/PEAR#featurename"
[root@linux ~]# pear upgrade --force http://pear.php.net/get/PEAR-1.4.3
downloading PEAR-1.4.3.tgz ...
Starting to download PEAR-1.4.3.tgz (276,859 bytes)
.........................................................done: 276,859 bytes
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
Did not download optional dependencies: pear/XML_RPC, use --alldeps to download automatically
downloading Console_Getopt-1.2.3.tgz ...
Starting to download Console_Getopt-1.2.3.tgz (4,011 bytes)
...done: 4,011 bytes
upgrade ok: channel://pear.php.net/Console_Getopt-1.2.3
upgrade ok: channel://pear.php.net/PEAR-1.4.3
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"
[root@linux ~]# pear upgrade PEAR
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
Did not download optional dependencies: pear/XML_RPC, use --alldeps to download automatically
downloading PEAR-1.7.1.tgz ...
Starting to download PEAR-1.7.1.tgz (302,377 bytes)
..............................................................done: 302,377 bytes
upgrade ok: channel://pear.php.net/PEAR-1.7.1
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
To install use "pear install PEAR#featurename"</pre>
<p>This article is based entirely from this PEAR Bug posting:<br />
<a href="http://pear.php.net/bugs/bug.php?id=12990" title="PEAR :: Bug #12990 :: Issues with PEAR Upgrade News Item from 1/3/08">PEAR :: Bug #12990 :: Issues with PEAR Upgrade News Item from 1/3/08</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D28&count=vertical&related=&text=Problems%20upgrading%20old%20PEAR%20versions' class='twitter-share-button' data-text='Problems upgrading old PEAR versions' data-url='http://www.tonybhimani.com/?p=28' data-counturl='http://www.tonybhimani.com/2008/04/30/problems-upgrading-old-pear-versions/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2008/04/30/problems-upgrading-old-pear-versions/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2008/04/30/problems-upgrading-old-pear-versions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Captcha Images with PHP and the GD Library</title>
		<link>http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/</link>
		<comments>http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 06:34:01 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[security images]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/</guid>
		<description><![CDATA[A long time ago I wrote some code to create captcha images using PHP. The goal was to create similar or exact representations of the captcha&#8217;s used on Yahoo&#8217;s Overture. I really don&#8217;t have an answer why I chose their &#8230; <a href="http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A long time ago I wrote some code to create <a href="http://en.wikipedia.org/wiki/Captcha" title="Captcha definition on Wikipedia" target="_blank">captcha</a> images using PHP. The goal was to create similar or exact representations of the captcha&#8217;s used on Yahoo&#8217;s Overture. I really don&#8217;t have an answer why I chose their style except that it&#8217;s possible I liked the way they looked. I am sharing this code for creating the images but it&#8217;s up to you to create some logic in applying their use with HTML forms (I&#8217;ll give some hints at the end of this post).</p>
<p>This is the code to create the image. It returns an image resource identifier.  Note the use of a custom TrueType font &#8212;  you&#8217;ll need to change that line to the path of a font on your system.</p>
<pre class="code">&lt;?php
// generate captcha image - returns image handle
function captcha_image($code_string, $img_width=150, $img_height=40) {
  // seed srand
  srand((double)microtime()*1000000);

  // create image
  $im = @imagecreate($img_width, $img_height) or die("Cannot Initialize new GD image stream");

  // security code
  $security_code = $code_string;

  // define font
  $font = "/usr/fonts/ttf/Georgia.ttf";

  // create some colors
  $black = imagecolorallocate($im, 0, 0, 0);
  $white = imagecolorallocate($im, 255, 255, 255);
  $grey = imagecolorallocate($im, 128, 128, 128);

  // randomness, we need lots of randomness <img src='http://www.tonybhimani.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
  // background color -&gt; 1=black, 2=white, 3=grey (more colors can be added)
  // lines -&gt; black bg (1=white or 2=grey), white bg (1=black or 2=grey), grey bg (black only)
  $randval = rand(1, 3);
  if ($randval == 1) {
    $bgcolor = $black;
    $fontcolor = $white;
    $linecolor = ((rand(0, 1) == 0) ? $black : $white);
  } elseif ($randval == 2) {
    $bgcolor = $white;
    $fontcolor = $black;
    $linecolor = ((rand(0, 1) == 0) ? $black : $white);
  } else {
    $bgcolor = $grey;
    $fontcolor = $black;
    $linecolor = ((rand(0, 1) == 0) ? $black : $grey);
  }

  // line positioning and increment
  $x_start = rand(0, 10);
  $x_size = rand(5, 10);
  $y_start = rand(0, 10);
  $y_size = rand(5, 10);

  // fill with background color
  imagefill($im, 0, 0, $bgcolor);

  // initial x position
  $font_x = 10;

  // write text
  for ($i = 0; $i &lt; strlen($security_code); $i++) {
    // font size -&gt; 20 to 35
    $font_size = rand(25, 35);
    // font angle -&gt; -20 to +20
    $font_angle = rand(0, 20);
    if ($font_angle != 0) { if (rand(0, 1) == 0) { $font_angle = -$fone_angle; } }
    // font y position -&gt; if font_size &lt;= 27 then 30 to 35, if font_size &gt; 27 then 30 to 35
    if ($font_size &lt;= 27) { $font_y = rand(25, 30); } else { $font_y = rand(30, 35); }
    // write the text
    imagettftext($im, $font_size, $font_angle, $font_x, $font_y, $fontcolor, $font, $security_code{$i});
    // one more time to make it bolder
    imagettftext($im, $font_size, $font_angle, $font_x+1, $font_y+1, $fontcolor, $font, $security_code{$i});
    // next font x position
    $font_x += ($font_size + 5);
  }

  // draw horizontal lines
  for ($y = $y_start; $y &lt; $img_height; $y += $y_size) {
    imageline($im, 0, $y, $img_width, $y, $linecolor);
  }
  // draw vertical lines
  for ($x = $x_start; $x &lt; $img_width; $x += $x_size) {
    imageline($im, $x, 0, $x, $img_height, $linecolor);
  }

  // return captcha image handle
  return $im;
}
?&gt;</pre>
<p>We need a method for generating random four character strings when the captcha is created and displayed to the user. This function will do the trick.</p>
<pre class="code">&lt;?php
function secret_key($length=4) {
  $salt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
  srand((double)microtime()*1000000);
  $i = 0;
  $skey = "";
  while ($i &lt; $length) {
    $num = rand() % strlen($salt);
    $tmp = substr($salt, $num, 1);
    $skey .= $tmp;
    $i++;
  }
  return $skey;
}
?&gt;</pre>
<p>With everything in place, we can generate the secret key, create the captcha, and finally display it to the user using this code.</p>
<pre class="code">&lt;?php
// set headers
header("Content-type: image/png");
header("Cache-Control: no-cache");
header("Pragma: no-cache");

// generate secret
$skey = secret_key();

// create captcha and output to browser as PNG image
$im = captcha_image($skey);
@imagepng($im);
@imagedestroy($im);
?&gt;</pre>
<p>Here is an example of the code in action. The style looks very similar to the images used on <a href="https://secure.overture.com/login.do" title="Yahoo's Overture" target="_blank">Yahoo&#8217;s Overture</a>.</p>
<p><strong><font size="+1">Captcha Demo »</font></strong>   <img src="http://www.tonybhimani.com/files/captcha/captcha.php" alt="Captcha" /></p>
<p>Now you know how to create a captcha, so what about verifying the input against the captcha value? This can be accomplished a variety of ways and everyone tends to have their preference.</p>
<ul>
<li>One method is to save the secret key in a session variable. As the image is created, store the key in a session variable and once the form is submitted, check the user&#8217;s value against the one stored in the session. If they match, proceed but if they fail, return an error and don&#8217;t process the form data.</li>
<li>If you don&#8217;t want to use sessions, you could try using temp files. Store the key in a temp file and pass some value as a query string identifying to the script that the key is in that file. Read in the key and <a href="http://www.php.net/manual/en/function.md5.php" title="PHP: md5 function reference" target="_blank">MD5</a> or <a href="http://www.php.net/manual/en/function.sha1.php" title="PHP: sha1 function reference" target="_blank">SHA1</a> crypt the key and save it in a hidden form field. When the form is submitted, compare the hashed key against the user input (which you will also hash). Process the form data if the keys match.</li>
</ul>
<p>You can download the provided source file. Use the PHP file as an image source in your HTML IMG tag.</p>
<pre class="code">&lt;img src="<span style="background-color: #ffff00">http://www.yourdomain.com/captcha.php</span>"&gt;</pre>
<p>Don&#8217;t forget to edit the path to the TrueType font you want to use in the <em>captcha_image</em> function. Failure to do so will lead to missing image characters.</p>
<p><strong>Source Files:</strong> <a href="http://www.tonybhimani.com/files/2008/02/captcha.zip" title="Captcha PHP Source Code">captcha.zip</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D17&count=vertical&related=&text=Creating%20Captcha%20Images%20with%20PHP%20and%20the%20GD%20Library' class='twitter-share-button' data-text='Creating Captcha Images with PHP and the GD Library' data-url='http://www.tonybhimani.com/?p=17' data-counturl='http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Searching for fields in unknown MySQL tables</title>
		<link>http://www.tonybhimani.com/2007/11/02/searching-for-fields-in-unknown-mysql-tables/</link>
		<comments>http://www.tonybhimani.com/2007/11/02/searching-for-fields-in-unknown-mysql-tables/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 03:28:20 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/2007/11/02/searching-for-fields-in-unknown-mysql-tables/</guid>
		<description><![CDATA[A friend emailed me weeks ago asking if there is a SQL SELECT statement to search for fields in a database if the table names are unknown. As far as I knew there wasn&#8217;t and suggested creating a script to &#8230; <a href="http://www.tonybhimani.com/2007/11/02/searching-for-fields-in-unknown-mysql-tables/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A friend emailed me weeks ago asking if there is a SQL SELECT statement to search for fields in a database if the table names are unknown. As far as I knew there wasn&#8217;t and suggested creating a script to do the searching for her.</p>
<p>1. Here&#8217;s a code snippet to achieve a search for a single field across all tables in a specified database.</p>
<pre class="code">&lt;?php
// variables
$dbname = 'my_db';
$dbfield = 'my_field';
// connect to database
$dblink = mysql_connect('localhost', 'user', 'password');
if ($dblink) {
  mysql_select_db($dbname, $dblink);
} else {
  die('Failed to connect to DB');
}
// get table list
$query = "show tables";
$result = mysql_query($query, $dblink);
// loop through table names
while (list($table) =  mysql_fetch_row($result)) {
  // get table description
  $query = "describe $table";
  $result2 = mysql_query($query, $dblink);
  // loop through table description fields
  while ($row = mysql_fetch_array($result2, MYSQL_ASSOC)) {
    // does this field match what we're looking for?
    if ($row['Field'] == $dbfield) {
      echo "Found '".$row['Field']."' in table =&gt; $table&#92;n";
    }
  }
  mysql_free_result($result2);
}
mysql_free_result($result);
?&gt;</pre>
<p>2. This is a variant to achieve a search for an array of fields across all tables in a specified database.</p>
<pre class="code">&lt;?php
// variables
$dbname = 'my_db';
$dbfields = array('my_field1','my_field2','my_field3');
// connect to database
$dblink = mysql_connect('localhost', 'user', 'password');
if ($dblink) {
  mysql_select_db($dbname, $dblink);
} else {
  die('Failed to connect to DB');
}
// get table list
$query = "show tables";
$result = mysql_query($query, $dblink);
// loop through table names
while (list($table) =  mysql_fetch_row($result)) {
  // get table description
  $query = "describe $table";
  $result2 = mysql_query($query, $dblink);
  // loop through table description fields
  while ($row = mysql_fetch_array($result2, MYSQL_ASSOC)) {
    // does this field match any in the array?
    if (in_array($row['Field'], $dbfields)) {
      echo "Found '".$row['Field']."' in table =&gt; $table&#92;n";
    }
  }
  mysql_free_result($result2);
}
mysql_free_result($result);
?&gt;</pre>
<p>3. And finally, this version searches for an array of fields across all tables and databases in MySQL.</p>
<pre class="code">&lt;?php
// variables
$dbfields = array('my_field1','my_field2','my_field3');
// connect to database
$dblink = mysql_connect('localhost', 'user', 'password');
if (!$dblink) {
  die('Failed to connect to DB');
}
// get databases list
$query = "show databases";
$result = mysql_query($query, $dblink);
// loop through table names
while (list($dbname) =  mysql_fetch_row($result)) {
  mysql_select_db($dbname);
  // get table list
  $query = "show tables";
  $result2 = mysql_query($query, $dblink);
  // loop through table names
  while (list($table) =  mysql_fetch_row($result2)) {
    // get table description
    $query = "describe $table";
    $result3 = mysql_query($query, $dblink);
    // loop through table description fields
    while ($row = mysql_fetch_array($result3, MYSQL_ASSOC)) {
      // does this field match what we're looking for?
      if (in_array($row['Field'], $dbfields)) {
        echo "Found '".$row['Field']."' in table =&gt; $table of database =&gt; $dbname&#92;n";
      }
    }
    mysql_free_result($result3);
  }
  mysql_free_result($result2);
}
mysql_free_result($result);
?&gt;</pre>
<p>Be sure to change the variables $dbname, $dbfields, and the mysql_connect options before using these scripts. You can run them by typing</p>
<pre class="code">php -f /path/filename</pre>
<p>on the command-line or from your web server. If run from the web, change the new line (&#92;n) to a HTML line break (&lt;br&gt;).</p>
<p><strong>Source Files:</strong> <a href="http://www.tonybhimani.com/files/2007/11/db-search-fields.zip">db-search-fields.zip</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D14&count=vertical&related=&text=Searching%20for%20fields%20in%20unknown%20MySQL%20tables' class='twitter-share-button' data-text='Searching for fields in unknown MySQL tables' data-url='http://www.tonybhimani.com/?p=14' data-counturl='http://www.tonybhimani.com/2007/11/02/searching-for-fields-in-unknown-mysql-tables/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2007/11/02/searching-for-fields-in-unknown-mysql-tables/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2007/11/02/searching-for-fields-in-unknown-mysql-tables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom SquirrelMail Login Pages for Virtual Hosts mini-HOWTO</title>
		<link>http://www.tonybhimani.com/2007/10/13/custom-squirrelmail-login-pages-for-virtual-hosts-mini-howto/</link>
		<comments>http://www.tonybhimani.com/2007/10/13/custom-squirrelmail-login-pages-for-virtual-hosts-mini-howto/#comments</comments>
		<pubDate>Sat, 13 Oct 2007 21:27:49 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/2007/10/13/custom-squirrelmail-login-pages-for-virtual-hosts-mini-howto/</guid>
		<description><![CDATA[Originally posted on August 8, 2006 9:57 PM This little tutorial will show you how to create custom SquirrelMail login pages for many virtual hosts, or in plain English, you have one copy of SquirrelMail and host many web sites &#8230; <a href="http://www.tonybhimani.com/2007/10/13/custom-squirrelmail-login-pages-for-virtual-hosts-mini-howto/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><font size="1">Originally posted on August 8, 2006 9:57 PM</font></p>
<p>This little tutorial will show you how to create custom SquirrelMail login pages for many virtual hosts, or in plain English, you have one copy of SquirrelMail and host many web sites on a single server. The purpose is to provide a unique login page for each web site domain without installing multiple copies of SquirrelMail. This is very useful if you are running a webhosting business or you host your friend&#8217;s web sites (like I do) and you don&#8217;t want SquirrelMail branded with your name but theirs. If that isn&#8217;t a good enough reason then how about the fact that the default SquirrelMail login page is boring and you should jazz it up with a custom web site theme.</p>
<p>The following screenshots are examples of some webmail login pages on my server. They all use the same copy of SquirrelMail (version 1.4.6) but with my tweaks each domain has a custom login page.</p>
<div style="width:450px;overflow:auto;white-space:nowrap;"><a href="http://www.tonybhimani.com/files/custom_sqmail/webmail_xenocafe.jpg" target="_blank"><img src="http://www.tonybhimani.com/files/custom_sqmail/thumb_webmail_xenocafe.jpg" border="0" alt="XenoCafe WebMail Login Page" /></a> <a href="http://www.tonybhimani.com/files/custom_sqmail/webmail_pineapplenow.jpg" target="_blank"><img src="http://www.tonybhimani.com/files/custom_sqmail/thumb_webmail_pineapplenow.jpg" border="0" alt="PineappleNOW! WebMail Login Page" /></a> <a href="http://www.tonybhimani.com/files/custom_sqmail/webmail_salina.jpg" target="_blank"><img src="http://www.tonybhimani.com/files/custom_sqmail/thumb_webmail_salina.jpg" border="0" alt="Salina's WebMail Login Page" /></a></div>
<p>This walkthrough makes the assumption that you have HTML, PHP, and some graphic design skills. To edit the SquirrelMail files you should know how to copy and paste and understand PHP, but to create your own custom templates you&#8217;ll need to know HTML, PHP, and graphics. You should also have root access to your server or have the ability to upload the modified SquirrelMail files to your server. The other obvious assumption is that you have SquirrelMail 1.4.6 installed and configured on your server (using another version of SquirrelMail may work, but I don&#8217;t know how much their code changed between revisions). If you don&#8217;t have SquirrelMail installed then you can check out my <a href="http://www.xenocafe.com/tutorials/linux/redhat/squirrelmail/installing_squirrelmail.php">SquirrelMail 1.4.6 tutorial on XenoCafe</a>. With that said, let&#8217;s get started.</p>
<p>1. You should already know where SquirrelMail is installed on your server and have it configured for each domain that accesses it. For this howto I&#8217;ll use the example directory location of <i>/www/webmail/html/</i> and the Apache virtual host file for webmail has a ServerAlias directive set for each domain (webmail.domain1.com, webmail.domain2.com, etc&#8230;). See my <a href="http://www.xenocafe.com/tutorials/linux/centos/apache_web_server/index.php">Apache Web Server tutorial</a> for more information on setting up virtual hosts.</p>
<p>2. The way I accomplished custom webmail login pages was to create a directory in /www/webmail/html/  called <i>hosts</i>. This directory is where all your templates are stored for each custom webmail login page and their associated images. Start by creating a host directory in your webmail root directory (for clarification, this is the same top level directory where the SquirrelMail &quot;src&quot; directory exists).</p>
<pre class="code">cd /www/webmail/html/
mkdir hosts</pre>
<p>3. There are three SquirrelMail PHP files that we&#8217;ll need to edit. The primary one is called <i>global.php</i> that resides in the functions directory. We&#8217;ll insert our custom function called <i>show_login_page</i> that makes custom logins possible. Let&#8217;s take a look at this login page function we&#8217;re creating.</p>
<pre class="code">function show_login_page( $errTitle=&quot;&quot;, $errString=&quot;&quot; ) {

  $httphost = strtolower( $_SERVER[&quot;HTTP_HOST&quot;] );

  switch ($httphost) {
    case &quot;webmail.domain1.com&quot;:
      require( SM_PATH . &quot;hosts/domain1/domain1.php&quot; );
      break;

    case &quot;domain2.com&quot;:
    case &quot;www.domain2.com&quot;:
    case &quot;webmail.domain2.com&quot;:
      include( SM_PATH . &quot;hosts/domain2/domain2.php&quot; );
      break;

    default:
      require( SM_PATH . &quot;hosts/default/default.php&quot; );
      break;
  }

}</pre>
<p>This function accepts two arguments ($errTitle and $errString). You&#8217;ll learn about these later when we modify one of the other SquirrelMail files. $httphost contains the server name of which web site the user is visiting. This is acquired from the global $_SERVER[&quot;HTTP_HOST&quot;] PHP variable. We use a switch/case structure to evaluate the HTTP HOST name. Depending on which host is visited the custom template for that host is shown for the login page. The host names are set up through Apache virtual hosts and DNS, in the case of the webmail subdomain. For www.domain.com and domain.com, it is assumed access to the site is coming from a /webmail directory. That can be established via symbolic links like so.</p>
<pre class="code">ln -s /www/webmail/html/ /www/domain/html/webmail</pre>
<p>So webmail can be accessed from http://webmail.domain.com or from http://www.domain.com/webmail since both paths map to the same physical space. You&#8217;ll see the PHP <i>include</i> function being used once a host is matched. The include function inserts your custom login page&#8217;s code as part of the HTML output to the web browser. The path to the PHP page is within the hosts directory we created earlier. For each host you want to serve custom logins you&#8217;ll create a subdirectory within hosts (I use the domain name without the ending .com, .net, etc). You&#8217;ll store your custom login page and image files within that domain directory. The last part of the switch/case is the default login page. This is shown when there are no HTTP HOST matches and thus displays the default SquirrelMail login page.</p>
<p>Open up the functions/global.php file in a text editor and add the show_login_page function to the end of the file right above the ending ?&gt; PHP tag. Customize the hosts for your server and save the file when you&#8217;re done.</p>
<p>4. Next we&#8217;ll edit the src/login.php page. We&#8217;re basically gonna strip out parts of the exsiting SquirrelMail code and replace it with a call to our show_login_page function. Make a backup copy of login.php and open the original in a text editor. Delete everything in the file and insert this code.</p>
<pre class="code">&lt;?php

/**
 * login.php -- simple login screen
 *
 * Copyright (c) 1999-2006 The SquirrelMail Project Team
 * Licensed under the GNU GPL. For full terms see the file COPYING.
 *
 * This a simple login screen. Some housekeeping is done to clean
 * cookies and find language.
 *
 * @version $Id: login.php,v 1.98.2.11 2006/02/03 22:27:55 jervfors Exp $
 * @package squirrelmail
 */

/**
 * Path for SquirrelMail required files.
 * @ignore
 */
define(&quot;SM_PATH&quot;,&quot;../&quot;);

/* SquirrelMail required files. */
require_once(SM_PATH . &quot;functions/strings.php&quot;);
require_once(SM_PATH . &quot;config/config.php&quot;);
require_once(SM_PATH . &quot;functions/i18n.php&quot;);
require_once(SM_PATH . &quot;functions/plugin.php&quot;);
require_once(SM_PATH . &quot;functions/constants.php&quot;);
require_once(SM_PATH . &quot;functions/page_header.php&quot;);
require_once(SM_PATH . &quot;functions/html.php&quot;);
require_once(SM_PATH . &quot;functions/global.php&quot;);
require_once(SM_PATH . &quot;functions/forms.php&quot;);

/**
 * $squirrelmail_language is set by a cookie when the user selects
 * language and logs out
 */
set_up_language($squirrelmail_language, TRUE, TRUE);

/**
 * Find out the base URI to set cookies.
 */
if (!function_exists(&quot;sqm_baseuri&quot;)){
    require_once(SM_PATH . &quot;functions/display_messages.php&quot;);
}
$base_uri = sqm_baseuri();

/*
 * In case the last session was not terminated properly, make sure
 * we get a new one.
 */

sqsession_destroy();

header(&quot;Pragma: no-cache&quot;);

do_hook(&quot;login_cookie&quot;);

$loginname_value = (sqGetGlobalVar(&quot;loginname&quot;, $loginname) ? htmlspecialchars($loginname) : &quot;&quot;);

if(sqgetGlobalVar(&quot;mailto&quot;, $mailto)) {
    $rcptaddress = &quot;&lt;input type=\&quot;hidden\&quot; name=\&quot;mailto\&quot; value=\&quot;$mailto\&quot; /&gt;\n&quot;;
} else {
    $rcptaddress = &quot;&quot;;
}

<strong>show_login_page();</strong>

?&gt;</pre>
<p>Save your changes when you&#8217;re done and then we&#8217;ll move on to the last file.</p>
<p>5. The last file we edit is functions/display_messages.php. This file contains functions to display any messages (error or otherwise) on the screen, such as login failures, IMAP failures, etc. We need to change the logout_error function so when a login failure occurs that our custom page is shown instead of the default SquirrelMail version. Replace the logout_error function with this code.</p>
<pre class="code">function logout_error( $errString, $errTitle = &quot;&quot; ) {

    list($junk, $errString, $errTitle) = do_hook(&quot;logout_error&quot;, $errString, $errTitle);

    if ( $errTitle == &quot;&quot; ) {
        $errTitle = $errString;
    }

   <strong>show_login_page($errTitle, $errString);</strong>

}</pre>
<p>If you were wondering about those arguments to our show_login_page function, now you can see what they&#8217;re for. SquirrelMail uses a hook to capture error messages on events. All we are doing is passing those error values to our login page function. When you intially go to the page, no errors are shown. If you login in and provide invalid information, our same login page will be shown again, but this time it&#8217;ll have the error messages within it. It&#8217;s similar to a postback but the URL is different. When we defined our login page function, we initialized those arguments with default null string values so no errors would show. When logout_error is called we pass the errors so they will be shown.</p>
<p>6. SquirrelMail&#8217;s PHP files are done so what&#8217;s left is to go over the steps of creating a custom login theme. I&#8217;ll now go over the parts you need to include when creating a template. Here is an example of the default template.</p>
<pre class="code">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;

&lt;html&gt;

&lt;head&gt;
&lt;meta name=&quot;robots&quot; content=&quot;noindex,nofollow&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../themes/css/verdana-10.css&quot; /&gt;
&lt;title&gt;Domain - Login<strong>&lt;?php echo (($errTitle != &quot;&quot; ) ? &quot; - &quot;.$errTitle : &quot;&quot;); ?&gt;</strong>&lt;/title&gt;&lt;script language=&quot;JavaScript&quot; type=&quot;text/javascript&quot;&gt;
&lt;!--
  function squirrelmail_loginpage_onload() {
    document.forms&#91;0&#93;.js_autodetect_results.value = &quot;<strong>&lt;?php echo SMPREF_JS_ON; ?&gt;</strong>&quot;;
    var textElements = 0;
    for (i = 0; i &lt; document.forms&#91;0&#93;.elements.length; i++) {
      if (document.forms&#91;0&#93;.elements&#91;i&#93;.type == &quot;text&quot; || document.forms&#91;0&#93;.elements&#91;i&#93;.type == &quot;password&quot; ) {
        textElements++;
        if (textElements == <strong>&lt;?php echo (isset($loginname) ? 2 : 1); ?&gt;</strong>) {
          document.forms&#91;0&#93;.elements&#91;i&#93;.focus();
          break;
        }
      }
    }
  }
// --&gt;
&lt;/script&gt;

&lt;style type=&quot;text/css&quot;&gt;
&lt;!--
  /* avoid stupid IE6 bug with frames and scrollbars */
  body {
      voice-family: &quot;\&quot;}\&quot;&quot;;
      voice-family: inherit;
      width: expression(document.documentElement.clientWidth - 30);
  }
--&gt;
&lt;/style&gt;

&lt;/head&gt;

&lt;body text=&quot;#000000&quot; bgcolor=&quot;#ffffff&quot; link=&quot;#0000cc&quot; vlink=&quot;#0000cc&quot; alink=&quot;#0000cc&quot; onLoad=&quot;squirrelmail_loginpage_onload();&quot;&gt;
&lt;form action=&quot;redirect.php&quot; method=&quot;post&quot;&gt;
&lt;table bgcolor=&quot;#ffffff&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;100%&quot;&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;&lt;center&gt;&lt;img src=&quot;http://webmail.domain.com/images/domain_logo.gif&quot; alt=&quot;Domain Logo&quot; width=&quot;180&quot; height=&quot;50&quot; /&gt;&lt;br /&gt;
&lt;small&gt;SquirrelMail version 1.4.6&lt;br /&gt;
  By the SquirrelMail Project Team&lt;br /&gt;&lt;/small&gt;
&lt;table bgcolor=&quot;#ffffff&quot; border=&quot;0&quot; width=&quot;350&quot;&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#dcdcdc&quot; align=&quot;center&quot;&gt;&lt;b&gt;Domain Login&lt;/b&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;#ffffff&quot; align=&quot;left&quot;&gt;
&lt;table bgcolor=&quot;#ffffff&quot; align=&quot;center&quot; border=&quot;0&quot; width=&quot;100%&quot;&gt;&lt;tr&gt;&lt;td align=&quot;right&quot; width=&quot;30%&quot;&gt;Name:&lt;/td&gt;
&lt;td align=&quot;left&quot; width=&quot;*&quot;&gt;&lt;input type=&quot;text&quot; name=&quot;login_username&quot; value=&quot;<strong>&lt;?php echo $loginname_value; ?&gt;</strong>&quot; /&gt;
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;&lt;td align=&quot;right&quot; width=&quot;30%&quot;&gt;Password:&lt;/td&gt;
&lt;td align=&quot;left&quot; width=&quot;*&quot;&gt;&lt;input type=&quot;password&quot; name=&quot;secretkey&quot; /&gt;
&lt;input type=&quot;hidden&quot; name=&quot;js_autodetect_results&quot; value=&quot;<strong>&lt;?php echo SMPREF_JS_OFF; ?&gt;</strong>&quot; /&gt;
<strong>&lt;?php echo $rcptaddress; ?&gt;</strong>
&lt;input type=&quot;hidden&quot; name=&quot;just_logged_in&quot; value=&quot;1&quot; /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;center&gt;&lt;input type=&quot;submit&quot; value=&quot;Login&quot; /&gt;
&lt;/center&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;br&gt;<strong>&lt;?php if ($errString != &quot;&quot; ) { echo &quot;&lt;center&gt;&lt;font size=\&quot;2\&quot; face=\&quot;Arial, Helvetica, sans-serif\&quot; color=\&quot;#ff0000\&quot;&gt;&lt;strong&gt;$errString&lt;/strong&gt;&lt;/font&gt;&lt;/center&gt;&quot;; } ?&gt;</strong>
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/form&gt;
&lt;/body&gt;&lt;/html&gt;</pre>
<p>The code pieces in bold should be included in your template. I won&#8217;t go in depth over the code, that&#8217;s why I said you should know HTML and PHP.</p>
<p>I&#8217;ve included a zip file containing the altered PHP files and a couple templates to give you examples to follow when creating your own custom login pages. Be sure to read the README file included in the zip.</p>
<p><strong>Source Files:</strong> <a href="http://www.tonybhimani.com/files/custom_sqmail/sqmail-custom-logins.zip">sqmail-custom-logins.zip</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D12&count=vertical&related=&text=Custom%20SquirrelMail%20Login%20Pages%20for%20Virtual%20Hosts%20mini-HOWTO' class='twitter-share-button' data-text='Custom SquirrelMail Login Pages for Virtual Hosts mini-HOWTO' data-url='http://www.tonybhimani.com/?p=12' data-counturl='http://www.tonybhimani.com/2007/10/13/custom-squirrelmail-login-pages-for-virtual-hosts-mini-howto/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2007/10/13/custom-squirrelmail-login-pages-for-virtual-hosts-mini-howto/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2007/10/13/custom-squirrelmail-login-pages-for-virtual-hosts-mini-howto/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

