Past Weeks New Content
Search CMX

Advanced Search

Latest Free Content
View All
Free Content
Accessibility

Introducing Recursive Functions in PHP

By: Rob Williams

Page 2 of 3

Set for printing

Previous Next

Exploring Recursive Functions

A recursive function increases the flexibility and adaptability of a function in the same way that a loop increases the flexibility and adaptability of a static statement or block of code. Let's take a look at just how this works.

A good scenario for a recursive function is when you're dealing with some kind of multi-level object, such as a multi-dimensional array or an XML structure.

A multi-level object is one that contains multiple instances of the same type of object. A two-dimensional array, for example, can be a thought of as a multi-level object because it is simply one array object nested within a second. Because both the outer and nested object are arrays they contain the same properties and methods, and we should potentially be able to use the same function to deal with each of them.

Let's start off with a nice simple one-dimensional array:

<?php

$myArray = array();
$myArray[0] = "jim";
$myArray[1] = "bob";
$myArray[2] = "fred";

Imagine that we want to pass this array and all of its data from PHP (server-side) to JavaScript (client-side). The easiest solution is to create a function that will simply loop over the array and write out each key/value pair as they would be declared in a JavaScript array:

//Convert a PHP array to a JavaScript one
function arrayToJS($array, $baseName) {
   //Write out the initial array definition
   echo ($baseName . " = new Array(); \r\n ");    

   //Reset the array loop pointer
   reset ($array);

   //Use list() and each() to loop over each key/value
   //pair of the array
   while (list($key, $value) = each($array)) {
      //Output the array key/value
      echo ($baseName . "[" . $key . "] = '" . $value . "'; \r\n ");
   }
}

//Call the function and pass it our array
arrayToJS($myArray, "myArray");

The function takes two parameters. The first, $array, is the actual array object that we want to output. The second, $baseName, is a string that represents the name of the current array. When you execute the above code block you'll end up with the following output:

myArray = new Array();
myArray[0] = 'jim';
myArray[1] = 'bob';
myArray[2] = 'fred';

Seems like pretty straightforward stuff, and since we just finished manually declaring our array a few minutes ago this really doesn't appear to be that exciting. Keep in mind though we can now pass any array to this function and it will loop over and output each of the items in the above format. Before we start dealing with recursion though let's make sure that our function is as versatile as possible. Our example array was simple in that it contained all numerical keys and all string values. In the real world though we may need to deal with associative arrays — arrays with strings as keys instead of integers — or a mixed array — both string and integer keys. Let's rework our function a bit to handle these situations:

//Convert a PHP array to a JavaScript one (rev. 2)
function arrayToJS2($array, $baseName) {
   //Write out the initial array definition
   echo ($baseName . " = new Array(); \r\n ");    

   //Reset the array loop pointer
   reset ($array);

   //Use list() and each() to loop over each key/value
   //pair of the array
   while (list($key, $value) = each($array)) {
      //Output the array key/value
      if (is_numeric($key)) {
         //A numeric key, so output as usual
         $outKey = "[" . $key . "]";
      } else {
         //A string key, so output as a string
         $outKey ="[
'" . $key . "']";
      }
      //Output the key declaration
      echo ($baseName . $outKey . " = ");

      //Now output the value       
      echo ("'" . $value . "'; \r\n ");

   }
}

Let's try it out by adding a few associative indices to our array:

$myArray2 = array();
$myArray2[0] = "jim";
$myArray2[1] = "bob";
$myArray2[2] = "fred";
$myArray2["index1"] = "some value";
$myArray2["index12"] = "index 12 value";

Let's call our updated function and see what happens:

//Call the function and pass it our array
arrayToJS2($myArray2, "myArray2");

The output is as follows:

myArray2 = new Array();
myArray2[0] = 'jim';
myArray2[1] = 'bob';
myArray2[2] = 'fred';
myArray2['index1'] = 'some value';
myArray2['index12'] = 'index 12 value';

That takes care of the keys but now we need to address the same problem with the values themselves, as we may not always have string values for each array entry. In addition to strings and numerical values though we'll also need to deal with two rather special possibilities: false and null. When you tell PHP to output false to null using an echo statement, nothing shows up. Since both of these values essentially mean "no value" to PHP, this makes perfect sense. However when passing an array to JavaScript we want to actually pass the values null or false, so we have to test for them explicitly and output the appropriate string values. In order to maintain the accuracy of our array we'll also want to add an explicitly test for true values, as PHP would normally output these as the integer 1 rather than the value true.

In PHP a null value is specified by the keyword NULL; in JavaScript a null value is specified by the keyword null (remember that both languages are case-sensitive).

//Convert a PHP array to a JavaScript one (rev. 3)
function arrayToJS3($array, $baseName) {
   //Write out the initial array definition
   echo ($baseName . " = new Array(); \r\n ");    

   //Reset the array loop pointer
   reset ($array);

   //Use list() and each() to loop over each key/value
   //pair of the array
   while (list($key, $value) = each($array)) {
      //Output the array key/value
      if (is_numeric($key)) {
         //A numeric key, so output as usual
         $outKey = "[" . $key . "]";
      } else {
         //A string key, so output as a string
         $outKey = "['" . $key . "']";
      }

      //Output the key declaration
      echo ($baseName . $outKey . " = ");

      //Now output the value
      if (is_string($value)) {
          //Output as a string, as we did before       
          echo ("'" . $value . "'; \r\n ");
      } else if ($value === false) {
          //Explicitly output false
          echo ("false; \r\n");
      } else if ($value === NULL) {
          //Explicitly output null
          echo ("null; \r\n");
      } else if ($value === true) {
          //Explicitly output true
          echo ("true; \r\n");
      } else {
          //Output the value directly otherwise
          echo ($value . "; \r\n");
      }

   }
}

Again we'll update our array and add some new types of values before calling the revised function:

$myArray3 = array();
$myArray3[0] = "jim";
$myArray3[1] = "bob";
$myArray3[2] = "fred";
$myArray3["index1"] = "some value";
$myArray3["index12"] = "index 12 value";
$myArray3["billy"] = NULL;
$myArray3["carlos"] = true;
$myArray3["sandy"] = 12;
$myArray3["petrov"] = false;

//Call the function and pass it our array
arrayToJS3($myArray3, "myArray3");

The new function now handles all the key and value possibilities properly:

myArray3 = new Array();
myArray3[0] = 'jim';
myArray3[1] = 'bob';
myArray3[2] = 'fred';
myArray3['index1'] = 'some value';
myArray3['index12'] = 'index 12 value';
myArray3['billy'] = null;
myArray3['carlos'] = true;
myArray3['sandy'] = 12;
myArray3['petrov'] = false;

Page 2 of 3 Previous 1 2 3 Next


download
Download Support Files


Keywords
Recursive function, array, multi-dimensional, JavaScript, generate XML