[PHP] Googleサイトマップを作成するClass(PC,モバイル対応)

(※2009/07/23 22:24 gzip圧縮対応のためのコードを追加しました)

PHPでサイトマップを作成するclassを作りました。
Googleサイトマップです。
PC版、モバイル版、どちらも対応しています。

気合入れて作ったので、コメントもバッチシ、ここであーだこーだ言うよりも、ソース読んだほうが早いかも。
コメントに出力例もコード例も書いているし・・・。

サイトマップインデックスファイルを作るので、Googleさんに登録するサイトマップURLは1つだけでOKです。
登録URLがどんなに増えても、PCとモバイルと混ざってても、Googleさんに登録するサイトマップURLは1つだけでOKです。

デフォルトでは、/sitemap.xml がサイトマップインデックスファイルです。
これをGoogleさんに登録するだけでOKです。
(gzipしてたら、/sitemap.xml.gz です)

サイトマップで作成されるファイル(デフォルト)

document root
  ∟ sitemap.xml  ← サイトマップインデックス
  ∟ sitemap
      ∟ p  ← PC用サイトマップを格納
        ∟ sm1.xml
        ∟ sm2.xml
      ∟ m  ← モバイル用サイトマップを格納
        ∟ sm1.xml
        ∟ sm2.xml
※zgipを有効にした場合は、ファイル名の末尾に .gz の拡張子が付きます。

サイトマップを作成するコード例

<?php
// new してセット
$Sitemap = new Aulta_Sitemap();
$Sitemap->setIsGzip(true);
$Sitemap->setUrlRoot('http://example.com/');
$Sitemap->setPathDocumentRoot('/www/public_html/');
// $Sitemap->setDirNameSitemap('sitemap'); // デフォルト値あり
// $Sitemap->setFileNameSitemapIndex('sitemap.xml'); // デフォルト値あり

// PC用URLを add する
// 必要数だけ、ひたすら add します。
$array = array(
'loc' => 'http://example.com/'
, 'priority' => '1.0'
);
$Sitemap->addSitemapDataPc($array);

// モバイル用URLを add する
// 必要数だけ、ひたすら add します。
$Sitemap->addSitemapDataMobile('http://example.com/m/');

// 出力
$Sitemap->createSitemaps();

PHPサイトマップ作成Classの注意点

レンタルサーバなどではパーミッションの都合でPHPからファイルやディレクトリの作成ができないかもしれません。
その場合は、手動にて、仮のファイルとディレクトリを作成し、パーミッションを変更しておいてください。

PHPのサイトマップ作成Class

次のコードを、【UTF-8】で、【sitemap.php】とでも保存して使ってください。
一部、setterかconstか迷って、constにした箇所があるので、適当に変えてください。

<?php
/*********************************************************
* Copyright (C) 2007 - 2009
* app name : Aulta framework
* author : aulta
* url : http://aulta.net/
* update : 2009/07/23
*
* このファイルの使用条件
* 上部、Copyright部の維持だけお願いします。
* 改変、再配布は自由で無料です。
*********************************************************/
/*
* 【Googleサイトマップを作成】
*
* 作成されたサイトマップインデックスのURLをGoogleに登録してください。
*
*
* 出力例(デフォルトで出力した場合)
* document root
* ∟ sitemap.xml ← サイトマップインデックス
* ∟ sitemap
* ∟ p ← PC用サイトマップを格納
* ∟ sm1.xml
* ∟ sm2.xml
* ∟ m ← モバイル用サイトマップを格納
* ∟ sm1.xml
* ∟ sm2.xml
*
*
* コード例
$Sitemap->setIsGzip(true);
$Sitemap = new Aulta_Sitemap();
$Sitemap->setUrlRoot('http://example.com/');
$Sitemap->setPathDocumentRoot('/www/public_html/');
$Sitemap->setDirNameSitemap('sitemap');
$Sitemap->setFileNameSitemapIndex('sitemap.xml');

// PC用URLを add する
// 必要数だけ、ひたすら add します。
$array = array(
'loc' => 'http://example.com/'
, 'priority' => '1.0'
);
$Sitemap->addSitemapDataPc($array);

// モバイル用URLを add する
$Sitemap->addSitemapDataMobile('http://example.com/m/');

// 出力
$Sitemap->createSitemaps();

*/
class Aulta_Sitemap{

// サイトマップ 1ファイルに収めるURL数
const cc_sitemap_file_counts = 1000;

// PC用サイトマップを格納するディレクトリ名
const cc_sitemap_dir_name_pc = 'p';

// モバイル用サイトマップを格納するディレクトリ名
const cc_sitemap_dir_name_mobile = 'm';

// 改行コード
const cc_lf = "n";

// 下記の説明はsetterにて
private $_IsGzip = false;
private $_UrlRoot = 'http://example.com/';
private $_PathDocumentRoot = '/www/public_html/';
private $_DirNameSitemap = 'sitemap';
private $_FileNameSitemapIndex = 'sitemap.xml';

// データ格納用
private $_SitemapListPc = array();
private $_SitemapListMobile = array();
private $_SitemapIndexList = array();

/**
* コンストラクタ
*/
public function __construct(){
}

/**
* 出力ファイルをgzip圧縮する。
* 出力ファイル名の末尾に拡張子(.gz)が付きます。
* 引数 : true | false
*/
public function setIsGzip($val){
$this->_IsGzip = $val;
}

/**
* URLのルートをセットします。
* 末尾の / を忘れないでください。
*/
public function setUrlRoot($val){
$this->_UrlRoot = $val;
}

/**
* ドキュメントルートをフルパスでセットします。
* 末尾の / を忘れないでください。
* setUrlRoot()と同一ディレクトリを指定してください。
*/
public function setPathDocumentRoot($val){
$this->_PathDocumentRoot = $val;
}

/**
* サイトマップを格納するディレクトリ名をセットします。
* $this->_UrlRoot . $this->_DirNameSitemap
* 出力時に↑のディレクトリが自動生成されます。
*/
public function setDirNameSitemap($val){
$this->_DirNameSitemap = $val;
}

/**
* サイトマップインデックスのファイル名を指定します。
* $this->_UrlRoot . $this->_FileNameSitemapIndex
* 出力時に、↑のファイルが自動生成されます。
* Googleへ登録するサイトマップURLがこれにあたります。
*/
public function setFileNameSitemapIndex($val){
$this->_FileNameSitemapIndex = $val;
}

/**
* PC用のサイトマップデータを追加します。
* (例)
* $sitemap->addSitemapDataPc(
* array(
* 'loc' => 'http://example.com/index.html'
* , 'priority' => '1.0'
* )
* );
*/
public function addSitemapDataPc(&$array){
$index = count($this->_SitemapListPc);
if ($index == 0){
$this->_SitemapListPc[$index] = array();
} else {
$index--;
$count = count($this->_SitemapListPc[$index]);
if ($count >= self::cc_sitemap_file_counts){
$index++;
$this->_SitemapListPc[$index] = array();
}
}
array_push($this->_SitemapListPc[$index], $array);
}

/**
* モバイル用のサイトマップデータを追加します。
* (例)
* $sitemap->addSitemapDataMobile('http://example.com/index.html');
*/
public function addSitemapDataMobile($loc){
$index = count($this->_SitemapListMobile);
if ($index == 0){
$this->_SitemapListMobile[$index] = array();
} else {
$index--;
$count = count($this->_SitemapListMobile[$index]);
if ($count >= self::cc_sitemap_file_counts){
$index++;
$this->_SitemapListMobile[$index] = array();
}
}
array_push($this->_SitemapListMobile[$index], $loc);
}

/**
* サイトマップを作成
*/
public function createSitemaps(){
// サイトマップ出力フォルダ
$pathSitemap = $this->_PathDocumentRoot . $this->_DirNameSitemap;
$pathSitemap .= (substr($pathSitemap, strlen($pathSitemap) - 1) == '/' ? '' : '/');
// フォルダの確認と作成
if ( ! file_exists($pathSitemap)) mkdir($pathSitemap);
chmod($pathSitemap, 0777);
// サイトマップ作成
$this->createSitemapPc($pathSitemap);
$this->createSitemapMobile($pathSitemap);
$this->createSitemapIndex();
}

/**
* PCサイトマップ作成
*/
private function createSitemapPc($pathSitemap){
$pathSitemapPc = $pathSitemap . self::cc_sitemap_dir_name_pc . '/';
// フォルダの確認と作成
if ( ! file_exists($pathSitemapPc)) mkdir($pathSitemapPc);
chmod($pathSitemapPc, 0777);
// PCサイトマップを出力
$fileNo = 1;
foreach ($this->_SitemapListPc as &$list){
$filename = self::cc_sitemap_dir_name_pc . '/sm' . $fileNo . '.xml';
if ($this->_IsGzip) $filename .= '.gz';
$this->createSitemasChildPc($pathSitemap . $filename, $list);
$fileNo++;
$this->addSitemapIndex($filename);
}
}

/**
* モバイルサイトマップ作成
*/
private function createSitemapMobile($pathSitemap){
$pathSitemapMobile = $pathSitemap . self::cc_sitemap_dir_name_mobile . '/';
// フォルダの確認と作成
if ( ! file_exists($pathSitemapMobile)) mkdir($pathSitemapMobile);
chmod($pathSitemapMobile, 0777);
// モバイルサイトマップを出力
$fileNo = 1;
foreach ($this->_SitemapListMobile as &$list){
$filename = self::cc_sitemap_dir_name_mobile . '/sm' . $fileNo . '.xml';
if ($this->_IsGzip) $filename .= '.gz';
$this->createSitemasChildMobile($pathSitemap . $filename, $list);
$fileNo++;
$this->addSitemapIndex($filename);
}
}

/**
* PCサイトマップを作成して保存
*/
private function createSitemasChildPc($filepath, &$list){
$map = '';
foreach ( $list as &$value ) {
$map .= '<url>'
. '<loc>' . $value['loc'] . '</loc>'
. '<priority>' . $value['priority'] . '</priority>'
. '</url>' . self::cc_lf;
}
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . self::cc_lf
. '<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">' . self::cc_lf
. $map
. '</urlset>' . self::cc_lf;
$this->saveFile($filepath, $xml);
}

/**
* モバイルサイトマップを作成して保存
*/
private function createSitemasChildMobile($filepath, &$list){
$map = '';
foreach ( $list as &$value ) {
$map .= '<url>'
. '<loc>' . $value . '</loc><mobile:mobile/>'
. '</url>' . self::cc_lf;
}
$xml = '<?xml version="1.0" encoding="UTF-8" ?>' . self::cc_lf
. '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'
. ' xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0">' . self::cc_lf
. $map
. '</urlset>' . self::cc_lf;
$this->saveFile($filepath, $xml);
}

/**
* サイトマップインデックスに追加
*/
private function addSitemapIndex(&$filename){
array_push($this->_SitemapIndexList, $filename);
}

/**
* サイトマップインデックスを作成
*/
private function createSitemapIndex(){
$urlSitemap = $this->_UrlRoot . $this->_DirNameSitemap;
if (substr($urlSitemap, strlen($urlSitemap) - 1) != '/'){
$urlSitemap .= '/';
}
$maps = '';
foreach ( $this->_SitemapIndexList as &$filename ) {
$maps .= '<sitemap>'
. '<loc>' . $urlSitemap . $filename . '</loc>'
. '<lastmod>' . date('Y-m-d') . '</lastmod>'
. '</sitemap>' . self::cc_lf;
}
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . self::cc_lf
. '<sitemapindex xmlns="http://www.google.com/schemas/sitemap/0.84">' . self::cc_lf
. $maps
. '</sitemapindex>' . self::cc_lf
;
$filepath = $this->_PathDocumentRoot . $this->_FileNameSitemapIndex;
if ($this->_IsGzip) $filepath .= '.gz';
$this->saveFile($filepath, $xml);
}

/**
* 保存する
*/
private function saveFile(&$filepath, &$data){
if ($this->_IsGzip){
$gz = gzopen($filepath, 'w9');
gzwrite($gz, $data);
gzclose($gz);
} else {
file_put_contents($filepath, $data);
}
}
}