[PHP]サイトマップ(sitemap.xml)を動的に生成する

検索エンジンにウェブページの存在を知らせるためにXML形式のサイトマップを作るのは一般的ですが、サイトを更新するたびにサイトマップを手書きするのは大変です。

そこで PHP を使って sitemap.xml を作成するためのクラスを作ってみることにしました。

・sitemap_generator.php

<?php
class SitemapGenerator{
    private $sitemap;
    private $urlset = array();
     
    function __construct(){
        $this->sitemap = new DOMDocument('1.0', 'UTF-8');
        $this->sitemap->preserveWhiteSpace = false;
        $this->sitemap->formatOutput = true;
         
        $this->urlset = $this->sitemap->appendChild( $this->sitemap->createElement("urlset") );
        $this->urlset->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
    }
     
    function add($params){
        $url = $this->urlset->appendChild( $this->sitemap->createElement('url') );
        foreach($params as $key => $value){
            if(strlen($value)){
                $url->appendChild( $this->sitemap->createElement($key, $value) );
            }
        }
    }
     
    function generate($file=null){
        if( is_null($file) ) {
            header("Content-Type: text/xml; charset=utf-8");
            echo $this->sitemap->saveXML();
        } else {
            $this->sitemap->save( $file );
        }
    }
}

使用例

<?php
include_once "sitemap_generator.php";

$sitemap = new SitemapGenerator();

$sitemap->add([
	'loc'        => 'https://php-archive.net/',
	'lastmod'    => '2013-05-23',
	'changefreq' => 'daily',
	'priority'   => '1.0'
]);

$sitemap->add([
	'loc'        => 'https://php-archive.net/category/php/',
	'lastmod'    => date('c'),
	'changefreq' => 'monthly',
	'priority'   => '0.5'
]);

$sitemap->generate();

・実行結果

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://php-archive.net/</loc>
    <lastmod>2013-05-23</lastmod>
    <changefreq>daily</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://php-archive.net/category/php/</loc>
    <lastmod>2013-05-23T09:01:58+02:00</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

ページごとの url 要素を配列として add() に渡すと追加されます。
generate() で XML として表示されます。
また、generate() の引数にファイルパスを渡せばファイルとして保存されます。

WordPress の記事を元にサイトマップを独自生成する方法 も公開しました。
興味のある方はそちらもご覧ください。


サイトマップの構造

サイトマップは個々のページの情報を記した複数の「url」要素と、それらを束ねる「urlset」要素でできています。

<urlset>
  <url> ~ </url>
  <url> ~ </url>
  <url> ~ </url>
</urlset>

「url」要素内には、
・loc (ページのURL)
・lastmod (最終更新日)
・changefreq (更新頻度)
・priority (優先度)
などの要素があり、「loc」以外は必須ではありません。

更新日は「YYYY-MM-DD」で表すか、W3C Datetime 形式(ISO 8601)で表します。
PHP 5 以上であれば date(“c”) を使えば簡単に得られます。

更新頻度は次の値を使うことができます。
“always”, “hourly”, “daily”, “weekly”, “monthly”, “yearly”, “never”

「always」はアクセスする度に変化のあるページで、「never」は更新されることのないページです。
更新頻度はあくまで参考程度のものであり、ここで「hourly」を指定したからといって検索エンジンのクローラーが一時間おきにチェックしに来てくれるとは限りません。

「priority」は優先度に合わせて 0.0 ~ 1.0 の数値で指定します。
デフォルトは 0.5 で、優先度の高いものを大きな数値で表します。
これは相対的なものであり、全てのページに 1.0 を指定しても「全て同じ優先度」であることを意味するだけで、「1.0 = 重要なページ」であることを意味するわけではありません。

サイトマップ構造の詳細については下記URLを御覧下さい
http://www.sitemaps.org/ja/protocol.html

[PHP]GDを使ってグラデーション画像をつくる

PHP の GD を使ってグラデーションを描画するサンプルです。

256階調を最大とし、開始色と終了色のミックス量を決めて混色するシンプルな仕組みです。
太さ 1px の線状にグラデーションを作り、 imagecopyresampled() を使って引き伸ばすことで高速化を図っています。

<?php
//キャンバスサイズ
$width   = 300;
$height  = 200;
 
//開始色
$start_r = 255;
$start_g = 255;
$start_b = 0;
 
//終了色
$end_r = 0;
$end_g = 255;
$end_b = 255;

//方向("vertical" 又は "horizontal")
$direction = "vertical";

$image = imagecreatetruecolor($width, $height);

if($direction === "horizontal"){
	$grad_w = 256;
	$grad_h = 1;
} else if($direction === "vertical"){
	$grad_w = 1;
	$grad_h = 256;
}
$gradient = imagecreatetruecolor( $grad_w, $grad_h);	
	
for($i=0;$i<=255;$i++){

	$mix = $i / 255;

	$current_r = $start_r * (1 - $mix) + $end_r * $mix;
	$current_g = $start_g * (1 - $mix) + $end_g * $mix;
	$current_b = $start_b * (1 - $mix) + $end_b * $mix;

	$color = imagecolorallocate($gradient, $current_r, $current_g, $current_b);

	if($direction === "horizontal"){
		imagesetpixel($gradient, $i, 0, $color);
	} else if($direction === "vertical"){
		imagesetpixel($gradient, 0, $i, $color);
	}
}

imagecopyresampled($image, $gradient, 0, 0, 0, 0, $width, $height, $grad_w, $grad_h);

header("Content-type: image/jpeg");
imagejpeg($image);
imagedestroy($image);
imagedestroy($gradient);

grad_h
水平方向

grad_v
垂直方向

グラデーションの開始と終了を RGB 値(それぞれ0~255)で指定します。
グラデーションの方向は垂直(vertical)と水平(horizontal)が選べます。

[PHP]数値を一定の範囲に収める(上限・下限値で丸める)

ある数字を 100 以上 300 以下に制限し、超えた場合はその範囲内に丸めるといった処理をする場合、条件分岐を使えば一応出来ますが、 min() と max() を組み合わせれば一行で書くことができます。

<?php
$value	 = 500;

$low	 = 100;
$high	 = 300;

$value = min( max($value, $low), $high);

echo value;

[結果]

300

そのまま使うとちょっと気持ち悪いので関数化して使ったほうがわかりやすいかもしれません。