Caching Dynamic XML Pages with PHP

Posted by Andrew on Jun 20, 2010 in Code, Web Design |

Below is a method to cach database heavy dynamic pages. In this example I was building an elaborate playlist which would be hit by lots of users. For the example I greatly simplified the query I was making so that you can see the caching method. With this method the first user to hit the page on the day would build a text file which is saved on the server with the xml content. Each consecutive user would just read the file instead of hitting the database. This greatly reduced the load on the database server leaving it free for handling individual requests such as searches.

Though this example builds an xml file, it would be just as easy to build an html page.

Start by opening creating the proper header in your php file and defining where you are storing the cached code.

//Make sure the header type is set for XML
header ("Content-Type:text/xml");

//The filename of the saved xml data.

Now its time to check if the data file exists. If it does then get the file date.

//Look for the video list xml file
if (file_exists($filename)) {

	//Check the date of the current xml file.
	$last_modified = date ("Y-m-d", filemtime($filename));
} else{
	//Set to an old date so it will create a new file

We then compare the files date to todays date and see if its old.

$todays_date = date("Y-m-d");
$today = strtotime($todays_date);

$expiration_date = strtotime($last_modified);
if ($expiration_date == $today) { 

	//The file is less than 24 hours old so show it
	//echo the file to the user
	$xmlpage = file_get_contents($filename);
	echo $xmlpage;

If the file is more than 24 hours old then begin updating the data. In this code I am grabbing the data from the database for my videos and then assembling the XML and assigning it to a variable.

} else { 

		//If file is old, make a new one.
               //Start the xml file

               //Open your database with an include
              include 'openDB.php';
               //Query your database and build your xml file by adding to $xml_output
               $query = 'SELECT * FROM `daily_videos`  ORDER BY RAND() LIMIT 0 , 100';
               $result=mysql_query($query) or die("result error". mysql_error());
		if (!$result) {
Error performing query: " .
			   mysql_error() . "


		//Close the database
		include 'admin/includes/closeDB.php';

		//Build the new file
		$xml_output = "\n";
		$xml_output .= "\n";
		while ( $row = mysql_fetch_array($result) ) {

I always like to make sure that the data I am pulling from my database is correct by checking that the video files and images are really there.

			//Check to see if all the files are there,  if not, do not show the listing.
			$videofilename = $_SERVER{'DOCUMENT_ROOT'} ."/mp4/". strtolower($row['filename']).".mp4";
			$thumbfilename=	$_SERVER{'DOCUMENT_ROOT'} ."/thumbnails/".strtolower($row['filename']).".jpg";

				if (file_exists($videofilename)) {

					if (file_exists($thumbfilename)){
						$xml_output  .=  "\t\n";
						$xml_output .= "\t\t" . $row["idx"] . "\n";
					        $xml_output .= "\t\t\n";

XML files are very strict when it comes to what characters can be used. The following code is used to remove any illegal characters that may have been entered in by the writers who were writing the descriptions.

					        // Escaping illegal characters that nay be in the description
						$row['description'] = str_replace("&", "and", $row['description']);
						$row['description'] = str_replace("<", "less than", $row['description']);
						$row['description'] = str_replace(">", "greater than", $row['description']);
						$row['description'] = str_replace("\"", "'", $row['description']);
						$row['description'] = str_replace("#", "number", $row['description']);
						$row['description'] = str_replace("`", "'", $row['description']);
						$row['description'] = str_replace("’", "'", $row['description']);
						$row['description'] = htmlspecialchars($row['description']);

					        $xml_output .= "\t\t" . htmlentities ($row['description']) . "\n";
					       $xml_output .= "\t\t
" . htmlentities ($row["artist_name"]) . "\n";
					       $xml_output .= "\t\t" . $row['filename'] . "\n";
					       $xml_output  .=  "\t\n";

		$xml_output .= "";
               //Close the xml tag
               $xml_output .= "";

In the following code I delete the old data file and then write the variable $xml_output to a new file.

		//Delete the old file

		//Write the data to file for the next user
		$fh = fopen($filename, 'w') or die("can't open file");
		fwrite($fh, $xml_output);

		//Output the data for this user
		echo $xml_output;

Tags: ,

Copyright 2010 Andrew McClary