Auto-generated cache.manifest in PHP

If you don’t want to read the entire entry, you can get the code (and propose changes, of course) in github:

A very interesting thing in HTML5 is the possibility of create offline applications or web pages through the cache.manifest file. This pages can be read by the user when he don’t have an Internet connection, that today, with the poor mobile network coverage in some places, is something usual. It’s also a good idea also with good connections because the user don’t have to download all the data and the page load will be faster.

So, yes, really interesting, but if you have tried to create a cache.manifest by your own it takes time and effort, because you have to update it every time you add or change a file in your web or app.

For this reason I’ve look for an easy, or better, automatic, way to generate this file and I’ve found that is really easy with PHP (sure that it is also with other server side languages).

Take a look at the code to see how easy it is:

I think it need no much explanation but:

– First we declare that the file is a cache.manifest and write “CACHE MANIFEST” in the first line:

– Almost everything is done in the function “create_manifest” that iterate through all the files/folders of the folder defined in the variable $folder.
Inside the function we create an array, $dir, that contains all the files/folders, thanks to the class “RecursiveDirectoryIterator“. We “foreach” this array and get the path of every file with “pathinfo“.
Then, if the object is a file (not a folder) and it’s not called manifest.php (because if you caches your manifest file you’re gonna have a bad time), and it’s not a “dotfile”, we print it into the page, replacing spaces with %20 (in theory that’s not necessary, because you have create your URLs and files in a proper way 🙂 ).
Finally, we add the md5 hash of the file into the $hashes variable (I will explain that later)

– It rest to call the function in the folder whose files we want to add into the cache.manifest file. We can add a point(.) if we want to include all.

– Finally, if we change the content of a file without changing his name (we update an image for example) the browser don’t know if the file has changed and it going to use the cached version of the file. But if the cache.manifest has changed he is going to download again all the files.
Printing the $hashes variable (that is different every time a file change) we make sure that the browser going to download all the files if we change anything.

And that’s it. Only rest add it into our web page after the doctype declaration:

We have an auto-generated cache.manifest file that we don’t need to update every time 🙂

It’s works, for example, in the Revista Exégesis tablet version:

Go to the Homepage → ← Go back



  1. max says:

    Hi. Thanks a lot for this awesome script. How can i change the name of the file which created to offline.appcache add a random version number? The web app can not be used offline, because every time i open the index.html the manifest.php starts and every file is not up date date. So it would be cool if i can open a url like and the file offline.appcache is generated newly with all files (as well as the new ones on the server) thanks a lot

    • admin says:

      Hi max

      if I have understood correctly you want to generate the file “offline.appcache” with a php script.

      Usinr the same script at the beginning of the page:

      – First remove the line that define the ‘Content-Type’:

      header(‘Content-Type: text/cache-manifest’);

      – define the variable $data in top of the script:

      $data = ”;

      – In the script, change the “echo” parts to save this data into a variable ‘$data’ intead of printing them: Replace ‘echo’ for ‘$data .=’

      – And finally create a file with the content of ‘$data’:

      // Give a name to your file, you can add here a random number or something like that if you want
      $my_file = ‘offline.appcache’;
      // prepare the file to be opened
      $handle = fopen($my_file, ‘w’) or die(‘Cannot open file: ‘.$my_file);
      // write data into the file
      fwrite($handle, $data);
      // close the file

      I didn’t test it, but it must generate the “offline.appcache” file in the same folder that you have the php script.

      Hope it helps 🙂

      • admin says:

        Another (very important!) thing, be careful to not include the ‘offline.appcache’ in the generated file.

        Change the line:

        if ($file -> IsFile() && $file != “./manifest.php” && substr($file -> getFilename(), 0, 1) != “.”) {

        by something like (with the correct name that you put to the file):

        if ($file -> IsFile() && $file != “./offline.appcache” && substr($file -> getFilename(), 0, 1) != “.”) {

  2. Jared says:

    Very useful, thanks! Maybe for a follow up or a quick note on this article you could suggest how to make the server use php to compile .appcache files.

  3. Frank says:

    Although it is quite a few months old, I just found this post and it is exactly what I am looking for. My app adds an updated file 3 times a week and my manifest had to be updated manually.
    All I now have to do is add the updated file to the folder with all others that I want cached and this script grabs it and does the update.
    Thank you very much.

  4. matthias says:

    this is great stuff! But is there a way this can cache query strings as well like here :
    ./css/site_global.css?426517801. it will only cache this: ./css/site_global.css.
    adding them manually is too much work. Thanks for help

  5. soren says:

    Hi first of all thanks for the script, though while i’m running it it stops at a certain point and then I get the following error:

    Application Cache Error event: Resource fetch failed (404) http://localhost/Devine/20142015/RMDII/opdracht/2DEV2_selleslaghSoren_RMD2_inspiration/code/%3Cbr

    Do you have any idea what the problem could be? Thanks!

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.