Dynamic sitemap with PHP

I needed to create a sitemap for my blog. Upon googling I learned that every single blog post I make needs to be in that sitemap, so I took my Archive page, which basically lists all my blog posts and modified it a little:

<?phpinclude 'lib/getPostData.php';header('Content-type: text/xml');echo '<?xml version="1.0" encoding="utf-8"?>';echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';    $dir = 'posts/';    $content = array_diff(scandir($dir), array('..', '.', '.htaccess'));    natcasesort($content); // Sort content    foreach (array_reverse($content) as $c) {        $number = preg_split("/[\s,.]+/", $c);        $path = $dir . $c;        echo '<url><loc>' . getPostData($path, "link") . '</loc></url>';    }    echo '<url><loc>http://lambdan.se</loc></url>';    echo '</urlset>';?>

Ofcourse, depending on how your blog works it will be different. For mine I have a getPostData.php which you could say is the core of my blog. It allows me to get links, content, teasers, images, etc. from my Markdown files.

Anyway, the principle is:

  • Set header to Content-type: text/xml
  • Echo out XML version
  • Echo out urlset xmlns
  • loop over all blog posts and make them echo out <url><loc>http://URL</loc></url>.
  • At the bottom you can add any additional 's you want that might be static
  • Finally echo out </urlset>

Save it as sitemap.php. Now you need to modify your .htaccess, to add a RewriteRule that will make /sitemap.xml into /sitemap.php:

RewriteRule ^sitemap\.xml sitemap.php

And done! You can see my sitemap by going to http://lambdan.se/sitemap.xml

Update

Upon posting this post I noticed that I got redirected to my sitemap.xml for some reason when I clicked the permalink to this post. The original title of the post was "Dynamic sitemap.xml with PHP", so I removed the .xml part and now it works. You can still see the same bug by going to something like: http://lambdan.se/94/random-string-sitemap-xml

I guess the sitemap rewriterule gets triggered on sitemap-xml too.

Update 2

Thanks to help from Twitter the above issue was fixed and I updated the RewriteRule in the guide accordingly.