Posted on May 14, 2008 in PHP by Elliott BrueggemanNo Comments »

Last November, I published a post on creating a simple PHP Captcha. Some readers noted that I actually used a more advanced captcha for my own site’s discussion pages, and asked for the source code. I’ve actually gone a step further and improved my own captcha by adding more background noise, decreasing the likelihood that a bot would be able to break it. Though harder for a bot to read, I changed the font and made it easier for a human to read.

As noted before, Captchas are images that are meant to tell the difference between a person and a computer, be presenting an image with text in it, and asking the user to enter the text and submit it with the form. Captchas are used to reduce spam on publicly accessible message boards and comment lists.

Below is the new and improved PHP captcha script and example implementation.

Requirements

To use this script, you will need PHP enabled web server with the Image (GD) extension enabled. If you are not sure, check with your hosting company. Most major hosting companies, like GoDaddy.com provide this by default.

Setup

On the page where your users are submitting content, like a post or a comment, you want to display the captcha and an input box for the user to enter the text displayed in the captcha. To use the PHP script below to you need to include it as an image on the page you want it to display - save the script as something like “advanced_captcha_script.php” and use the following html to display it on the page.

Include this html code inside your form tag:

<!-- display the script as an image --> 
<img src="advanced_captcha_script.php" /> 
<!-- an input box to input the captcha text -->  
<input name="captcha_input" id="captcha_input" />

The Script

<?php
session_start(); //MUST START SESSION 
$string_length = 6; //NUMBER OF CHARS TO DISPLAY 
$large_letters = array('m','w');
$rand_string = ''; 
 
for ($i=0; $i<$string_length; $i++) { 
  //PICK A RANDOM LOWERCASE LETTER USING ASCII CODE 
  $rand_string .= chr(rand(97,122)); 
}
 
//IMAGE VARIABLES 
$width = 100; 
$height = 36; 
 
//INIT IMAGE 
$img = imagecreatetruecolor($width, $height); 
 
//ALLOCATE COLORS 
$black = imagecolorallocate($img, 0, 0, 0); 
$gray = imagecolorallocate($img, 110, 110, 110); 
$medgray = imagecolorallocate($img, 180, 180, 180); 
$lightgray = imagecolorallocate($img, 220, 220, 220); 
//FILL BACKGROUND
imagefilledrectangle($img, 0, 0, $width, $height, $lightgray); 
 
//ADD NOISE - DRAW background squares
$square_count = 6;
for ($i = 0; $i < 10; $i++) {
  $cx = (int)rand(0, $width/2);
  $cy = (int)rand(0, $height);
  $h  = $cy + (int)rand(0, $height/5);
  $w  = $cx + (int)rand($width/3, $width);
  imagefilledrectangle($img, $cx, $cy, $w, $h, $medgray); 
}
 
//ADD NOISE - DRAW ELLIPSES
$ellipse_count = 5;
for ($i = 0; $i < $ellipse_count; $i++) {
  $cx = (int)rand(-1*($width/2), $width + ($width/2));
  $cy = (int)rand(-1*($height/2), $height + ($height/2));
  $h  = (int)rand($height/2, 2*$height);
  $w  = (int)rand($width/2, 2*$width);
  imageellipse($img, $cx, $cy, $w, $h, $gray);
}
 
//REPLACE THIS WITH THE FONT YOU UPLOAD 
$font = 'Tuffy.ttf'; 
$font_size = 18; 
 
//CALC APPROX LOCATION - CUSTOMIZED FOR ABOVE FONT 
$y_value = ($height/2) + ($font_size/2); 
$x_value = 0;
 
//DRAW STRING USING TRUE TYPE FUNCTION 
 
for ($i = 0; $i < $string_length; $i++) {
  $chr = substr($rand_string, $i, 1);
  $x_value += 3 * ($font_size/5); 
  imagettftext($img, $font_size, 0, $x_value, $y_value, $black, $font, $chr); 
  //check to see if larger than normal letters, if so add more horiz space
  if (in_array($chr, $large_letters)) {
    $x_value += 4;
  }
}
 
$_SESSION['encoded_captcha'] = md5($rand_string . 'my_secret_key'); 
 
//OUTPUT IMAGE HEADER AND SEND TO BROWSER 
header("Content-Type: image/png"); 
imagepng($img); 
?>

Here’s an example of what the captcha looks like (refresh the page to generate a new captcha):

Script Notes

We are using a font called “Tuffy.ttf” that is in the public domain in this script. You will need to download this font and upload to the same directory as the captcha script. You can download this font from the homepage of its creator or directly from my site.

Checking The Result

After the user has submitted the form, we still have to validate their captcha text entry. Without validation, our captcha security is useless. The general flow of things after the form has been submitted is:

  1. Compare the user entry to the captcha text
  2. If they are the same, enter the user’s content into your database
  3. If they are different, display an error message to the user.

If you examine the PHP script above you will notice that we are storing the generated captcha as a session variable concatenated with a secret key. If we use the PHP function session_start() on the next page after the form has been submitted, we will be able to access that stored session variable. We do not store it as plain text, or else a spam bot might be able to access the stored text in the session variable and then type the correct captcha text in the input box, bypassing our security. Instead, we store it a an md5() hash, which is a one-way encryption method. All md5() encrypted strings by their nature cannot be decrypted, so to validate the user entry we need to md5() encrypt the user’s input, concatenate in the secret key and compare it to the already encrypted session variable. Below is some PHP code that shows how we could validate the captcha:

<?php
session_start(); 
$user_content=trim($_POST['user_content']); 
$user_captcha_input=trim($_POST['user_captcha_input']); 
if (isset($_SESSION['encoded_captcha'])) { 
  if ($_SESSION['encoded_captcha'] == md5($user_captcha_input . 'my_secret_key')) { 
    //..THE USER IS NOT A BOT, STORE THEIR INPUT
  } 
  else { 
    //THE USER ENTERED THE WRONG CAPTCHA, 
    //DISPLAY AN ERROR MESSAGE AND 
    //DO NOT STORE THEIR INPUT
  } 
} 
?>
Posted on April 9, 2008 in AJAX, Javascript, PHP by Elliott BrueggemanNo Comments »

Background

Previously I posted my PHP AJAX Framework so I thought I would give an example of its use. In this case, you probably have seen this example before - using AJAX and PHP to check if a username is available during some kind of web-based user registration. The goal is to alert the user if a username is taken before they have submitted the form, allowing them to enter another username quickly. This feat can be easily accomplished with the PHP AJAX Framework.

Setup

You are going to need to copy the contents of the PHP AJAX Framework into a JavaScript file. In this example I have put the contents into the “php_ajax_framework.js” file. You are also going to need to write a PHP script that will be called in the AJAX sequence of events, notifying the user whether the username is available or not.

Below is an example PHP Script, which has the filename “username_exists.php” and will need to be in the same directory as the page that is triggering the AJAX.

PHP Username Available Script

This script is requested by our AJAX helper function and sent the text in our username input box. In the script is a call to a function usernameExists() which returns true or false, depending on whether the username exists. In a real web site or application, this would query our database to see if the username existed. In this example, for ease of understanding, we just check to see if the username is in a defined array of usernames.

<?php 
$username = trim($_GET['username']);
 
if (usernameExists($username)) {
  echo '<span style="color:red";>Username Taken</span>';
}
else {
  echo '<span style="color:green;">Username Available</span>';
}
 
function usernameExists($input) {
  // in production use we would look up the username in 
  // our database, but for this example, we'll just check
  // to see if its in an array of preset usernames.
  $name_array =  array ('steve', 'jon', 'george', 'admin');
 
  if (in_array($input, $name_array)) {
    return true;
  }
  else {
    return false;
  }
}
?>

Username Check Page

Our example username page is very basic - you should integrate this into your existing site. The important parts are the JavaScript functions and the input box, which uses the onKeyUp() JavaScript event to call a function which them triggers the AJAX chain of events. More information on setting up the PHP AJAX Framework can be found on its post page, but the basic idea is that you create an _init function that specifies which PHP script to execute and what variables to send it (in this case, the value of the user input box.) You also create a _results function which will be given the results of your PHP Script and then do something with them (in this case, display a notice to the user whether the name is available.) The _init and _results functions are given function names prepended to these terms which are the same (in the below case, we prepend “check_username” to both) and then they are triggered by calling our PHP AJAX Framework function ajaxHelper() with the name we prepended.

<html>
<head>
<script type="text/javascript" src="php_ajax_framework.js"></script>
<script type="text/javascript">
function check_username_init() {
  var user_field = document.getElementById('user');
  return 'username_exists.php?username=' + user_field.value;
}
function check_username_ajax(results) {
  var results_div = document.getElementById('results_div');
  results_div.innerHTML = results;
}
function check_username() {
  var user_field = document.getElementById('user');
  if (user_field.value.length > 0) {
    //call our AJAX function in the PHP AJAX Framework
    ajaxHelper('check_username');
  }
  else {
    //clear results field 
    var results_div = document.getElementById('results_div');
    results_div.innerHTML = '';
  }
}
</script>
</head>
<body>
Username: 
<input name="user" id="user" size="20" onKeyUp="check_username();">
<div id="results_div"></div>
</body>
</html>

Here is an live example of the above scripts all working together. Remember that we are just checking against an array of names. Try typing in one of the names in the array to see what happens when a particular username is taken (steve, jon, george, admin.)

Conclusion

Implementing AJAX is easy and just requires putting all the pieces together. Give AJAX and shot and implement the PHP AJAX Framework on your site for simple AJAX tasks.

Posted on March 20, 2008 in PHP by Elliott BrueggemanNo Comments »

Again?

Awhile ago I posted a PHP Execution class article for timing various PHP elements. Since then, a few developers have requested that I include the ability to start and start the timer, so you can be more precise with elements that you want to time and elements that you don’t. I decided to code this class in full PHP 5+ object-oriented structure. In addition to increased functionality, sticking to this style of programming supports PHP as an enterprise level language, and helps its standing among other more weathered and commercially used languages.

The Timer Script

This script returns the time in ms (milliseconds) rounded to the nearest ms when used in a php script or web page.

<?php
class Timer{
 
  private $start_time;
  private $end_time;
  private $accumulated_time;
 
  //Public constructor
  public function __construct() {
    $this->start_time = NULL;
    $this->end_time = NULL;
    $this->accumulated_time = 0;
  }
 
  //Public functions
  public function start() {
    if ($this->is_stopped()) {
      //add time so far to accumulated time
      //reset end time and set start time
      $this->accumulated_time += ($this->end_time - $this->start_time); 
      $this->start_time = $this->get_timestamp();
      $this->end_time = NULL;
    }
    else if (!$this->is_started()) {
      $this->start_time = $this->get_timestamp();
    }
  }
 
  public function stop() {
    if ($this->is_started()) {
      $this->end_time = $this->get_timestamp();
    }
  }
 
  public function reset() {
    $this->__construct(); 
  }
 
  public function retrieve() {
    $this->stop();
    return round($this->accumulated_time + ($this->end_time - $this->start_time));
  } 
 
  //Private functions
  private function is_started() {
    //if start is numeric but end is null, we are started
     if(is_numeric($this->start_time) && is_null($this->end_time)) {
      return true;
    }
    return false;
  }
 
  private function is_stopped() {
    //if end time is numeric, we have a stopped timer
    if(is_numeric($this->end_time)) {
      return true;
    }
    return false;
  }
 
  private function get_timestamp() {	
    //retrieve seconds and microseconds (one millionth of a second)
	//multiply by 1000 to get milliseconds
    $timeofday = gettimeofday();
    return 1000*($timeofday['sec'] + ($timeofday['usec'] / 1000000));
  } 
}
?>

Usage

Using this script is relatively easy as you can probably see from the function names. The 4 main functions in addition to the constructor are start(), stop(), retrieve(), and reset(). Here is an example of usage of this class:

<?php
//instantiate the timer object
$timer = new Timer();
 
//start the timer
$timer->start();
 
//... do something worth timing
 
for($i=0;$i<10000000;$i++){}
 
//stop the timer
$timer->stop();
 
//... do something NOT worth timing
 
//start the timer again
$timer->start();
 
//... do something worth timing
 
//stop the timer
$timer->stop();
 
//print the time accumulated
echo $timer->retrieve();
Posted on March 9, 2008 in PHP by Elliott BrueggemanNo Comments »

MY Common PHP Includes

When I start a new application or website, I always start with the same framework of files. I have a series of include files that I include as necessary on pages (scripts) on the site. Stuff like site navigation, database connection, and core functions are some of the includes I use.

My functions include has all the functions that I’m confident are going to be used frequently enough on the site to warrant their inclusion (and subsequent declaration) in every script in the site. While most of the functions vary from site, because they relate to a specific feature or concept that the site incorporates, there are two functions that I always include.

My Get and Post Functions

All my sites and applications are dynamic, which means they receive input from the user using either the GET or POST method. If you incorporate forms into your site, you’re probably familiar with GET and POST and the differences between the two. One thing I noticed after some time programming was that handling data through GET and POST was done frequently and could be easily compartmentalized in two simple helper functions.

Below is my implementation of these functions:

<?php
function getData($var, $maxLength=99999) {
  $value = NULL;
  if (isset($_GET[$var])) {
    $value = trim(htmlentities($_GET[$var], ENT_QUOTES));
    if (strlen($value) > $maxLength) {
      $value = substr($value, 0, $maxLength);
    }
  }
  return $value;
}
 
function postData($var, $maxLength=99999) {
  $value = NULL;
  if (isset($_POST[$var])) {
    $value = trim(htmlentities($_POST[$var], ENT_QUOTES));
    if (strlen($value)>$maxLength) {
      $value = substr($value, 0, $maxLength);
    }
  }
  return $value;
}
?>

These functions act as helper functions to retrieve the value that was sent to the script and available to PHP’s global $_GET and $_POST arrays. They also implement a few simple extra features. When calling either of these two functions, you can also supply a $maxLength parameter, which would be the maximum expected length of that variable. If anything is longer, then someone may be trying to take advantage of your website by sending data not in the way you intended. If the variable is longer than expected, the function still allows it, though it trims it to the length you are expecting. This can be helpful if you are inserting values into a database that has limits on the number of characters in a field. In addition, the function also puts the value through PHP’s htmlentities() function which will encode each character into their html equivalent, which I almost always need. This can also disarm any injected code that a malicious user may be sending to your script. Lastly, the function returns NULL when the expected variable has not been passed. This allows easy error handling when calling this function. Here is an example of doing error handling when retrieving a function:

<?php
//Attempt to retrieve the value
$username = getData('username');
 
if ($username == false) {
  //This value does not exist, do something to handle this situation
}
else {
  echo 'Welcome ' . $username . '!';
}
?>
Posted on February 22, 2008 in PHP by Elliott BrueggemanNo Comments »

Why Change Your php.ini file?

Both PHP for Windows and Linux ship with pre-configured .ini files with settings common to most PHP setups. The Windows installer (which I recommend if you’re using Windows for a development machine, or even have your live site on Windows) goes a step further and also will add lines to your php.ini file through a simple GUI that enable both your web server and desired PHP extensions.

Most people will leave these the rest of the .ini file unchanged, but there are some changes that can make life much easier. Below are my recommendations for changes to the default php.ini file. The line number is next to each changed line, and is accurate for Windows PHP 5.25 distributions.

Short Tags

Short tags are PHP tags like this <? ?> and were very common a few years ago and taught to me in my Web Technologies class at NYU. You should generally allow these, especially if you are working with inherited code. This setting was the cause of over an hour of frustration when I moved an application to a new server and it suddenly wouldn’t load.

131 Orig: short_open_tag = Off
131 Mine: short_open_tag = On

Maximum Execution Time

For some reason this is only set to 30 seconds by default. Some heavy hitting scripts that write to disk, retrieve information from the web, or other things where waiting is involved, can run longer than 30 seconds. The cron.php script for a Drupal site that I work on customarily runs for over a minute.

303 Orig: max_execution_time = 30
303 Mine: max_execution_time = 240

Memory Limit

I’ve found that many high traffic sites will run out of memory when this is set to 128m. This setting is per script, so if 10 scripts are executing at once, you can easily max out your memory. If you’re using more than 64m for a certain script, you need to optimize your code, or split up functionality into more than one script.

306 Orig: memory_limit = 128M
306 Mine: memory_limit = 64M

Display Errors

I would recommend the following change only for development machines, not live severs. When set to “On”, PHP will output the error directly to the screen in addition to your error log (if enabled.) This can be very useful for debugging.

372 Orig: display_errors = Off
372 Mine: display_errors = On

Error Log

This is another setting I would only recommend doing on a development machine, not a live server. When uncommented and supplied with a valid filename, this will output all errors and warnings to an error log file in the base directory of your server root. Again, very helpful for debugging and development.

428 Orig: ;error_log = filename
428 Mine: error_log = errors.txt

Upload Filesize

On the chance that you are uploading files in your scripts, this is a handy change to make. I’ve found that 4M is a much friendlier setting, especially with digital picture uploads, which are regularly more than 2M.

597 Orig: upload_max_filesize = 2M
597 Mine: upload_max_filesize = 4M

Session Name

When using sessions, PHP will create cookies to store information and the below setting will be the name of the cookie. When in doubt, give a malicious user as little information as possible, and this setting exposes the fact that you are using PHP sessions. Pick a more general name.

1010 Orig: session.name = PHPSESSID
1010 Mine: session.name = XYZ

Don’t forget to restart your web server after making any of the above changes.

Posted on February 13, 2008 in PHP by Elliott BrueggemanNo Comments »

Debugging Can Be Difficult

Debugging a PHP script can be a difficult task, especially when code is located over many files. Trying to debug a complicated CMS like Drupal, where function calls are not always explicit and may be implemented as hooks, can be an outright nightmare.

Magic Constants

Luckily, PHP has a few not so well known magic constants that can greatly aid developers. I think the most useful of all is the __FUNCTION__ constant. This function will return the name of the function that it is called in. To use effectively add either of the following two statements to the first line of each function in the file(s) of code you are executing:

echo('Current Function: ' . __FUNCTION__);
error_log('Current Function: ' . __FUNCTION__);

After you execute your script or page, you will get a chronologically ordered function by function run-down of what has been executed. Note that you must choose either echo or error_log ouput, where appropriate. Echo will output directly to the screen, but may not work as expected in some circumstances where your output is buffered, or echo’s happen amid hidden page elements. The most reliable way is to use error_log() to output to your server’s PHP error log. Unfortunately, this log may not be viewable in some hosted site situations where you have limited access to PHP’s configuration.

Other magic constants are also available for debugging object oriented PHP code including __CLASS__ and __METHOD__. The constant __FUNCTION__ will return the same method information when a function is inside of a class, so you can just use __FUNCTION__ instead of __METHOD__.

The last two magic constants are __FILE__ and __LINE__ which do pretty much exactly what you think they would do. For more information on PHP’s magic constants, check out this PHP manual page.

Posted on February 6, 2008 in PHP, SEO, Search Engines by Elliott BrueggemanNo Comments »

Background

Displaying your email address on your site as text has always been risky. Why? Long ago, spammers created bots that searched the web for email address (by looking for something in the xxxx@yyyy.com format) and then spammed them to oblivion. As a result, web developers often use little tricks like writing out the @ symbol (xxxx at yyyy.com) or inserting a little image of an @ symbol between the username and the domain to prevent a spambot from reading the address. Another problem arises when a user wants to display their name on a website, but doesn’t want a search engine to be able to read the name and then associate it with the site in the engine’s search results. PHP allows a solution for both of these scenarios that is versatile and easy to implement.

Dynamically Generated Images

One of the many powers of PHP is its ability to generate images dynamically, meaning on the fly, when a page is requested. PHP uses the GD extension to create gifs, pngs, jpegs, etc and manipulate them with a small set of predefined functions. The idea here is to display a dynamically generated image of your name or email address that is invisible to search engines, because it is an image and not text.

Why not use Photoshop or another similar program to make an image of a name for one time use? Well you could do this, but what about a situation where data is displayed dynamically, like on a blogging site, where new users sign without the intervention of a web developer? You wouldn’t want to have to manually create an image each time this happened. Dynamically created images in PHP are the solution.

Inserting Dynamic Images Into Your Site

PHP scripts that generate images can only generate images. They cannot have html or other PHP elements echo’d out to the screen. In order to get them to work, you have to isolate the script that generates the image from the script (or page) that displays the image. Let’s say we want to display our email address on our page home.php, and we have a script that generates the image of our email address in email_address.php. To accomplish this, we would need to have an <img> tag on home.php that pointed to email_address.php. Here is what the tag on home.php could look like:

<img src="email_address.php" alt="" />

Note that we are substituting our image generating script into the spot where we would normally have the name of an image, but we keep the “.php” extension.

The Script

To use this script, copy the below code into a file and save it as disguise_text.php and upload it to your server. Then, follow the instructions in the “Implementing the Script” section.

<?php
//get name from passed arg
$text= base64_decode(urldecode($_GET[text]));
//width per char is based on experimentation - yours may be different
$width_per_char = 6.25;
//image height and width
$length = $width_per_char * strlen($text);
$height = 15;
//create image
$img = imagecreatetruecolor($length, $height);
//define used colors
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
//set the background to white
imagefilledrectangle($img, 0, 0, $length, $height, $white);
//write name in black
imagestring($img, 2, 2, 2, $text, $black);
//output header and generate image
header("Content-Type: image/png");
imagepng($img);
?>

Implementing the Script

After you have uploaded the above script to your server as disguise_text.php, insert the following image tag into the page you want to display the image (paste onto one line - it is separated due to column width):

<img src="http://www.ebrueggeman.com/blog/wp-admin/disguise_text.php?
text=<?php echo urlencode(base64_encode('jwaters@apple.com')); ?>" 
alt="email address" />

Here is what the above code actually generates: email address

Notes

Without getting overly complicated, the example we have uses size 2 of PHP’s default font to display the text. The auto image width feature of the script is based on the width of this particular font with this size. If you are going to change the font, make sure to change the $width_per_char and $height variables to accurately represent your font. Also, as shown above, the script only works for pages with white backgrounds. To display the image with a different color background, change the RGB values of the “$white = imagecolorallocate($img, 255, 255, 255);” code to match your background.

Conclusion

Generating images in PHP is easy if you know the basics, and hiding text from search engines can be a useful tool. Check out this related article on Image Optimization in PHP

Posted on January 16, 2008 in AJAX, Javascript, PHP by Elliott BrueggemanNo Comments »

Background

In the previous article, we examined the PHP AJAX Framework, which is an easy way of combining AJAX with PHP. In order to trigger our AJAX, we relied on user interaction. However, what happens when you want your AJAX call to execute at a certain time interval? The solution is relatively easy and involves the JavaScript function setInterval().

AJAX Timer Code

Below is a snippet of JavaScript code that will work with my PHP AJAX Framework to call the sales_calculate hook every 5 seconds:

<script language="JavaScript">
var time = 5; //time in seconds
var interval = time * 1000;
var timer = setInterval("ajaxHelper('sales_calculate')", interval);
</script>

The above code will execute our ajaxHelper() function with the sales_calculate hook that will in turn call sales_calculate_setup() and then sales_calculate_ajax() every 5 seconds.

Note that this code is meant to accompany my PHP Framework, and will not trigger an AJAX call unless properly configured. Please refer to the prior AJAX Framework article for more information.

Posted on January 9, 2008 in AJAX, Javascript, PHP by Elliott Brueggeman1 Comment »

Background

One of the most useful new web technologies is AJAX, or Asynchronous JavaScript and XML. In short, AJAX allows you to send and receive server requests without a user having to reload the page. This allows pages to be more dynamic without interrupting the user experience.

AJAX is fairly easy to implement and use effectively, but finding a comprehensive start to finish tutorial for integration with PHP is not quite as easy. To make the task easier, I have put together a simple PHP AJAX framework that is flexible and easy to implement.

AJAX Workflow

The inner workings of AJAX are a mystery for some so I will go over the basics of how our framework will work with PHP.

  1. Using JavaScript, a call to your AJAX function is triggered by clicking somewhere, entering something, etc.
  2. Your AJAX function creates an XMLHttpRequest object.
  3. When ready, the object requests information from your server in the form of a URL, possibly with arguments such as myscript.php?name=jon&year=2007, etc.
  4. The server executes the PHP script and sends the result by echo[ing] it out.
  5. Instead of printing it to the screen, that information is instead returned to you as a JavaScript variable.
  6. Using JavaScript, that information can now be dynamically inserted in the page by using the innerHTML property or by assigning the result to the value of a form element.
  7. Rinse and Repeat… The value of AJAX is that you can repeat this process infinitely without having the user have to navigate away from the page!

PHP AJAX Framework

The PHP AJAX Framework shown below is structured into three parts. The part that stays the same every time is the JavaScript ajaxHelper() function. This is the core of our AJAX functionality. We also need to create two additional JavaScript functions. The code of these functions is different depending on what you want to do. These functions or hooks will be called by the ajaxHelper() function and their names must end in “_init” and “_ajax” which will be explained below.

The ajaxHelper() function

function ajaxHelper(functionName) {
  var xmlHttp;
  // Firefox, Opera 8.0+, Safari, SeaMonkey
  try {
    xmlHttp=new XMLHttpRequest();
  }
  catch (e) {
    // Internet Explorer
    try {
      xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e) {
      try {
        xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch (e) {
        alert("Sorry, your browser does not support AJAX.");
        return false;
      }
    }
  }
 
  xmlHttp.onreadystatechange=function() {
    //The request is complete == state 4
    if (xmlHttp.readyState==4) {
      var response=xmlHttp.responseText;
      //Send reponse to _ajax hook of passed function name
      eval(functionName + "_ajax" + '(\'' + response + '\')');
    }
  }
 
  //Get request string from _setup hook of passed function name
  var requestString = eval(functionName+"_init" + '()');
  if (requestString) {
    xmlHttp.open("GET", requestString, true);
    xmlHttp.send(null);
  }
}

The _init and _ajax functions

As stated above, these are functions are hooks, meaning that they will be called dynamically by the ajaxHelper() function depending on the argument you pass it. For example, on a button click you execute the ajaxHelper(’chat_update’) function. The ajaxHelper will call chat_update_init() and then chat_update_ajax() automatically, so you must have them defined. By making them dynamic hooks, you can have many different AJAX calls on the same page but use the same ajaxHelper() function each time. You pass the ajaxHelper() function the first part of the name of your two additional functions (minus the _init and _ajax), which is “chat_update” in the above example.

The _init hook function specifies the name of the PHP file and any arguments to be passed to the ajaxHelper() function. An example _init hook is as follows:

function my_first_try_init() {
  //retrieve username from html input box with the id "name_box"
  var username = document.getElementById('name_box');
  var script = 'myscript.php';
  var queryString = "?username=" + username;
  return script + queryString;
}

The _ajax function is passed the results of the PHP script specified in the _init hook as a JavaScript variable. Using JavaScript trickery, we can update the page that the user is viewing. You can use the .innerHTML property and change the contents of a div or other element. Or, you could even change the text of input boxes by changing the .value property. This may sound confusing, but study the below examples for a better understanding.

function my_first_try_ajax(results) {
  var targetDiv = document.getElementById('firstDiv');
  var resultHTML='<h1>' + results + '</h1>';
  targetDiv.innerHTML = resultHTML;
}

The above code replaces the html within a div with the id “firstDiv” with whatever has been returned by myscript.php wrapped in h1 tags. You could have an empty div and only insert html into it on AJAX calls. The div would look like this:

<div id="firstDiv"></div>

While declaring an _ajax hook function is required, adding JavaScript code inside the function is optional. Why? Because often you do not want to change content on the user’s page, but instead just update values in the database on your call to the script specified in the _init hook. In that case, nothing would need to be updated on the page.

Your PHP Script

Creating your PHP script that will be called by the AJAX framework is easy if you know PHP. You can have your PHP script do pretty much anything. You probably want to either return some value or values, update a database, or both. The only thing to note is that to return a value, you need to “echo” it out. Values printed to the screen from your PHP callback script are returned to the the JavaScript _ajax() hook function as the results variable, as seen above.

How do you return multiple results? Well the implementation differs depending on what you want to return, but if you want to return an array you simply echo out a comma separated list in your PHP script and then you split the returned JavaScript variable by the commas and loop through the values in your _ajax() function and do whatever. Here is an example of a php script that connects to a database and returns the current sales totals for the year:

<?php
//connect to database
$link = mysql_connect('localhost', 'username', 'password')
  or die('Could not connect: ' . mysql_error());
mysql_select_db('sales_db') or die('Could not select database');
 
$currentYear = date('Y');
 
//execute query
$sql = "SELECT SUM(sale_total) as `total`
  FROM sales_table WHERE year = $currentYear";
$result = mysql_query($sql);
 
//retrieve results
while ($row = mysql_fetch_assoc($result)) {
  $total = $row["total"];
}
 
//return via echo to our JavaScript _ajax function
echo $total;
?>

Here is another example that returns an array of values:

<?php
//[not shown] do a database call and retrieve an array
$valueArray = array(23, 231, 'roger 123', 26, 'Las Veags,
  Nevada', 'Washington', 77);
 
//replace commas with their html value so they do not
//get in the way of separating out the array
// values with commas via the implode statement
echo implode(', ', str_replace(',', '&#44;', $valueArray));
?>

Activating AJAX

Finally, the only thing we are missing is how we trigger our AJAX call. There are many ways to do this. The most common method is when a user interacts with an element on the page, triggering the AJAX helper function, but this is not the only way. You can also use a JavaScript timer and call the AJAX at a set interval. This method will be covered in a future article. Let’s look at some common examples of triggering AJAX through user interaction:

Button Click

<input type="button" id="trig" value="ClickMe" onClick="ajaxHelper('my_first_ajax');" >

Mouse-Over a Div

<div id="TriggerDiv" onMouseOver="ajaxHelper('sales_calculate');" ></div>

Click in a Text Box

<input type="text" name="datefield" onClick="ajaxHelper('update_date');" >

Conclusion

The uses for AJAX are endless, especially coupled with PHP. Explore, experiment, and see what’s best for your website.

Posted on December 23, 2007 in PHP by Elliott BrueggemanNo Comments »

Background

PHP is not a strictly typed language, and many programmers often overlook problems that can be caused with not paying attention to numeric types. The problem is that PHP does not alert you when you have gone outside of the bounds of what an integer can hold. Instead, it silently converts your value to a float (floating point number.)

Why should you care? Mathematic expressions with floats are not always exact – sometimes they can be way off. PHP, like most programming languages, uses shortcuts to estimate the result of floating point mathematic expressions. The rule of thumb is that the larger the numbers you are working with, the greater amount of estimations involved in finding a result. If you were programming a PHP-based financial application, this could be a huge liability.

The best way to handle large numbers in PHP is to be aware of exactly what type of number you are dealing by knowing the PHP bounds of integers. PHP supplies a constant PHP_INT_MAX which will tell you what the maximum integer is for your instance of PHP. Not all computers/operating systems/versions of PHP are the same, so it is good to find the PHP_INT_MAX for each setup. Note that the PHP_INT_MAX also determines the smallest negative number – just multiply it by -1 to get the PHP integer minimum.

PHP Integer Testing Script

Below is a testing script to help you determine the PHP_INT_MAX:

<?php
$intMax = PHP_INT_MAX;
 
echo "$intMax<br />";
 
if (is_int($intMax)) {
	echo "$intMax is an Int<br />";
}
else {
	echo "$intMax is NOT an Int<br />";
}
 
if (is_int($intMax + 1)) {
	echo "$intMax+1 is an Int<br />";
}
else {
	echo "$intMax+1 is NOT an Int<br />";
}
 
if (is_int($intMax * (-1))) {
	echo "$intMax*(-1) is an Int<br />";
}
else {
	echo "$intMax*(-1) is NOT an Int<br />";
}
?>

The result of this script:

2147483647
2147483647 is an Int
2147483647+1 is NOT an Int
2147483647*(-1) is an Int

PHP Float Testing Script

Now that you know the bounds of integers, what do you do? Truth be told, there is not a whole lot you can do to guarantee the integrity of your floating point numbers. It may be more important to know which figures are the result of math involving floating point numbers, so you can disclose this to your audience, and act accordingly. See the simple example below that shows how poorly PHP can do math involving floating point numbers:

<?php
//TEST 1
$number = 216897510871;
$original_number = $number;
 
$number *= 11123.74;
$number /= 11123.74;
 
if ($original_number == $number) {
	echo "Test 1: Are Equal<br />";
}
else {
	echo "Test 1: Are NOT Equal<br />";
}
 
//TEST 2
$number = 216897510871;
$original_number = $number;
 
$number *= 11123.75;
$number /= 11123.75;
 
if ($original_number == $number) {
	echo "Test 2: Are Equal<br />";
}
else {
	echo "Test 2: Are NOT Equal<br />";
}
?>

The result of this script:

Test 1: Are Equal
Test 2: Are NOT Equal
Posted on December 16, 2007 in PHP by Elliott BrueggemanNo Comments »

Background

Previously we have seen how to make a native Excel spreadsheet through the use of the PEAR extension. This article is about generating comma (.csv.) and tab delimited spreadsheets that are readable in many popular programs, and useful in a multitude of websites and applications. You need no external packages or extensions to generate these files - PHP does this natively.

Differences

Comma separated value files known by their .csv extension are the most popular alternative to the native Excel .xls spreadsheet file. One problem is that .csv files are actually text files with column values separated with commas, and this can cause problems when your data also has commas in it. The additional code necessary to solve this problem is often not worth it, so many people generate tab delimited files with PHP instead. When creating tab delimited files, you can use both the native Excel .xls extension or the .tsv (tab separated values) extension. However, a user’s OS may not be setup to recognize the .tsv extension and may try to open it in a regular text editor. The better option is to use the Excel .xls extension for your tab delimited files to guarantee that the user will be able to open it successfully with a myriad of browser, OS, and software combinations - I have found that many other non Microsoft spreadsheet programs support the .xls extension. In the below script, I have opted below for an .xls tab delimited file, but I have also included the necessary changes in the comments to generate .csv files as well.

PHP Code

<?php
/* Data to be inserted into excel in an array of arrays
 * Each array is the avg monthly temp of a different city */
$data = array ( array ( "City" => "Seattle",
	"Jan" => 46, "Feb" => 50, "Mar" => 53, "Apr" => 58,
	"May" => 64, "Jun" => 70, "Jul" => 75, "Aug" => 76,
	"Sep" => 70, "Oct" => 60, "Nov" => 51, "Dec" => 46 ),
	array ( "City" => "New York",
	"Jan" => 39, "Feb" => 42, "Mar" => 50, "Apr" => 60,
	"May" => 71, "Jun" => 79, "Jul" => 85, "Aug" => 83,
	"Sep" => 76, "Oct" => 64, "Nov" => 54, "Dec" => 44 ),
	array ( "City" => "San Francisco",
	"Jan" => 56, "Feb" => 59, "Mar" => 61, "Apr" => 64,
	"May" => 67, "Jun" => 70, "Jul" => 71, "Aug" => 72,
	"Sep" => 73, "Oct" => 70, "Nov" => 62, "Dec" => 56 )
);
 
$csvTitle = "Monthly Average High Temperature By City";
 
/* We know the keys of each sub-array are the same, so
 * extract them from the first sub-array and set them
 * to be our column titles */
$titleArray = array_keys($data[0]);
 
/* Set your desired delimiter. You can make this a true
 * .csv and set $delimiter = ","; but I find that tabs
 * work better as commas can also be present in your data.
 * Note that you must use the .tsv or .xls file extension for Excel
 * to correctly interpret tabs. Otherwise if you are using commas
 * for your delimiter, use .csv for your file extension. */
$delimiter = "\t";
 
//Set target filename - see above comment on file extension.
$filename="Search_Export.xls";
 
//Send headers
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
header("Pragma: no-cache");
header("Expires: 0");
 
//print the title to the first cell
print $csvTitle . "\r\n";
 
//Separate each column title name with the delimiter
$titleString = implode($delimiter, $titleArray);
print $titleString . "\r\n";
 
//Loop through each subarray, which are our data sets
foreach ($data as $subArrayKey => $subArray) {
	//Separate each datapoint in the row with the delimiter
	$dataRowString = implode($delimiter, $subArray);
	print $dataRowString . "\r\n";
}
?>
Posted on December 7, 2007 in