LaravelでXMLサイトマップの作り方

PHPのLaravelでxmlサイトマップを作る機会があったため、laravelでxmlサイトマップの作り方について説明します。

私が使うlaravelのバージョンは9.52です。

1. サイトマップ

まず、php、laravel云々の前にサイトマップとは何かについて説明します。

1.1. サイトマップって何に使うのか?

サイトマップは、ウェブサイトの構造をクローラーに効果的に伝え、検索エンジンに正確な情報を提供するための重要な要素です。使用例として、例えば、Google Search Consoleのインデックス作成でサイトマップの部分で使います。

1.2. サイトマップとは

サイトマップは親ファイルとなるサイトマップインデックスと子ファイルに分かれています。サイトマップの記述方法は子ファイルと親ファイルで異なり、Htmlのようにタグを用いて書きます。今回使用するタグは以下のようになります。

親ファイルのタグ説明

sitemapindex すべてのタグを囲む。
sitemap 一つの子ファイルの情報を囲む。
loc 子ファイルのリンク
lastmod 更新時間を伝える

子ファイルのタグ説明

urlset すべてのタグを囲む。
url 一つのリンクの情報を囲む。
loc ページのリンク
lastmod 更新時間を伝える
changefreq botに更新頻度を伝える

1.3. サイトマップの具体例

サイトマップの親ファイルと子ファイルの具体的な書き方は以下のようになります。実際は、#######にドメイン名が入ります。

親ファイル

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemapindex>
  <sitemap>
    <loc>https://#######.com/sitemap1.xml</loc>
    <lastmod>2023-07-21T06:01:53+00:00</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://#######.com/sitemap2.xml</loc>
    <lastmod>2023-07-20T06:01:53+00:00</lastmod>
  </sitemap>
</sitemapindex>

子ファイル

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://#######.com/page1</loc>
    <lastmod>2023-07-21T06:01:53+00:00</lastmod>
    <changefreq>daily</changefreq>
  </url>
  <url>
    <loc>https://#######.com/page2</loc>
    <lastmod>2023-06-21T06:01:53+00:00</lastmod>
    <changefreq>weekly</changefreq>
  </url>
</urlset>

1.4. 自作する必要はあるのか?

laravel-sitemapというものがあります。これでいいと感じたら、composerでインストールして使ってください。ただ、気になる点があるとすれば、最後の更新が2020年の11月という点です。

2. PHP/Laravelで自作する

サイトマップの具体例で示したものをPHP/Laravelで実装します。ここまでの説明で、頭の中にイメージが浮かんで、コードが書けると感じたら、以下のページは参考にするか見る必要はないです。

2.1. web.phpを編集

routesフォルダの中のweb.phpを編集してルート設定をします。

Route::get('/sitemap.xml', [SitemapController::class, 'site']);
Route::get('/sitemap/hoge.xml', [SitemapController::class, 'hoge']);

それぞれの意味を解説します。
1行目はSitemapControllerクラスのsiteメソッドを使って「https://ドメイン/sitemap.xml」にアクセスした場合、親ファイルに該当するサイトマップインデックスが返されることを示しています。
2行目はSitemapControllerクラスのhogeメソッドを使って「https://ドメイン/sitemap/hoge.xml」にアクセスした場合、子ファイルに該当するサイトマップが返されることを示しています。

次に、Contorllerを作成します。

2.2. Contorllerの作成

以下のコマンドを入力してSitemapControllerという名前のContorllerを作成する。

php artisan make:controller SitemapController

コマンドを実行すると以下のようになります。

web.phpに以下のコードを追加する。

use App\Http\Controllers\SitemapController;

app/Http/Controllers/SitemapController.phpに以下のコードを書く。


<?php
 
namespace App\Http\Controllers;
use Illuminate\Http\Request;
 
class SitemapController extends Controller
{
 
    public function site(){
        return response()->view("sitemap/sitemap")->header('Content-Type', 'text/xml');
    }
 
    public function hoge(){
        $img=null; //DB::table('テーブル名')->get();
        return response()->view('sitemap/hoge',["images"=>$img])->header('Content-Type', 'text/xml');
    }
} 

SitemapControllerに定義したメソッドについて説明します。
siteメソッド: サイトマップインデックス(親ファイル)を返す処理を行います。response()->view(“sitemap/sitemap”)は、sitemap/sitemap.blade.phpビューファイルを表示することを意味します。これは、XML形式でサイトマップを定義したビューファイルになります。
hogeメソッド: 子ファイルに該当するサイトマップを返す処理を行います。response()->view(‘sitemap/hoge’, [“images” => $img])は、sitemap/hoge.blade.phpビューファイルを表示し、取得したページの情報をビューファイルに渡すことを意味します。

実際に、運用するときは、$imgのnullを変更してください。一例として、私の場合は、クエリビルダを使用して、対象となるページを取得しました。クエリビルダとは、コメントアウトされたDB::table(‘テーブル名’)->get()は、データベースから対象となるページの情報を取得するためのクエリです。

2.3. bladeファイルを作成する

bladeを用いて、親ファイルと子ファイルのサイトマップを作成します。
親ファイルをreusroces/views/sitemap/sitemap.blade.phpに作成します。

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<?php
$dateTime = new DateTime(now());
$w3cDatetime = $dateTime->format('Y-m-d\TH:i:sP');
?>
  <sitemap>
    <loc>https://######.com/sitemap/hoge.xml</loc>
    <lastmod>{{$w3cDatetime}}</lastmod>

  </sitemap>
  <sitemap>
    <loc>https://######.com/sitemap/hogehoge.xml</loc>
    <lastmod>{{$w3cDatetime}}</lastmod>

  </sitemap>
</sitemapindex>

echoを用いて、を出力していますが、<?がphpの始まりとして認識されてしまうためです。 lastmodはW3C日付形式に対応しているため、DateTimeを使用しています。また、$datetimeにnowを用いて、現在の時刻にしていますが、実際は、変更された時間をデータベースから取り出してnowの部分に入力していました。

次に、子ファイルをreusroces/views/sitemap/hoge.blade.phpに作成します。@foreachを用いて動的に作成します。子ファイルはコピペしても動きません。ControllerとDBを変えてください。

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; 
?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@foreach($images as $image)
<?php
$dateTime = new DateTime($image->updated);
$w3cDatetime = $dateTime->format('Y-m-d\TH:i:sP');
?>
  <url>
    <loc>{{$image->url}}</loc> //ページのリンク
    <lastmod>{{$w3cDatetime}}</lastmod>
    <changefreq>weekly</changefreq>
  </url> 
@endforeach
</urlset>

2.4. 親ファイルの様子を見る

php artisan serve

コマンドを入力して、ローカルホストでサーバーを立てて、http://127.0.0.1:8000/sitemap.xmlに移動すると、以下のようになる。

サイトマップを増やしたい場合は、同様のことを繰り返して行ってください。

PR