Recursion example using PHP

Recursion is a data structure by which a function is called several times till the condition which calls the function becomes true. I have seldom used it while coding but I would like to show you one particular instance where I used it to display a category level structure in a drop down.

First you need to create the table in mySQL. I have named the table as categories for the purpose of this example. You can name it anything you like.

CREATE TABLE `categories` (
`categories_id` int(11) NOT NULL auto_increment,
`categories_name` varchar(64) default NULL,
`parent_id` int(11) NOT NULL default '0',
PRIMARY KEY (`categories_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 

After that run the following INSERT queries which will create some sample data for this table

insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (65,'Top Level 1',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (66,'Top Level 2',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (67,'Sub Level 1-1',65);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (68,'Sub Level 2-1',66);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (69,'Sub Level 2-2',66);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (70,'Top Level 3',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (71,'Sub Level 3-1',70);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (72,'Top Level 4',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (73,'Top Level 5',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (74,'Sub Level 2-3',66);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (75,'Sub Level 3-1-1',71);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (76,'Sub Level 2-2-1',69);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (77,'Sub Level 2-2-1-1',76);

Finally you need to create a PHP script and enter the following bit of code to it.

<?php
// open the database connection

function get_rec($parent, $strCategory) {
$sql = "select * from categories where parent_id = ". $parent;
$rs1 = mysql_query($sql) or die(mysql_error());
$num1 = mysql_num_rows($rs1);

if ($num1 != 0) {
while ($data1 = mysql_fetch_object($rs1)) {
$strTempCategory = $strCategory ." -> " . $data1->categories_name;
echo "<option value=". $data1->categories_id .">". $strTempCategory ."</option>";
if (get_rec($data1->categories_id, $strTempCategory) == "") {
}
}
}
else {
return "";
}
}
?>
<select name="cboCategory" size="1">
<option value="0">Select</option>
<?php
$sql_cat="select * from categories where parent_id = 0 order by categories_name asc";
$result_cat = mysql_query($sql_cat) or die (mysql_error());
while ($data_cat = mysql_fetch_object($result_cat)) {
echo "<option value='".$data_cat->categories_id."'>".$data_cat->categories_name ."</option>";
echo get_rec($data_cat->categories_id, $data_cat->categories_name);
}
?>
</select>

Save the PHP file and run it. You should be able to view a drop down on the web page which will show the data you have just inserted in a tree view.

For ease I have provided the complete PHP code as well as the SQL file which you can then run and test on your computer.

Download the PHP Recursion Example by Adeel Sarfraz

Wish happy birthday to your customers from Zen Cart

Zen Cart by default requests a customer to enter his/her date of birth during registration. This is optional of course and can be removed from the Zen Cart admin panel. However one can make good use of this to regularly wish their customers a happy birthday thereby keeping in touch with them.

I have developed a script which will send a birthday wish to the customer when their birth date comes along. You will need to setup a cron job on your hosting server to run the script each day. You are also free to make changes to the script according to your needs.

Here is the Zen Cart birthday script and hope it helps some one.

Remember to copy it to your root folder and then setup a cron job to execute it daily.

How to parse large sized XML files using PHP XML Parser

I was recently provided a Google Base XML file by a client to load on one of his websites. The size of the XML file was over 20MB.  The format of the XML file was as follows:

<?xml version="1.0"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0"
xmlns:c="http://base.google.com/cns/1.0">
<channel>
<title>Company Name</title>
<description>Company Name Description</description>
<link>www.companyname.com</link>
<item>
<g:id>TEST</g:id>
<title>Test Product Name</title>
<link>http://www.companyname.com/test-page.html</link>
<description>Test Product Descripton</description>
<g:price>99.99</g:price>
<g:expiration_date>2012-01-16</g:expiration_date>
<g:shipping>
<g:country>US</g:country>
<g:service></g:service>
<g:price>0.00</g:price>
</g:shipping>
<g:condition>new</g:condition>
<c:google_product_category type="string">Product</c:google_product_category>
<g:gtin>TESTGTIN</g:gtin>
<g:mpn>TESTMPN</g:mpn>
<g:product_type>Product</g:product_type>
<g:image_link>http://www.companyname.com/images/test_product.jpg</g:image_link>
<g:brand>TestBrand</g:brand>
<g:shipping_weight>1 kg</g:shipping_weight>
</item>
<item>
..
</item>
<item>
..
</item>
.
.
</channel>
</rss>

The task as can be seen is not complex however I had a feeling that reading such big file would prove to be a hitch. I first tried to use simplexml_load_file to load the file and then loop through the array and then save it into the database. The script failed after taking a few seconds and the error message I received was unable to load the file. That was expected.

I then coded a script which used the PHP XML Parser to parse the XML file. I just needed to specify what action to perform for each tag and the code handled the rest. Please view following code which parses the XML given above and saves it into the database:

<?php

// Open the database connection

$arr = array();
$flagStop = 0;
$flag = '';

$parser = xml_parser_create();

function start($parser,$element_name,$element_attrs) {
global $flag;
global $flagStop;

if ($element_name == 'ITEM') {
$flagStop = 1;
}

if ($flagStop == 1) {
switch($element_name) {
case "TITLE":
$flag = 'title';
break;
case "LINK":
$flag = 'link';
break;
case "DESCRIPTION":
$flag = 'description';
break;
case "G:IMAGE_LINK":
$flag = 'image';
break;
case "G:BRAND":
$flag = 'brand';
break;
case "G:PRICE":
$flag = 'price';
break;
case "G:SHIPPING":
$flag = 'not';
break;
default:
$flag = '';
break;
}
}
}

function stop($parser,$element_name) {
global $arr;
global $flagStop;

switch($element_name) {
case "ITEM":

// Save the information into the database

// Clear the array fields before moving onto the next ITEM tag
$arr[0]['title'] = '';
$arr[0]['link'] = '';
$arr[0]['description'] = '';
$arr[0]['image'] = '';
$arr[0]['brand'] = '';
$arr[0]['price'] = '';

// Resetting the flag
$flagStop = 0;

break;
}
}

function char($parser,$data) {
global $arr;
global $flag;
global $flagStop;

if ( ($flagStop == 1) && ($arr[0][$flag] == '') ) {
$arr[0][$flag] = $data;
}
}

xml_set_element_handler($parser, "start", "stop");
xml_set_character_data_handler($parser, "char");

$fp = fopen("<path to xml file>","r");
$totdata = '';
while ( ($data = fread($fp,8192)) != '') {
xml_parse($parser, $data, feof($fp)) or die(sprintf("XML Error: %s at line %d", xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser)));
}

xml_parser_free($parser);

echo "done";
?>

XML Parser is a swell function to parse large XML files and the script above saved the data into the database within a couple of seconds.

Comments?

Steps to implement mySQL FULLTEXT

mySQL has full text indexing and searching support from version 5.0 onwards however there are some limitations. If you need to implement full text indexing then please review points given below:

1. mySQL allows full text indexing on MyISAM tables and not any other table type. If you try to create a full text index on an InnoDB table for example you will receive the following error message

Error Code : 1214
The used table type doesn't support FULLTEXT indexes

If you plan on using a table with InnoDB for full text indexing then you will first need to change it to MyISAM. Run the following statement to change the table to MyISAM

alter table &lt;table name&gt; engine = MyISAM;

2. You can only use the full text index on CHAR, VARCHAR and TEXT data type. If you try to create it on a column with a data type other than he ones specified then you will receive the following error message

Error Code : 1283
Column '&lt;column name&gt;' cannot be part of FULLTEXT index

3. You can specify the full text index in the CREATE table statement or ALTER table statement. Example of specifying full text index in the CREATE table statement is as follows

CREATE TABLE product
(
pid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
pname VARCHAR(200),
pcode VARCHAR(20),
pdesc TEXT,
FULLTEXT (pname,pdesc)
) ENGINE=MyISAM;

Example of specifying full text index in the ALTER table statement is as follows

ALTER TABLE product ADD FULLTEXT(pname, pdesc);

After completing the above steps you can test whether the full text index is working or not by inserting some data into the table. Please note you should enter at least 10 or more records and the same data should not be copied in each record otherwise it will not work.

The following statement will try to return result using the MATCH()..AGAINST syntax which is how full text index searches through the records in the table.

SELECT * from product where MATCH(pname, pdesc) AGAINST('test');

Please note that full text indexing will only run on the columns in which the full text index has been created. If you try to run the above statement on a non full text index column then it will not run.

If we take the above table for example we have not created full text index on the “pcode” field. If we run our SELECT statement as

SELECT * from product where MATCH(pname, pcode) AGAINST('test');

we will receive the following error

Error Code : 1191
Can't find FULLTEXT index matching the column list

Hope the above helped. Let me know if you have any questions/comments.

How to parse an XML file in PHP using XML parser

PHP offers a new and fast way to parse XML files. This approach makes it easier to parse very large XML files in a couple of seconds.

Here goes the code to parse a sample XML file. The XML in that file is also given below

<!-- The XML to be parsed with the code below -->

<person>
<name>Adeel Sarfraz</name>
<phone>123456790</phone>
<address>Karachi</address>
</person>


<?php

$parser = xml_parser_create();

// This function is called whenever a start tag is encountered 
function start($parser,$element_name,$element_attrs) {
 switch($element_name) {
    case "NAME":
           //Add code here
	    break; 
    case "PHONE":
            //Add code here
	    break; 
    case "ADDRESS":
            //Add code here
	    break; 
    default:
           //Add code here
	   break;
   }
}

// This function is called whenever an end tag is encountered
function stop($parser,$element_name) {
}

// This function is called when the data within the tags is to be read
function char($parser,$data) {
  	print $data;
}
xml_set_element_handler($parser,"start","stop");
xml_set_character_data_handler($parser,"char");
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,true);
$fp=fopen("example.xml","r");
while ($data=fread($fp,4096))  {
  xml_parse($parser,$data,feof($fp)) or die (sprintf("XML Error: %s at line %d", xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser)));
}
xml_parser_free($parser);
?>

Hope the above helps.

How to read a zip file in PHP

If you want to read all the files a zip file contains and extract those files to a location on your computer then you can do the following.

First of all make sure that the zip package is included in your PHP distribution. I use Windows so Windows users can just uncomment the entry for php_zip.dll in php.ini and restart the IIS service to start using it.

<?php
$zip = zip_open("e:/myfiles/example.zip");
if ($zip) {
  while ($zip_entry = zip_read($zip)) {
    $fp = fopen("unzipped/".zip_entry_name($zip_entry), "w");
    if (zip_entry_open($zip, $zip_entry, "r")) {
      $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
      fwrite($fp,"$buf");
      zip_entry_close($zip_entry);
      fclose($fp);
    }
  }
  zip_close($zip);
}
else {
	print "error no. = ". $zip;
}
?>

As you can see from the above, we provided the exact location of the zip file and then read and copied each file to the unzipped folder.

Hope the above helps

How to download a file using CURL in PHP

Downloading a file is easy but what if you had to download a file through your page and save it on our machine.

Well here goes. We use our friendly CURL library in PHP for this. You can use the following code to download and save the file on your machine

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/example_file.zip");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$str = curl_exec($ch);
curl_close($ch);
$f = fopen("my_example_file.zip","w");
fwrite($f,$str);
fclose($f);
?>

That’s all there is to it. You can save the file by any name and start using it.

Hope the above helps

How to use AJAX to check user already exists or not in PHP

AJAX is a wonderful technology that provides the visitor with a “no refresh” experience on the web. With the advent and popularity of Web 2.0 this technology is making progress by leaps and bounds.

If you would like to verify whether a user is registered on your website or not then you can use the following code to implement that functionality.

As AJAX uses JavaScript we will be using the XMLHTTP object.

<script><!--
/*
Due to browser compatibility issues following function instantiates the right object with respect to the browser
*/

function getHTTPObject() {
var xmlhttp;

if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}
else if (window.ActiveXObject){
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
if (!xmlhttp){
xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");
}
}
return xmlhttp;
}

// Instantiating the object
var http = getHTTPObject();
// --></script>

Next we will define the function which actually gets called to verify the user from the web page

<script><!--
function getMemberEmail() {
/*
Place validation code here to verify whether the input is in the correct format or not.  If it is not in the correct format then prompt user other wise start checking the user.
*/

sId = document.frmCheck.txtEmail.value;
document.getElementById('spnMessage').innerHTML = "Please wait...";
var url = "chk_user_email.php?e=";

// Note the http is a global variable as you can see from the above code

http.open("GET", url + escape(sId), true);
http.onreadystatechange = handleResponse;
http.send(null);
}
// --></script>

Now we have to write the code which handles the response from the chk_user_email.php file.

<script><!--

function handleResponse() {
/*
We have to check the response status and whether the operation has completed or  not. 4 means completed and 200 means that response is OK.
*/

if (http.readyState == 4) {
if(http.status==200) {
var results=http.responseText;
document.getElementById('spnMessage').innerHTML = results;
}
}
}
// --></script>

The complete code as it would appear on the page for the above example is below:

<script><!--
function getHTTPObject() {
var xmlhttp;

if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}
else if (window.ActiveXObject){
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
if (!xmlhttp){
xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");
}
}
return xmlhttp;
}

var http = getHTTPObject();

function getMemberEmail() {

sId = document.frmCheck.txtEmail.value;
document.getElementById('spnMessage').innerHTML = "Please wait...";
var url = "chk_user_email.php?e=";

http.open("GET", url + escape(sId), true);
http.onreadystatechange = handleResponse;
http.send(null);
}

function handleResponse() {

if (http.readyState == 4) {
if(http.status==200) {
var results=http.responseText;
document.getElementById('spnMessage').innerHTML = results;
}
}
}
// --></script>
<form> <input name="txtEmail" type="text" />
<span id="spnMessage" type="text" /> </span>

</form>

Problems while installing Drupal 6.x

If you are facing problem on step 3 of Drupal installation where you enter your database name, username and password and after clicking Continue button the page just refreshes blanking out everything then the following fix applies to you if are on Windows 2003.

This problem has also been mentioned on Drupal website

1. Go to the sites/default folder.
2. Create an empty file by the name of settings.php in that folder.
3. Right click on settings.php and click on Security tab.
4. Search and add the IUSR_ account.
5. Give it read and write permissions on the settings.php file and proceed normally.

The installation will complete without a hitch.