Use PHP Flat File Cache To Lighten Database Load

Posted in Tutorials, Web Design • Posted on 8 Comments

We know how much fun it is to have to write the same query 12 different times and/or do a lot of LEFT, INNER, or explicit JOINs to the data that we need.  There are several different available methods of caching available depending on the environment we are developing in.  One that is very quick and simple is Flat File caching and it can also serve many different purposes.

These methods are slightly advanced and can be very helpful if you have built your own custom CMS for your website.  Later we will link to more basic practices that can lead you up to these methods.

Using flat file caching for an easily accessible array

This can be handy if you have a site that uses categories for anything like products, blogs, articles, etc. For this it is very nice to use a multi-dimensional array as you will most likely want to store more than one thing about each category. Let’s just take an example of product categories. For product categories you will have information on at least; category URL, category title, DB id, and possibly some more details about the category or an image (there are of course many more possibilities). You could structure the array with the id as the key or what is most likely better you can use the URL as the key. So your array might look like this:

<?php
      $_CATEGORIES['seo_url'] = array('id'=>$id,'title'=>$title,'image'=>$image);
?>

Using the URL as the key for the array allows us to access all of the information just by knowing the

<?php $_SERVER['REQUEST_URI']; ?>

. So how do we create a cache for all of the categories? Say we are using MySQL and the DB table name is categories.

<?php
       $cat_query = mysql_query("SELECT id,seo_url,title,image FROM categories");
       while($cat = mysql_fetch_assoc($cat_query))
       {
              $seo_url = stripslashes($cat['seo_url']);
              unset($cat['seo_url']);
              $_CATEGORIES[$seo_url] = $cat;
       }

       $f = fopen('cache/product_categories.php','w+');
       fwrite($f, '<?php'.chr(10).'$_CATEGORIES = '.var_export($_CATEGORIES, true).'?>');
       fclose($f);
?>

Of course this takes correct permissions and you will have to take security precautions that are out of the realm of this post but this is a simple example of making a flat cache file that will give you an easily accessible array of the categories. You see in the fwrite that it adds the open and close PHP tags and the chr(10) adds some line breaks so that the file is readable. You can then just have an include wherever you will need the product categories. I have used this in some systems that I have made and to make sure that it is always up to date the cache is updated anytime that there are changes to the categories table in the database.

To keep it up to date I created a function that does this for me so that I don’t have repeat code anywhere.  The function can be done like this:


<?php

function build_category_cache()
{
       $cat_query = mysql_query("SELECT id,seo_url,title,image FROM categories");
       while($cat = mysql_fetch_assoc($cat_query))
       {
              $seo_url = stripslashes($cat['seo_url']);
              unset($cat['seo_url']);
              $_CATEGORIES[$seo_url] = $cat;
       }

       $f = fopen('cache/product_categories.php','w+');
       fwrite($f, '<?php'.chr(10).'$_CATEGORIES = '.var_export($_CATEGORIES, true).'?>');
       fclose($f);
}
?>

You see that basically all you need to do to turn code into a simple function is to add function the_function_name (){} around the code that you want to run. The open and close parenthesis in this case have nothing in them because the function is not returning anything because the purpose of the function is create a flat cache file. And to call the function from our category edit script simply do this.

<?php
      build_category_cache();
?>

Using flat files for including some content

This is handy for managing content of your site and is actually most likely similar to methods that WordPress, Drupal, or almost any other CMS probably uses. In this use of flat files you are basically just creating HTML files that can be used as includes or just stand alone pages. This is a method that can be used to help make your website more dynamic. Perhaps you have a front page that you want something to change with the seasons then you could name your cache files something like winter.html, fall.html, etc. and on the front end check the php date() and display the file appropriate to that date.

In this example lets just say that we have a MySQL database with a table named content. And in this one we are just creating cache files for the main content of each page. In the database “title” is a heading on the page which we will put in h2 tags and “content” is the main content going under it.

<?php
       $content_query = mysql_query("SELECT id,seo_url,title,content FROM content");
       while($c = mysql_fetch_assoc($content_query))
       {
              $seo_url = stripslashes($c['seo_url']);
              $output = '<h2>'.stripslashes($c['title']).'</h2>';
              $output .= '<p>'.stripslashes($c['content']).'</p>';

              $f = fopen('cache/'.$seo_url.'.html','w+');
              fwrite($f,$output);
              fclose($f);
       }
?>

You see here that we had to move the file management code into the while because we are going to be creating multiple cache files. There will be a cache file for each content page. Here is a simple example of how to use this on the front end.

With this you could run most content off of one file if you wanted to. You could use the index file below with a header similar to this:

header.php

<?php
	$uri = $_SERVER['REQUEST_URI'];
	$uri = explode('/',$uri);  // this will give you an array with all of the levels of the url
	$uri = array_filter($uri);  // this gets rid of empty/false/null/<0 values
	$levels = count($uri);  //this will count the number of levels which you will need in some cases

	$file = $uri[$levels].'.html';  //here you are checking to see if the file exists
	if(!file_exists($uri[$levels]))  //most likely you actually want to do more checking but this is a basic example
	{
		header('HTTP/1.1 301 Moved Permanently'); //301 is not necessary but there are times you will want to use it
		header('Location: /');
		exit;
	}
?>

index.php

<?php
       include('includes/header.php');
       include('cache/'.$file);
       include('includes/footer.php');
?>

With this sample you could have your site served up with just the index.php and of course your header/footer/and cached files. You just need a .htaccess file to make sure that all URL’s point to the index file. An entry like:

RewriteRule ^(.*)? index.php [NC,L]

In this example we have a header.php which will have all of our beginning html code as well as probably the navigation and anything at the top of the page that is static ac\ross all pages of our website. The footer is the same deal as the header. This is code that appears on most any page of the site. The reason for having the header and footer as include files instead of on each page is so that it can be edited in just one place instead of having to edit on every page.

Obviously this is assuming you have already gotten the URL and put it into the variable. With this you can server up multiple different content pages with the exact same PHP page dynamically. Any questions or comments let me know. If you would like more detail about this method or uses I can respond in comments or even in new blogs. I know this is a little more advanced and some of you might not know when or where you would even use anything like this so don’t be shy.

7 Written ArticlesWebsite

I am a web developer by trade but originally went to school for Information Technology - Network Engineering Technology at Purdue University. Getting into web development as a student web developer I developed a passion for it that left networking seem a bit boring. Even though I finished up my networking degree I stuck with web development lately I have been a WP7 advocate. My Blog.

8 Comments Best Comments First
  • louis

    Saturday, July 30th, 2011 22:54

    8

    i need help! storing data in flat file give me headeach! if someone can help me, ill be gratefull.please

    +1
  • Rahul

    Thursday, October 7th, 2010 17:09

    2

    Very useful indeed,,,Elaborate and can be understood without much strain…

    0
    • Brad

      Thursday, October 7th, 2010 17:42

      1

      Thank you. There is much more where that came from

      0
  • sekhoane

    Sunday, October 10th, 2010 18:28

    3

    trying it out , hopefully i am sure it works….thanx

    0
  • detj

    Friday, October 22nd, 2010 07:46

    4

    very helpful. I’ll try using this whenever I get a chance. Can u write more about how to use index.php to show static header/footer and serving different content. The code mainly I mean.

    0
  • Brett Widmann

    Thursday, January 27th, 2011 06:16

    6

    This worked so well! I really appreciate the great info.

    0
  • Vishal

    Thursday, November 11th, 2010 11:44

    5

    Brad, what if we end up with flat files that are huge, in hundreds of KBs or MBs… Wouldn’t including or requiring such files in our cms would require substantial amount of memory allocation for all those defined variables in those flat files? I don’t think this is a good idea… But I’d like to hear from you about this…

    0
    • Brad Billman

      Sunday, February 13th, 2011 19:41

      7

      Sorry for such a late reply but plain and simple, don’t use this method unless it will be helpful. If you are dealing with large enough amounts of data that it will slow performance then don’t use it. I have not done any benchmarks to try to do this but I simply only use the flat file for things that I know will have a limited number of items and will save on small JOIN statements typically.

      +1
  • louis

    Saturday, July 30th, 2011 22:54

    8

    i need help! storing data in flat file give me headeach! if someone can help me, ill be gratefull.please

    +1
  • Brett Widmann

    Thursday, January 27th, 2011 06:16

    6

    This worked so well! I really appreciate the great info.

    0
  • Vishal

    Thursday, November 11th, 2010 11:44

    5

    Brad, what if we end up with flat files that are huge, in hundreds of KBs or MBs… Wouldn’t including or requiring such files in our cms would require substantial amount of memory allocation for all those defined variables in those flat files? I don’t think this is a good idea… But I’d like to hear from you about this…

    0
    • Brad Billman

      Sunday, February 13th, 2011 19:41

      7

      Sorry for such a late reply but plain and simple, don’t use this method unless it will be helpful. If you are dealing with large enough amounts of data that it will slow performance then don’t use it. I have not done any benchmarks to try to do this but I simply only use the flat file for things that I know will have a limited number of items and will save on small JOIN statements typically.

      +1
  • detj

    Friday, October 22nd, 2010 07:46

    4

    very helpful. I’ll try using this whenever I get a chance. Can u write more about how to use index.php to show static header/footer and serving different content. The code mainly I mean.

    0
  • sekhoane

    Sunday, October 10th, 2010 18:28

    3

    trying it out , hopefully i am sure it works….thanx

    0
  • Rahul

    Thursday, October 7th, 2010 17:09

    2

    Very useful indeed,,,Elaborate and can be understood without much strain…

    0
    • Brad

      Thursday, October 7th, 2010 17:42

      1

      Thank you. There is much more where that came from

      0

Comments are closed.

54.161.147.106 - unknown - unknown - US