<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>XMLサイトマップ生成PHPプログラム</title>
<meta name="robots" content="NOINDEX,NOFOLLOW">
<!-- Free Icon Fonts の読み込み - 使用しなければ削除可 -->
<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet">
</head>
<body>
<h2> <i class="fa-regular fa-pen-to-square fa-2x" style="color: crimson"></i> XMLサイトマップの作成</h2>
<hr>
<div style="margin:15px 5px 10px 20px;padding: 0 15px 0 0; font-size: 14px;background-color: lavenderblush; border: gray 1px solid; border-radius: 4px;">
<div style="margin:15px 0 0 20px">
<form method="post">
<input type="submit" name="downloadLocal" value="XML ファイルをローカルにダウンロード" style="background-color: white;border-radius: 5px;cursor: pointer;">
</form>
</div>
<ul>
<li>ここからダウンロードした XML ファイルには、ページの HTML 部の一部が含まれます。</li>
<li>参考としてご覧いただき、純粋な XML ファイルが必要な場合はリモートサーバーからダウンロードしてください。もしくは、ダウンロードしたファイルの HTML 部を削除してください。「<?xml version="1.0" encoding="UTF-8"?>」から「</urlset>」までが XML ファイルです。</li>
</ul>
</div>
<hr>
<?php
//************************************************
// XMLサイトマップ生成PHPプログラム
// プログラム提供:みんなの知識 ちょっと便利帳
// https://www.benricho.org/Tips/sitemapgenerator/
// Released: January 3, 2024
//************************************************
// ウェブサーバーのドキュメントルート。自動取得
$sitemapDirectory = $_SERVER['DOCUMENT_ROOT'];
// .xmlファイルの名称(最終的なファイル名)
// .xmlファイルの名称は変えることも可能。ただし、多くの検索エンジンが「sitemap.xml」を標準的な命名規則としており、「sitemap.xml」を使用することが推奨される
$finalSitemapFilename = 'sitemap.xml';
// サイトマップファイルの保存先(最終的なディレクトリ - ルート)
$finalSitemapPath = $sitemapDirectory . '/' . $finalSitemapFilename;
// サイトマップ生成の対象ディレクトリ
$rootDirectory = $_SERVER['DOCUMENT_ROOT'];
// .xmlファイルの名称(一時的なファイル名)
$tempSitemapFilename = 'temporarysitemap.xml';
// サイトマップファイルの保存先(一時的なディレクトリ)
$tempSitemapPath = $sitemapDirectory . '/' . $tempSitemapFilename;
// 一時的なディレクトリが存在しない場合は作成する
$tempDirectory = dirname($tempSitemapPath);
if (!file_exists($tempDirectory)) {
mkdir($tempDirectory, 0777, true);
}
// 旧サイトマップを削除し、新サイトマップにリネームする(シェルコマンドを使用)
$oldSitemapFilename = 'old-' . $finalSitemapFilename;
$oldSitemapPath = $sitemapDirectory . '/' . $oldSitemapFilename;
// 旧サイトマップが存在する場合は削除
if (file_exists($oldSitemapPath)) {
unlink($oldSitemapPath);
}
// 新サイトマップにリネーム
if (file_exists($tempSitemapPath)) {
rename($tempSitemapPath, $oldSitemapPath);
}
// ダウンロードボタンがクリックされたかどうかを確認
if (isset($_POST['downloadLocal'])) {
// サイトマップを一時ディレクトリにコピー
copy($finalSitemapPath, $tempSitemapPath);
// ダウンロード用のヘッダーを設定
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $finalSitemapFilename . '"');
header('Content-Length: ' . filesize($tempSitemapPath));
// ファイルを出力
readfile($tempSitemapPath);
// ダウンロード後、一時ディレクトリに保存したサイトマップを削除
unlink($tempSitemapPath);
exit;
}
///// 除外対象の設定 /////
// 除外するディレクトリ。除外するディレクトリ名のみを指定。['dir-1', 'dir2'] など
// 必要がなければ空に。[];
$excludeDirectories = [];
// 除外するファイル。ファイル名のみを指定。['aaa.html', 'bbb.php'] など
// 必要がなければ空に。[];
$excludeFiles = [];
// 除外するディレクトリ/ファイル ['dir-1/dir1/file1.html', 'dir2/file2.php'] など
// 除外パスには先頭に「/」は入れない
// 必要がなければ空に。[];
$excludePaths = [];
// メタタグの ['NOINDEX', 'NOFOLLOW', 'REFRESH'] などが入ったファイルを除外
// 必要がなければ空に。[];
// ['NOINDEX'] の指定をおすすめします
$excludeMetaTags = ['NOINDEX'];
///// サイトマップ生成の条件 /////
// ページタイトルを取得(1:取得する、2:取得しない)
// ※ Google Search Console では非推奨
// ※[重要] Google Search Console に登録する場合は、「2:取得しない」にする
// ※「1:取得する」にすると、Google Search Console では『titleタグが認識されない。修正を』とのアラートが表示される
$getTitle = 2;
// ページタイトルから削除する文字列を指定
// ※指定した文字をタイトルから削除することができる。['の', 'です'] など
// 必要がなければ空に。[];
$removeTitleStrings = [];
// ファイルの最終更新日を取得(1:取得する、2:取得しない)
// ※ Google Search Console では推奨
$getLastMod = 1;
// ページ更新頻度
// ※ Googleでは無視・非推奨。『値を追加しないでください』とされている
// ページ更新頻度を使用(1:使用する、2:使用しない)
$useChangeFreq = 2;
// 更新頻度の要素選択
// 「1」にした場合はページ更新頻度の要素を選択。['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never']
// 要素 always:アクセスするたびに更新、hourly:1時間更新、daily:毎日更新、weekly:毎週更新、monthly:毎月更新、yearly:毎年更新、never:更新しない
$changefreqValues = ['サイトの更新頻度に適用される値を選択・記入'];
// ページ優先度
// ※ Googleでは無視・非推奨。『値を追加しないでください』とされている
// priorityを取得(1:取得する、2:取得しない)
$getPriority = 2;
// サイトマップ生成文言
$successMessage = "<p>・ サイトマップXMLファイルが生成されました。<br>・ Sitemap XML file has been generated.</p><p>・「{$finalSitemapFilename}」として、リモートサーバーのルートに保存されました。<br>・ セキュリティ対策上、プログラムファイルをリモートサーバーから削除してください。</p><p>・<a href='/{$finalSitemapFilename}' target='_blank'>「XMLファイル」をブラウザで開く[別タブ]</a></p>";
// サイトマップXMLヘッダ(最終的なファイル用)
$xmlFinal = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
XML;
// 再帰的にディレクトリ内のファイルを処理(最終的なファイル用)
function generateSitemap($directory, $excludeDirs, $excludeFiles, $getTitle, $removeTitleStrings, $getLastMod, $excludeMetaTags, $useChangeFreq, $changefreqValues, $getPriority, $excludePaths, &$xmlFinal) {
$dir = new DirectoryIterator($directory);
foreach ($dir as $fileInfo) {
if ($fileInfo->isDot()) continue;
$filename = $fileInfo->getFilename();
$filepath = $fileInfo->getPathname();
$fileExtension = pathinfo($filename, PATHINFO_EXTENSION);
// 除外対象のディレクトリ/ファイルかどうか確認
$excludePath = str_replace($_SERVER['DOCUMENT_ROOT'], '', $filepath);
if (in_array(ltrim($excludePath, '/'), $excludePaths)) {
continue;
}
if ($fileInfo->isDir()) {
if (in_array($filename, $excludeDirs)) {
continue;
} else {
generateSitemap($filepath, $excludeDirs, $excludeFiles, $getTitle, $removeTitleStrings, $getLastMod, $excludeMetaTags, $useChangeFreq, $changefreqValues, $getPriority, $excludePaths, $xmlFinal);
}
} else {
if (in_array($filename, $excludeFiles) || in_array($filename, $excludeDirs)) {
continue;
}
if (in_array($fileExtension, ['html', 'php'])) {
processFile($filepath, $getTitle, $removeTitleStrings, $getLastMod, $excludeMetaTags, $useChangeFreq, $changefreqValues, $getPriority, $xmlFinal);
}
}
}
}
// ファイルを処理(最終的なファイル用)
function processFile($filepath, $getTitle, $removeTitleStrings, $getLastMod, $excludeMetaTags, $useChangeFreq, $changefreqValues, $getPriority, &$xmlFinal) {
$content = file_get_contents($filepath);
if (shouldExcludeContent($content, $excludeMetaTags)) {
return;
}
$url = getRelativeUrl($filepath);
// UTC(協定世界時)での設定 - サイトマップXMLでの<lastmod>要素には、通常UTC(協定世界時)を使うことが推奨される
$lastMod = ($getLastMod == 1) ? getLastModifiedDateUTC($filepath) : '';
/*
// ローカルタイムでの設定
$lastMod = ($getLastMod == 1) ? getLastModifiedDateLocal($filepath) : '';
*/
$xmlFinal .= "\n <url>";
$xmlFinal .= "\n <loc>{$url}</loc>";
if ($getTitle == 1) {
$title = getTitleFromContent($content);
if (!empty($title)) {
$title = str_replace($removeTitleStrings, '', $title);
$xmlFinal .= "\n <title>{$title}</title>";
}
}
// 最終更新日時の表示
if (!empty($lastMod)) {
$xmlFinal .= "\n <lastmod>{$lastMod}</lastmod>";
}
// changefreqの表示
if ($useChangeFreq == 1) {
$changefreq = $changefreqValues[array_rand($changefreqValues)];
$xmlFinal .= "\n <changefreq>{$changefreq}</changefreq>";
}
// priorityの表示
if ($getPriority == 1) {
$priority = getPriorityFromDepth($filepath);
$xmlFinal .= "\n <priority>{$priority}</priority>";
}
$xmlFinal .= "\n </url>";
}
// 階層の深さからpriorityを計算(最終的なファイル用)
function getPriorityFromDepth($filepath) {
$depth = substr_count($filepath, DIRECTORY_SEPARATOR);
return 1 - ($depth * 0.1);
}
// メタタグを除外すべきか確認(最終的なファイル用)
function shouldExcludeContent($content, $excludeMetaTags) {
foreach ($excludeMetaTags as $tag) {
if (stripos($content, '<meta name="robots" content="' . $tag) !== false) {
return true;
}
}
return false;
}
///// ファイルの最終更新日時を取得 - サイトマップXMLでの<lastmod>要素には、通常UTC(協定世界時)を使うことが推奨される
// 最終変更日を UTC (協定世界時) 形式で設定。「+00:00」と、UTC(協定世界時)であることが表記される
function getLastModifiedDateUTC($filepath) {
$lastModTimestamp = filemtime($filepath);
$lastModDateTime = new DateTimeImmutable('@' . $lastModTimestamp);
return $lastModDateTime->format('c');
}
/*
// ローカルタイムでの設定。(「+09:00」と、UTC(協定世界時)との時差が表記される)
function getLastModifiedDateLocal($filepath) {
$lastModTimestamp = filemtime($filepath);
return date('c', $lastModTimestamp);
}
*/
// HTMLファイルからタイトルを取得(最終的なファイル用)
function getTitleFromContent($content) {
$dom = new DOMDocument;
libxml_use_internal_errors(true); // HTML解析中のエラーを抑制する
$dom->loadHTML($content);
$titleElements = $dom->getElementsByTagName('title');
if ($titleElements->length > 0) {
$title = $titleElements->item(0)->textContent;
return $title;
}
return '';
}
// ファイルのURLを取得(最終的なファイル用)
function getRelativeUrl($filepath) {
$relativeUrl = str_replace($_SERVER['DOCUMENT_ROOT'], '', $filepath);
return $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . str_replace('\\', '/', $relativeUrl);
}
// サイトマップ生成開始(最終的なファイル用)
generateSitemap($rootDirectory, $excludeDirectories, $excludeFiles, $getTitle, $removeTitleStrings, $getLastMod, $excludeMetaTags, $useChangeFreq, $changefreqValues, $getPriority, $excludePaths, $xmlFinal);
// サイトマップフッタ(最終的なファイル用)
$xmlFinal .= "\n</urlset>";
// サイトマップをファイルに保存(最終的なファイル)
file_put_contents($finalSitemapPath, $xmlFinal);
// 成功メッセージを表示(最終的なファイルを生成した旨を表示)
echo $successMessage;
?>
<hr>
<p style="margin-top: 20px">
<!-- <a>タグにこのPHPプログラムのファイル名を設定。拡張子は「.php」 -->
<a href="このプログラムのファイル名.php" style="margin-left: 20px; text-decoration: none;"><i class="fa-solid fa-check" style="color: #005eff;"></i> 「XMLファイル」の再生成 <i class="fa-solid fa-rotate fa-spin fa-2x" style="color:crimson"></i>[ページ再読み込み]</a>
</p>
<p>
<!-- 生成した「XMLファイル」をブラウザで開く -->
<a href='<?php echo '/' . $finalSitemapFilename; ?>' target='_blank' style='margin-left: 20px; text-decoration: none;'><i class="fa-solid fa-check" style="color: #005eff;"></i> 「XMLファイル」をブラウザで開く <i class="fa-solid fa-chalkboard-user fa-beat-fade fa-2x" style="color:green"></i>[別タブ]</a>
<div style="margin-left: 30px;font-size: 12px;color: gray">※ファイルの容量が大きい場合などに、ブラウザで開けないことがあります。ブラウザで開けない場合は、「.xml」ファイルをウェブサーバーからダウンロードしてご確認ください。</div>
</p>
<hr>
<!-- 「Google」サイトマップの追加・更新確認 -->
<p>
<!-- <a>タグにご自身のURLを設定 -->
<a href="https://search.google.com/search-console/sitemaps?resource_id=ご自身のURL" target="_blank" style="margin-left: 20px; text-decoration: none;"> <i class="fa-solid fa-check" style="color: #005eff;"></i>「<strong>Google</strong>」サイトマップの追加・更新確認 <i class="fa-solid fa-arrow-up-from-bracket fa-bounce fa-2x" style="color: #db0016;"></i></a>
</p>
<!-- 「Google Search Console」 -->
<p>
<!-- <a>タグにご自身が登録している Google Search Console の、「サイトマップ」ページのURLを設定 -->
<a href="https://search.google.com/search-console?resource_id=ご自身のURL" target="_blank" style="margin-left: 20px; text-decoration: none;"><i class="fa-solid fa-check" style="color: #005eff;"></i>「<strong>Google Search Console</strong>」 <i class="fa-solid fa-up-right-from-square fa-beat fa-2x" style="color: blue"></i></a>
<div style="font-size: 13px; margin: 0 40px">※「Google Search Console」への登録が済んでいることが前提。</div>
</p>
<hr>
<!-- 「Bing」サイトマップの再送信・更新確認 -->
<p>
<!-- <a>タグにご自身が登録している Bing の「Webmaster Tools」ページのURLと設定したXMLファイル名を設定。ファイル名は「$sitemapFilename」で設定したファイル名に合わせる -->
<a href="https://www.bing.com/webmasters/sitemaps?siteUrl=ご自身のURL/&sitemap=ご自身のURL/sitemap.xml" target="_blank" style="margin-left: 20px; text-decoration: none;"> <i class="fa-solid fa-check" style="color: #005eff;"></i>「<strong>Bing</strong>」サイトマップの再送信・更新確認 <i class="fa-solid fa-arrow-up-from-bracket fa-bounce fa-2x" style="color: #db0016;"></i></a>
</p>
<!-- 「Bing webmaster Tools」 -->
<p>
<!-- <a>タグにご自身が登録している Bing の「Webmaster Tools」ページのURLを設定 -->
<a href="https://www.bing.com/webmasters/home?siteUrl=ご自身のURL" target="_blank" style="margin-left: 20px; text-decoration: none;">
<i class="fa-solid fa-check" style="color: #005eff;"></i>「<strong>Bing webmaster Tools</strong>」 <i class="fa-solid fa-up-right-from-square fa-beat fa-2x" style="color: blue"></i></a>
<div style="font-size: 13px; margin: 0 40px">※「Bing Webmaster Tools」への登録を済ませているか、「Google Search Console」との連携を済ませていることが前提。</div>
</p>
<hr>
<!-- ご自身のサイト名など。含めなければ削除してください -->
<h3 align="center"><i class="fa-solid fa-house" style="color: crimson"></i> ご自身のサイト名など <i class="fa-solid fa-house" style="color: crimson"></i></h3>
<!-- 削除しても結構です -->
<h4 align="center"><a href="https://www.benricho.org/" target="_blank" style="text-decoration: none;"><i class="fa-solid fa-house" style="color: blue"></i> みんなの知識 ちょっと便利帳 <i class="fa-solid fa-house" style="color: blue"></i></h4>
</body>
</html>