Random Quotes with XML
This tutorial will teach you how to create a class which can deal with a selection of quotes stored in an XML file. The class we will develop will contain two main functions; getRandomQuote which will take a random quote from the xml file and return it to us, and getQuotesByAuthor which will select and return all the quotes written by a certain author.
Click here for an example of the xml file that this tutorial will use.
This tutorial does use classes which means you will need a knowledge of Object Orientated Programming to fully understand it as I will not fully explain all these details, in addition it’s worth noting that all the code is written for PHP 4.3, and I can’t guarantee that it will work correctly in PHP 5.
Lets get started! The First thing you’ll need to do is download or save the xml file to your web server, either copy it below, or go here and save the file in your web browser.
<?xml version="1.0" encoding="utf-8"?> <allQuotes> <quote> <content>Before God we are all equally wise - and equally foolish.</content> <author>Albert Einstein</author> </quote> <quote> <content>It is a miracle that curiosity survives formal education.</content> <author>Albert Einstein</author> </quote> <quote> <content>Always forgive your enemiesnothing annoys them so much.</content> <author>Oscar Wilde</author> </quote> <quote> <content>Whatever you do will be insignificant, but it is very important that you do it.</content> <author>Mahatma Gandhi</author> </quote> </allQuotes>
Now that you have the XML file we can start to write the PHP class.
First we need to start our class and define the variables we will be using:
class Quotes{ var $quoteURL; var $quoteXML; var $quoteValues; var $numQuotes;
Generally when writing PHP classes you start the class name (in this case ‘Quotes’) with a capital letter. After defining our class, we can write a function which is executed when an object is created from our class, to do this we simply name this function the same as our class, ‘Quotes’:
function Quotes($quoteURL){//function executes when class starts $this->quoteURL = file_get_contents($quoteURL); $parser = xml_parser_create(); xml_parse_into_struct($parser, $this->;quoteURL, $this->quoteXML, $this->quoteValues); xml_parser_free($parser); $this->setNumQuotes(); }
This function uses one parameter, the URL of the XML file we will be reading from. This will be specified later in the script. The function then gets the contents of the XML file via file_get_contents, and uses the xml parsing functions that are built into php to deal with XML code. Using xml_parse_into_struct() we send all the tags and their values to the variable $quoteXML, this will be the most important in the script. Finally we call another function which is located in the class using ‘$this->setNumQuotes()’, this function is shown below:
function setNumQuotes(){ $i=0; $numNodes=count($this->quoteXML);//the number of tags $quotes=0; while($<$numNodes){ if($this->quoteXML[$i][tag]=="CONTENT"){ $quotes++; } $i++; } $this->numQuotes=$quotes; }
This functions works out how many quotes are stored in the XML file, a piece of information which we will need later. To do this it first uses the count() function to work out how many tags are stored in the XML file, then checks each tag to see if it stores the content information for one quote. Each time it finds the content information we know that it represent one quote: we keep a running total of these occurrences and at the end of the function we store this value in the variable $numQuotes so that it can be accessed from all of the other functions in the class.
Now we move onto our first really useful function, which returns quotes selected randomly from the XML file:
function getRandomQuote($number){ $quotes=array(); $i=0; while($i<$number){ $randNum=rand(0,$this->numQuotes-1)*10; $content=$this->quoteXML[$randNum+2][value]; $author=$this->quoteXML[$randNum+5][value]; array_push($quotes,array('content'=>$content,'author'=>$author)); $i++; } return $quotes; }
This function has one parameter, which lets the user specify how many quotes they want to retrieve. The script runs through a while loop for the number of times specified in $number. Each time the script loops it finds a random quote and adds it to an array which is returned at the end of the function.
During this loop we first generate a random number between 0 and the the number of quotes minus 1. The reason it starts on 0 is because the first index of an array is automatically 0, and we also minus 1 from the number of quotes to compensate for this. We then grab the content and author data from of the quote we randomly selected and add this to the end of the array we are compiling, using the array_push() function.
The last function in the class allows you to select all the quotes by a certain author.
function getQuotesByAuthor($author){ $i=0; $numNodes=count($this->quoteXML);//the number of tags $quoteArray=array(); while($i<$numNodes){ if($this->quoteXML[$i][value] == $author){ $contentID=$i-3; array_push($quoteArray,$this->quoteXML[$contentID][value]); } $i++; } return $quoteArray; }
For this function we search through each tag until we find one which contains author information, then we check to see if the author is the one we want, if it is then we add the quote to our array, if not then we move on to the next tag.
To do this we use a while loop, which repeats for the number of tags we have in the XML file. Then we use an if statement to check if the author is the one we want, and if so then we work out which tag contains the content of this quote, by taking 3 away from the index id of the author tag. Like in the previous function we use array_push() to add this quote to an array, which we return at the end of the function.
Putting all this together we get a class which looks like this:
class Quotes{ var $quoteURL; var $quoteXML; var $quoteValues; var $numQuotes; function Quotes($quoteURL){//function executes when class starts $this->quoteURL = file_get_contents($quoteURL); $parser = xml_parser_create(); xml_parse_into_struct($parser, $this->quoteURL, $this->quoteXML, $this->quoteValues); xml_parser_free($parser); $this->setNumQuotes(); } function setNumQuotes(){ $i=0; $numNodes=count($this->quoteXML);//the number of tags $quotes=0; while($i<$numNodes){ if($this->quoteXML[$i][tag]=="CONTENT"){ $quotes++; } $i++; } $this->numQuotes=$quotes; } function getRandomQuote($number){ $quotes=array(); $i=0; while($i<$number){ $randNum=rand(0,$this->numQuotes-1)*10; $content=$this->quoteXML[$randNum+2][value]; $author=$this->quoteXML[$randNum+5][value]; array_push($quotes,array('content'=>$content,'author'=>$author)); $i++; } return $quotes; } function getQuotesByAuthor($author){ $i=0; $numNodes=count($this->quoteXML);//the number of tags $quoteArray=array(); while($i<$numNodes){ if($this->quoteXML[$i][value] == $author){ $contentID=$i-3; array_push($quoteArray,$this->quoteXML[$contentID][value]); } $i++; } return $quoteArray; } }
To use this class we need to create a new object, from which we can call a function as shown below. Remember that because the Quotes() function requires a parameter we must provide it when we create the object:
$quotes= new Quotes('quotes.xml');/*this creates a new object, quotes.xml is the location of the xml file and the parameter required by the Quotes() function */ print_r($quotes->getRandomQuote(2));/*prints out an array containing the details of two random quotes*/ print_r($quotes->getQuotesByAuthor('Albert Einstein'));/*prints out all the quotes by Albert Einstein*/
I hope this tutorial has helped, feel free to post a comment if you have any questions or queries.
September 30th, 2008 at 4:46 pm
I probably wouldnt use it for its intended use but adapted slightly and it would be very useful.