Linux Online Advertisement
[ Register ]

[ Applications ]
[ Documentation ]
[ Distributions ]
[ Download Info ]
[ General Info ]
[ Book Store ]

Advertisement

[ Courses ]
[ News ]
[ People ]
[ Hardware ]
[ Vendors ]
[ Projects ]
[ Events ]
[ User Groups ]
[ User Area ]

Building Embedded Linux Systems

[ About Us ]
[ Home Page ]
[ Advertise ]

Advanced Linux Course

Linux Programming with PHP

Since we've already covered a great deal of PHP programming in the intermediate course, we'll be covering some items in this course to supplement what you've learned previously. This section will consist of short lessons of ways on how to enhance your use of PHP.

Using the GD Library

GD is a library to provide a means to create PNG, JPEG and GIF images for web pages on the fly. You can use GD, for example, to create buttons, graphs, charts and other types of graphics based on changing information. Let's say you had some data that you wanted to represent as a pie graph. Traditionally, you would create the image of the graph with some image manipulation tool and then include it on a web page. When the data that the graph is based on changed, you would have to do this all over again. With the GD library, you can take this 'real time' data and create new graphs whenever the data changes.

Installing the GD library used to involve compiling support into PHP, but as of version 4.3, GD support has been added to PHP by default. All you have do do is know how to use it in your scripts. That's what we're going to learn how to do now.

The Human Test

You've probably noticed that to sign up for free email accounts or blog services, you normally have to type the letters and numbers found in an image. These images, created on the fly, are there to separate humans from robots. Web robots can create thousands of accounts without any kind of human intervention. What they cannot do, however, is tell you what a picture contains. That's essentially the idea behind having you type in the letters and numbers found in one of these images. Since there is no 'text' in the image, human eyes are required to know what it says. Our example for using the GD library will be to create one of these images for a web sign up form. Let's have a look at the code:

<?php
//generate 5 letters/numbers at random

mt_srand((double)microtime() * 1000000);
$pool = array('a','b','c','d','e','f','g','h','j','k', 'm','n', 
'p', 'r','s','t','u','v','w','x','y', '2', '3', '4', '5', '6', 
'7', '8', '9');
        for($i=1; $i<=5; $i++){
                $randomness = mt_rand(0,25);
                $robocode .= $pool[$randomness];
        }



// create image
$width = 200;
$height = 80;
$image = imagecreate($width, $height);

/* colors of image - tries to be difficult
* creates a wine background
* and similar letter color */


// NOTE: 0,0 are the X and Y coordinates of 
// the upper left corner of the rectangle,

imagefilledrectangle($image, 0, 0, $width, $height, $wine);

/* NOTE:
 * 28 = font size 
 * 20 = gives the text a slight angle 
 * 15,70 = the X and Y coordinates of text */

imagettftext($image, 28, 20, 15, 70, $semi_wine, "./StayPuft.ttf", "$robocode");
// have a different name everytime we show the image
$pngName = date("dHis");

imagepng($image,"$pngName.png");

// free memory
imagedestroy($image);

?>

Let's have a look at the code. First, we need to create a random string. The first routine does just that. The $pool variable is an array of numbers and letters. Since some letters and numbers resemble each other (which causes mistakes and annoys people), I have removed ones that I consider problematic from the array (0 and the letter O, z and the number 2, 1 and the letter l, etc.). Our goal is to trick the robots, not humans.

Next, we create the image itself. This is fairly straightforward, as you can see. Declare the height and width as variables and then use GD's 'imagecreate' to create it. Now we define the colors for the image. As you can see in my comments in the code, we try to make this as difficult as possible for OCR (optical character recognition) programs. Some of these systems have been defeated by robot programs that can even scan the image. I tested this out using GOCR, an open source OCR program and I wasn't able to get the characters. Finally, we apply color to the image with 'imagefilledrectangle'.

As far as creating the text itself, 'imagettftext' does that. We'll also use a free (as in both beer and freedom) true-type font I found called StayPuft.ttf. One of the reasons I picked it is because it's strange-looking enough to be difficult for OCR. The comments above explain what the numbers correspond to.

Next, we rename the image. It would be easy to defeat the system if we gave it the same name as the random string that appears. I chose to give it the name of the day, hour and seconds of the server. This adds a bit of randomness as well.

The last bit we need to do is destroy the image. If we just kept creating images every time somebody signed up, the server would run out of memory. Destroying it frees up memory and ensures that this never happens.

Ideally, you would take this code and embed it into a sign up form.

include ("antirobot.php");

print "<img alt=\"eat this robot!\" src=\"$pngName.png\" />\n";

On the actual sign up form, how do we make sure the user is entering the random letters and numbers on the image? There are a few ways to do it, but since we don't need the GD library for that, consider it your homework to figure that out.

PHP and XML

This section is meant to deal with how PHP can process XML, so it's logical that we have to talk, first, about XML.

About XML

XML stands for eXtensible Markup Language. XML is something like HTML except that there are no pre-defined tags. For example, if we were writing a story for a web page using HTML, it would most likely look like this:

<h1>A Sad Story</h1>
<h2>Chapter 3</h2>
<h3>In which our hero gets trapped in an abandoned mine with
an encyclopedia salesman</h3>
<p>"Look at the bindings on these tomes. This is real lea...". Before
he could get the word 'leather' out of his mouth, the beams holding
up the roof of the tunnel, exhausted from dry rot, gave way, spewing
debris in front of the entrance. </p>

Since we said that XML uses no pre-defined tags, in XML it could look like this:

<story>
<title>A Sad Story</title>
<chapter>Chapter 3</chapter>
<summary>In which our hero gets trapped in an abandoned mine with
an encyclopedia salesman</summary>
<para>"Look at the bindings on these tomes. This is real lea...". Before
he could get the word 'leather' out of his mouth, the beams holding
up the roof of the tunnel, exhausted from dry rot, gave way, spewing
debris in front of the entrance. </para>
</story>

As the web became more popular, HTML began to show its limitations. For this reason, XML was developed. It's necessary to point out, however, that XML is not a substitute for HTML. HTML is really about how data should look. What limits HTML is that there is no way to define or describe the data itself. That's where XML picks up the slack. Take a look at the two examples. The story in HTML format has the summary in <h3> tags. This tells us how the summary should look but it doesn't tell us that it's a summary. We could put anything between <h3> tags. On the other hand, the XML example shows that what goes between the <summary> tags is, in fact, a summary of the story. Even though we've defined this, there's still a problem. A browser or other rendering device won't know what do do with this XML file. That's where HTML comes back into the picture. Since browsers do know what to do with HTML, we can create a type of style sheet for XML, known as XSLT, that explains how the XML is to be formatted for a browser. Now we've reached the point where PHP comes into the picture.

XML Support in PHP

There are two stable versions of PHP, so that means there are two ways of handling XML support in PHP. First, if you're using the PHP 4.3 series (this comes by default with most distributions), you'll need to add XML support by adding on libraries. The main library you'll need is called Sablotron. The machine I am using to create and test the examples for this lesson is running Debian Sarge, which, at the time of this writing is the stable version of Debian. To add XML support to the default installation of PHP, I used apt-get like so:

apt-get install php4-xslt

This will install the Sablotron and other necessary libraries to that your PHP setup with parse XML files.

As far as the newer PHP 5 goes, please refer to the previous chapter where we dealt with installation in depth. Here we mention that XML has much better built-in XML support. Nevertheless, at the time of this writing, PHP 4 is more widely used at present so our examples in this lesson will run on a webserver using PHP 4.

An XML Example

I got my start with Linux as a English as a foreign language teacher looking for ways to improve computer assisted learning. So I suppose it's appropriate to use an English exercise as an example of XML support in PHP.

The English exercise is a good example because XML works best when we need to serve pages that have fairly well-defined layout. In our example, we'll be creating exercises with questions, possible answers and an answer key.

Designing a Document

What you'll need to do first is design a standard document format that suits your needs. That's easy to do thanks to XML. A template for my English exercise looks like this:

<?xml version="1.0" encoding="ISO-8859-1"?>

<exercise>

<!-- preliminary stuff - like metadata -->

<metasect>

<keywords>
<word id="x"></word>
</keywords>

<createinfo>
<writers>
      <author>
        <firstname>John</firstname>
        <minitial>Q.</minitial>
        <lastname>Public</lastname>
        </author>
</writers>

<legal>
<copynote>copyright © John Q. Public</copynote>
</legal>

<createdate>
     <year>YYYY</year>
     <month>MM</month>
     <day>DD</day>
</createdate>

<update id="X">
     <year>YYYY</year>
     <month>MM</month>
     <day>DD</day>
     <comment></comment>
</update>
</createinfo>

<caption></caption>

</metasect>

<!-- end prelim -->
<!-- start exercise -->

<exersect>

<subjectinfo>
<level></level>
<category></category>
<subcategory></subcategory>
<topic></topic>
</subjectinfo>

<title></title>

<instruc>

</instruc>

<!-- provide an example if needed -->

<example>
<exquest></exquest>
<exans></exans>
</example>

<questsect>

<question id="X">
<showquest> </showquest>
<choices>
<poss></poss>
<poss></poss>
<poss></poss>
</choices>
</question>

</questsect>

<keysect>

<!-- provide an example if needed -->
<keycomment>
<comment></comment>
</keycomment>

<key id="X">
<showkey> </showkey>
</key>

</keysect>

</exersect>

</exercise>


First, we define the whole document as an 'exercise'. Then we base it on two major sections: <metasect>, which contains metadata about the document, <exersect> which contains the meat and potatoes of the exercise. <exersect> itself contains two main subsections: <questsect>, which contains the questions and <keysect>, which contains the answer key part. I like this layout best, as it provides a framework to base your XML document around. You go filling in layers from the general to the more specific.

As far as the questions and the answers go, you'll see that we've identified each with and ID tag. This is to associate the question with its corresponding answer.

Then we flesh out the document with other sections that provide additional information, like the <instruc> section to provide instructions on the exercise, <example>, which provides an example question, and the <keycomment> to provide some kind of commentary on the answers.

Now that we have our document layout decided on, now it's time to create a style sheet.

Creating XSLT Style Sheets

XSLT stands for EXtensible Stylesheet Language Transformations. Transformations is the keyword here. As we mentioned before, if we create an XML document using the template above, a browser doesn't know what to do with it. That's where our XSLT document comes in. It provides the instructions on how the XML document should be displayed. In our server running PHP, both the XML and XSLT files will be parsed and based on the XSLT, the XML document will be rendered in a browser. For our English exercise, our XSLT file will look like this:

<xsl:stylesheet version = '1.0'
     xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>

 <xsl:output encoding="UTF-8" indent="no"
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    omit-xml-declaration="yes" />
  <xsl:template match="/">
  <html>
  <head>
  <meta name="Keywords" content="english" />
  <title><xsl:value-of select="exercise/exersect/title"/></title>
  </head>
  <body>
  <p><small><strong>Level: </strong><xsl:value-of select="exercise/exersect/subjectinfo/level"/></small><br/>
  <small><strong>Category: </strong><xsl:value-of select="exercise/exersect/subjectinfo/category"/></small><br/> 
  <small><strong>Topic: </strong><xsl:value-of select="exercise/exersect/subjectinfo/topic"/></small></p>
  <p></p>
  <h3 align="center"><xsl:value-of select="exercise/exersect/subjectinfo/title"/></h3>
  <p><big><span style="color: #000080;"><xsl:value-of select="exercise/exersect/instruc"/></span></big></p>
  
<!-- show example if its there -->

<xsl:if test="exercise/exersect/example/exquest">
<p><small><strong>Example:</strong> <xsl:value-of select="exercise/exersect/example/exquest"/></small><br/>
<small><span style="font-style: italic"><xsl:value-of select="exercise/exersect/example/exans"/></span></small></p>
</xsl:if>

<!-- show questions -->

<ol>
<xsl:for-each select="exercise/exersect/questsect/question">
      <li><xsl:value-of select="showquest"/>
      <ul>
         <xsl:for-each select="choices/poss">
          <li><xsl:value-of select="."/>
          </li>
          </xsl:for-each>
          </ul>
       </li><p></p>
      </xsl:for-each>
      </ol>
<p></p>

<!-- javascript routine to show answer key -->

<link href="/written/advan/xml/showkey.css" rel="stylesheet" type="text/css" />
<p><script type="text/javascript" src="/written/advan/xml/showkey.js"></script></p>
<div class="keysect"> 
<ul>
<li><a style="cursor:pointer;" onmousedown="toggletree(this)">Click to show/hide answer key</a>
<p>
<!-- show key comment if its there -->

<xsl:if test="exercise/exersect/keysect/keycomment/comment">
<p><small><strong><xsl:value-of select="exercise/exersect/keysect/keycomment/comment"/></strong></small></p>
</xsl:if>
</p>

<ol class="subnav" style="display: none;">
<xsl:for-each select="exercise/exersect/keysect/key">
      <li><xsl:value-of select="showkey"/>
      </li>
      </xsl:for-each>
      </ol>
</li>
</ul>
</div>


<p align="right"><small><strong>Created:</strong> 
<xsl:value-of select="exercise/metasect/createinfo/createdate/year"/>-<xsl:value-of select="exercise/metasect/createinfo/createdate/month"/>-<xsl:value-of select="exercise/metasect/createinfo/createdate/day"/></small><br/>

<small><strong>Revisions:</strong> 
<!-- show each update -->
<xsl:for-each select="exercise/metasect/createinfo/update">
<br/>
<xsl:value-of select="year"/>-<xsl:value-of select="month"/>-<xsl:value-of select="day"/>
</xsl:for-each>
</small></p>

<p align="right"><small><xsl:value-of select="exercise/metasect/createinfo/legal/copynote"/></small></p>

  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

If you notice, there are elements of both style sheets and programming languages in an XSLT style sheet. You can also see that it makes use of HTML tags. In this case, we're using the XHTML standard.

The normal way to place XML content inside a style sheet is to use: <xsl:value-of select="/XMLtag/">; in between the HTML tags for the content in question.

You'll notice, though, that XSLT can take on attributes of a programming language. Note, for example, the section where we test if the English lesson has provided an example question:

<xsl:if test="exercise/exersect/example/exquest">
<p><small><strong>Example:</strong> <xsl:value-of select="exercise/exersect/example/exquest"/></small><br/>
<small><span style="font-style: italic"><xsl:value-of select="exercise/exersect/example/exans"/></span></small></p>
</xsl:if>

If it finds content between the XML tags it will display it. This is essentially an 'if' condition, found it any programming language. Just below that, we see another programming language convention. Using a 'for-each', we output the questions in a numbered list:

<ol>
<xsl:for-each select="exercise/exersect/questsect/question">
      <li><xsl:value-of select="showquest"/>
      <ul>
         <xsl:for-each select="choices/poss">
          <li><xsl:value-of select="."/>
          </li>
          </xsl:for-each>
          </ul>
       </li><p></p>
      </xsl:for-each>
      </ol>
<p></p>

Each time it runs into a 'question' tags, it will display what it finds. This method is also used in the answer key section.

Tying It Together with PHP

PHP is going to provide the means to serve this content. All we need is a simple script to do this:

<?php


$xh = xslt_create();
$showex = xslt_process($xh,"xml/{$_GET['exercise']}","xml/exercise.xsl",NULL);

if ($showex)

{
  print $showex;
}

else

{
 print "Error: ".xslt_error($xh);
}


?>

We'll call this script englishex.php. It simply takes any exercise file we create and parses it according to what's in our XSLT file, which we've named exercise.xsl. To access our English exercises in XML format, the URL would look like this:

englishex.php?exercise=adjectives.xml

The output would be standards compliant, browser-readable XHTML.



Comments: feedback (at) linux.org
Advertising: banners (at) linux.org
Copyright Linux Online Inc.
Compilation ©1994-2008 Linux Online, Inc.
All rights reserved.