Article

The PHP Anthology Volume 2, Chapter 1 - Access Control

Page: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Next

The addText method is where the clever work takes place:

Example 1.25. Images/RandomImageText.php (in SPLIB) (excerpt)          
         
 /**          
  * Add text to the image which is "randomized"          
  * @param string text to add          
  * @param int red hex value (0-255)          
  * @param int green hex value (0-255)          
  * @param int blue hex value (0-255)          
  * @return boolean true text was added successfully          
  * @access public          
  */          
 function addText($text, $r=38, $g=38, $b=38)          
 {          
   $length = $this->fWidth * strlen($text);          
         
   if ($length >= ($this->iWidth - $this->fWidth * 2)) {          
     return FALSE;          
   }          
         
   $this->xPos = floor(($this->iWidth - $length) / 2);          
         
   $fColor = ImageColorAllocate($this->image, $r, $g, $b);          
         
   srand((float)microtime() * 1000000);          
   $fonts = array(2, 3, 4, 5);          
   $yStart = floor($this->iHeight / 2) - $this->fHeight;          
   $yEnd = $yStart + $this->fHeight;          
   $yPos = range($yStart, $yEnd);          
                 
   for ($strPos = 0; $strPos < $length; $strPos++) {          
     shuffle($fonts);          
     shuffle($yPos);          
     ImageString($this->image,          
                 $fonts[0],          
                 $this->xPos,          
                 $yPos[0],          
                 substr($text, $strPos, 1),          
                 $fColor);          
     $this->xPos += $this->fWidth;          
   }          
   return TRUE;          
 }

Provided with a text string, the class will scatter the letters on the image, using a randomly varying vertical position, and a font chosen at random from a list. Optionally, you can supply this method with red, green, and blue values, which will define the color of the text.

If the string you provide is too big for the image, no text will be displayed; the code generates an error notice, but you'll have to pick this up with your error handler (see Chapter 10, Error Handling), as it will be invisible on the image.

The next two methods can be used to clear out any existing fonts registered with the class, and add new fonts. The default PHP fonts are somewhat dull and rather small, so you may want to consider adding your own. Check out PHP's imagestring and imageloadfont functions for further details.

Example 1.26. Images/RandomImageText.php (in SPLIB) (excerpt)          
         
 /**          
  * Empties any fonts currently stored for use          
  * @return void          
  * @access public          
  */          
 function clearFonts()          
 {          
   return $this->fonts = array();          
 }          
         
 /**          
  * Adds a new font for use in text generation          
  * @param string relative or full path to font file          
  * @return void          
  * @access public          
  */          
 function addFont($font)          
 {          
   $this->fonts[] = imageloadfont($font);          
 }

The getHeight and getWidth methods can be useful if you're unsure of the exact dimensions of your background image and want to determine whether the text you want to add will fit on the background before you add it.

Example 1.27. Images/RandomImageText.php (in SPLIB) (excerpt)          
         
 /**          
  * Returns the height of the background image in          
  * pixels          
  * @return int          
  * @access public          
  */          
 function getHeight()          
 {          
   return $this->iHeight;          
 }          
         
 /**          
  * Returns the width of the background image in          
  * pixels          
  * @return int          
  * @access public          
  */          
 function getWidth()          
 {          
   return $this->iWidth;          
 }

Finally, the getImage method returns the PHP resource identifier for the image.

Example 1.28. Images/RandomImageText.php (in SPLIB) (excerpt)          
         
 /**          
  * Returns the image resource for use with          
  * the ImageJpeg() function          
  * @return resource          
  * @access public          
  */          
 function getImage()          
 {          
   return $this->image;          
 }          
}

We still have to convert the image to a JPEG with the imagejpeg function; I've chosen to return the resource identifier rather than simply displaying the image itself, as I may want to manipulate the image further with other code and classes.

Now that we've prepared the class for adding text to an image, we need to update the SignUp class to provide a method that generates the text to appear in the image:

Example 1.29. AccessControl/SignUp.php (in SPLIB) (excerpt)          
         
 /**          
  * Creates a random string to be used in images          
  * @return string          
  * @access public          
  */          
 function createRandString()          
 {          
   srand((double)microtime() * 1000000);          
   $letters = range ('A','Z');          
   $numbers = range(0,9);          
   $chars = array_merge($letters, $numbers);          
   $randString = '';          
   for ($i=0; $i<8; $i++) {          
     shuffle($chars);          
     $randString .= $chars[0];          
   }          
   return $randString;          
 }

The trick now is to generate a random string with the above method, then store it in a session variable that's accessible by the code that actually generates the image. First, we need to modify one or two parts of the registration form code from the previous solution.

In the section where we begin to build the form, make the following modifications:

Example 1.30. 7.php (excerpt)          
         
 // Register a session variable for use in the image          
 if (!$session->get('randomString'))          
   $session->set('randomString', $signUp->createRandString());

The above code checks whether the random string has been created and stored in a session variable. If not, it creates one and stores it in a session variable.

Now, we add the form field and an img tag containing the image:

Example 1.31. 7.php (excerpt)          
         
 // The image check field for "humanness"          
 $form->addElement('text', 'imageCheck', 'Image Text:',          
                   'class="signupData"');          
 $form->addRule('imageCheck', 'Please enter text from image',          
                'required', false, 'client');          
           
 // Server side validation!          
 // Don't give away random string in JavaScript          
 $form->addRule('imageCheck',          
                'Please confirm the text in the image',          
                'regex',          
                '/^' . $session->get('randomString') . '$/',          
                'server');          
           
 // The image check field          
 $form->addData('          
   <tr valign="top">          
     <td class="info">          
       Enter the text as it<br />appears in the image          
     </td>          
     <td class="field">          
       <img src="8.php" />          
     </td>          
   </tr>');

Note that the validation rule we've applied to this field uses server side validation only, not client side. If we did use client side validation, a regular expression stating exactly what the image contains would appear in JavaScript, and would be available for a computer program to read.

All that remains is the code that will display the image itself:

Example 1.32. 8.php          
         
<?php          
// Include Session class          
require_once 'Session/Session.php';          
         
// Include RandomImageText class          
require_once 'Images/RandomImageText.php';          
         
// Instantiate the Session class          
$session = new Session;          
         
// Instantiate RandomImageText giving the background image          
$imageText = new RandomImageText('reg_image/reg_image.jpg');          
         
// Add the text from the session          
$imageText->addText($session->get('randomString'));          
         
// Send the right mime type          
header('Content-type: image/jpeg');          
         
// Display the image          
ImageJpeg($imageText->getImage());          
?>

Note that we passed the random string via a session variable, as opposed to a query string variable, as this, too, would be available for reading by a "robot" script.

Figure 1.4 illustrates the form modified with the new image checking feature.

1279_fig4
Figure 1.4. Humans Only, Thank You

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links