Skip to content

Instantly share code, notes, and snippets.

@zollinger
Created December 5, 2012 12:01
Show Gist options
  • Save zollinger/4215002 to your computer and use it in GitHub Desktop.
Save zollinger/4215002 to your computer and use it in GitHub Desktop.
Google Sitemap with PHP
<?php
class Sitemap {
/**
* Maximum size of a single sitemap file.
* Defaults to 9MB
*/
public $maxFileSize = 9437184;
/**
* File header for each generated file
*/
public $fileHeader = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">';
/**
* File footer appended to each file
*/
public $fileFooter = '</urlset>';
/**
* File name
*/
public $fileName = 'sitemap-%s.xml';
/**
* Current file pointer
*/
protected $fp;
/**
* Current file number
*/
protected $fileNumber = 0;
/**
* DB handle
*/
protected $db;
/**
* Constructor, takes array with mysql connection as argument
*
* @param $mysqlData array See connectDB() for reference
*/
public function __construct($mysqlData) {
$this->connectDB($mysqlData);
}
/**
* Connects to database with provides connection data
*
* @param $mysqlData array Array of format array('host'=>'..', 'user'=>'..', 'password'=>'..', 'database'=>'..')
*/
protected function connectDB($mysqlData) {
extract($mysqlData);
$this->db = new mysqli($host, $user, $password, $database);
}
/**
* Starts writing a new xml file including header. Closes the previous file if any.
*
* @return int Bytes written to new file
*/
public function newFile() {
// Close last file if we have one
if (isset($this->fp)) {
$this->closeFile();
}
$this->fileNumber++;
$this->fp = fopen(sprintf($this->fileName, $this->fileNumber), 'w');
return $this->write($this->fileHeader);
}
/**
* Writes xml footer and closes current file
*
* @return void
*/
public function closeFile() {
$this->write($this->fileFooter);
fclose($this->fp);
}
/**
* Generates sitemap.xml files using provides queries and the row template
*
* @param array Array of SQL queries, results are applied to template
* @param string Documentation see method $this->format()
*
* @return void
*/
public function generateFromQueries($queries, $template){
$fileSize = $this->newFile();
foreach($queries as $query) {
$result = $this->db->query($query);
while ($row = $result->fetch_assoc() ){
$fileSize += $this->write($this->format($template, $row));
// Check if we already got max file size and need to start an new file
if($fileSize > $this->maxFileSize) {
$fileSize = $this->newFile();
}
}
}
$this->closeFile();
}
/**
* Writes some $data to current open file
*
* @param string $data Data to be written
*
* @return int Bytes written
*/
public function write($data){
return fwrite($this->fp, $data);
}
/**
* Formats a template $template with variables from $data
*
* @param string $template Template string of format "{var1} some text {var2}"
* @param array Variables to apply to template
*
* @return string Formatted string
*/
public function format($template, $data){
foreach ($data as $placeholder=>$value) {
$template = str_replace('{'.$placeholder.'}', $value, $template);
}
return $template;
}
}
function generateInfocubeMap() {
$s = new Sitemap(array(
'host'=>'localhost',
'user'=>'user',
'password' => '',
'database'=>'infocube_data'
));
$queries = array(
"select id, urlizedname, 'p' as t from person where status='active'",
"select id, urlizedname, 'c' as t from company",
);
$template = "<url><loc>http://infocube.ch/de/{t}/{id}/{urlizedname}</loc>
<xhtml:link rel=\"alternate\" hreflang=\"en\" href=\"http://infocube.ch/en/{t}/{id}/{urlizedname}\" />
<xhtml:link rel=\"alternate\" hreflang=\"fr\" href=\"http://infocube.ch/fr/{t}/{id}/{urlizedname}\" />
<xhtml:link rel=\"alternate\" hreflang=\"it\" href=\"http://infocube.ch/it/{t}/{id}/{urlizedname}\" />
<xhtml:link rel=\"alternate\" hreflang=\"de\" media=\"only screen and (max-width: 640px)\" href=\"http://m.infocube.ch/de/{t}/{id}/{urlizedname}\" />
<xhtml:link rel=\"alternate\" hreflang=\"en\" media=\"only screen and (max-width: 640px)\" href=\"http://m.infocube.ch/en/{t}/{id}/{urlizedname}\" />
<xhtml:link rel=\"alternate\" hreflang=\"fr\" media=\"only screen and (max-width: 640px)\" href=\"http://m.infocube.ch/fr/{t}/{id}/{urlizedname}\" />
<xhtml:link rel=\"alternate\" hreflang=\"it\" media=\"only screen and (max-width: 640px)\" href=\"http://m.infocube.ch/it/{t}/{id}/{urlizedname}\" />
</url>";
$s->generateFromQueries($queries, $template);
}
generateInfocubeMap();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment