개발
PHP 개발 일지

PHP 사이트맵 제작 (2)

142 views as of October 29, 2024.

PHP 사이트맵 제작 (1) - eruLabo
PHP 사이트맵 제작 (1) - eruLabo
사이트맵이란?사이트맵은 그 사이트의 여러가지 페이지에 접근가능한 링크의 모음, 즉 메뉴라 볼 수 있다. 근데 용도는 사용자가 보기보다는 웹 서치 엔진이나 봇이 이 사이트에 대해 이해하는데 도움을 주기 최적화...
https://erulabo.com/198

이전 글에 이어 바로 코드 단계로 넘어가보겠다.

우선 제작해야하는건 SimpleSitemapGenerator 이다.

실제로 라라벨 환경이든 노드 환경이든 사이트맵 제작을 자동화해주는 라이브러리는 정말 널리고 널렸다.
당장 검색만해봐도 spatie/laravel-sitemap, presta/sitemap-bundle, laravelium/sitemap 등 널리고 널렸다.

근데 문득 생각이 드는게 고작 XML 구조화 파일만드는데 이런 라이브러리까지 설치해야되나? 라는 생각이 들게되어 검색과 GPT 도움으로 아래처럼 XML을 구조화 하는 코드를 간단하계 설계, 구현할 수 있었다.

<?php
 
namespace App\Services;
 
class SimpleSitemapGenerator
{
    protected $urls = [];
 
    /**
     * URL 추가 메서드
     */
    public function addUrl($loc, $lastmod = null, $priority = null)
    {
        $this->urls[] = [
            'loc' => $loc,
            'lastmod' => $lastmod,
            'priority' => $priority,
        ];
    }
 
    /**
     * XML 포맷으로 사이트맵 생성
     */
    public function generateXml()
    {
        $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset></urlset>');
        $xml->addAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
 
        foreach ($this->urls as $url) {
            $urlElement = $xml->addChild('url');
            $urlElement->addChild('loc', htmlspecialchars($url['loc']));
 
            if ($url['lastmod']) {
                $urlElement->addChild('lastmod', $url['lastmod']);
            }
 
            if ($url['priority']) {
                $urlElement->addChild('priority', $url['priority']);
            }
        }
 
        return $xml->asXML();
    }
 
    /**
     * XML 파일로 저장
     */
    public function saveToFile($path)
    {
        file_put_contents($path, $this->generateXml());
    }
}Copy

물론 위의 코드를 구현시키기위해서는 SimpleXMLElement 클래스를 사용해야하고 이를 이용하기위해서는 composerext-simplexml를 설치해야되긴하는데, 이건 익스텐션 파일정도니 다른 라이브러리와 의존성 검사도 딱히 하지않기 때문에 이정도는 감수해도 될거같다.

composer require ext-simplexmlCopy

설치하려면 위의 코드를 터미널에 입력하거나 직접 composer.json을 열어서 "require" 안에 "ext-simplexml": "*" 한줄을 추가하고 composer update 를 해도 된다.

이 다음에는 위의 코드를 실행할 커맨드 클래스를 아래와 같이 제작할 수 있다.
먼저 커맨드 클래스는 라라벨이 직접적으로 지원하는 형식으로 아래와 같이 artisan 명령으로 기본 클래스를 생성할 수 있다.

php artisan make:command GenerateSitemapCopy

위 코드를 실행시지면 App\Console\Commands\GenerateSitemap 파일이 생성되며 그 안의 내용을 아래 처럼 기입해준다.

<?php
 
namespace App\Console\Commands;
 
use App\Services\SimpleSitemapGenerator;
use Illuminate\Console\Command;
 
class GenerateSitemap extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'sitemap:generate';
 
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Generate the sitemap';
 
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
 
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $sitemap = new SimpleSitemapGenerator();
 
        // 예시 페이지 추가
        $sitemap->addUrl(url('/'), date('Y-m-d\TH:i:sP'), '1.0');
        // 필요한 페이지들을 추가...
        $sitemap->addUrl(url('/search?keyword=cate:%EA%B0%9C%EB%B0%9C'), date('Y-m-d\TH:i:sP'), '0.8');
        $sitemap->addUrl(url('/search?keyword=cate:%EC%95%A0%EB%8B%88'), date('Y-m-d\TH:i:sP'), '0.8');
        $sitemap->addUrl(url('/search?keyword=cate:%EA%B2%8C%EC%9E%84'), date('Y-m-d\TH:i:sP'), '0.8');
        $sitemap->addUrl(url('/search?keyword=cate:%EA%B8%B0%EB%A1%9D'), date('Y-m-d\TH:i:sP'), '0.8');
        $sitemap->addUrl(url('/search?keyword=cate:collection'), date('Y-m-d\TH:i:sP'), '0.8');
        foreach(\App\Models\Post::orderByDesc('created_at')->get() as $key => $post) {
            // 첫 페이지에 뜨는 게시글은 우선순위를 높게
            if($key < $post->perPage) {
                $priority = '0.8';
            } else {
                $priority = '0.64';
            }
            $sitemap->addUrl(url('/'.$post->id), date('Y-m-d\TH:i:sP', strtotime($post->created_at)), $priority);
        }
 
        // 사이트맵 파일 저장
        $sitemap->saveToFile(public_path('sitemap.xml'));
 
        $this->info('Sitemap generated successfully!');
    }
}Copy


나 같은경우는 사이트맵의 링크 단계가 메인페이지, 카테고리 페이지, 게시글들 이런 순서로 보였으면해서 addUrl을 위에처럼 구현화했는데 이 부분은 필요에 맞게 변형하면 될거같다.

일단 위의 코드까지 구현하면 터미널에서 커맨드로 사이트맵 제작을 실행해볼 수 있다.


이렇게 터미널에서 사이트맵 생성을 실행시키면 public 폴더 위치에 sitemap.xml이 생성이 된다. 이를 웹사이트에서 주소로 접근해 열어보면,


이런식으로 사이트맵을 얻어낼 수 있다.



이 다음에 해야할거는 이 행위를 터미널에서 타이핑으로 실행하는게 아니라 자동화 하는 단계이다.

이과정은 crontab 기능을 이용해 구현할 수 있다.
먼저 crontab -e 명령을 통해 에디트 모드를 활성화 하고 가장 하단에 아래 구문을 적어주면된다.


0 0 * * * /usr/bin/php /path/to/your/laravel/artisan sitemap:generateCopy

그러면 매일 자정에 위 명령이 실행되면서 사이트맵이 자동 실행될것이다.
실제로 저 크론탭의 명령은 바로 터미널에서 실행해도 즉각 사이트맵이 생성된다.

이제 이 코드를 기반으로 각 환경에 맞게 조금씩 바꾸어서 구현하면 되지않을까? 싶으면서 이만 글을 줄이겠다.

하하 끝!

#개발 #PHP #사이트맵 #Sitemap #Laravel
0 개의 댓글
×