这两天查看自己网站的请求日志,偶尔会发现 /sitemap.xml 这样的网址报404错误,我才意识到是自己的网站也需要一个对搜索引擎提供支持的站点地图了。
很久以前,我创建站点地图的方式是,利用第三方工具扫描网站生成过站点地图,但是,那样的地图是静态的,每次增减页面都要重新生成。以前的方式劳神费力,如今,再走老办法,肯定是没意义的,那就做一个动态的站点地图吧!
既然搜索引擎会查询 /sitemap.xml 这样的网址,我就干脆创建一个同名的路由好了:
Route::get('/sitemap.xml', [IndexController::class, 'sitemap'])->name('sitemap');
路由对应的方法如下:
/** * 动态的站点地图 */ public function sitemap() { $sitemap = new Sitemap\Root(); $sitemap->buildUrlElement( config('app.url'), Carbon::now()->toIso8601String(), 2, 1 ); $categoryIds = []; foreach ($this->data['nav_list'] as $item) { $categoryIds[] = $item['id']; $sitemap->buildUrlElement( $item['url'], $item['updated_at']->toIso8601String(), 2, 0.8 ); } ArticleModel::query() ->whereIn('category_id', $categoryIds) ->each(function ($item) use ($sitemap) { $sitemap->buildUrlElement( $item['url'], $item['updated_at']->toIso8601String(), 4, 0.8 ); }); return response($sitemap->render())->header('Content-Type', 'text/xml'); }
功能写好后,再打开 https://larastu.com/sitemap.xml 后,页面内容大致如下
This XML file does not appear to have any style information associated with it. The document tree is shown below.https://larastu.com 2022-05-22T14:33:40+08:00 daily 1 ... https://larastu.com/category/1 2022-04-28T11:07:32+08:00 daily 0.8
至于为什么要生成这样的格式,参考一下 百科 ,你就会知道答案了。
相关的工具类如下,我采用的是设计模式中的组合模式设计的:
RenderableInterface.php
Root.php
addElement(new UrlLoc($url)); $element->addElement(new Lastmod($updatedAt)); $element->addElement(new Changefreq($changeFreq)); $element->addElement(new Priority($priority)); $this->elements[] = $element; return $element; } public function render(): string { $sitemap = ''; $sitemap .= ''; foreach ($this->elements as $element) { $sitemap .= $element->render(); } $sitemap .= ' '; return $sitemap; } }
Url.php
elements[] = $element; } public function render(): string { $urlCode = ''; foreach ($this->elements as $element) { $urlCode .= $element->render(); } $urlCode .= ' '; return $urlCode; } }
UrlLoc.php和其他调用类的写法都和下面代码类似
url = $url; } public function render(): string { return "{$this->url} "; } }
到此,站点地图的开发过程算是记录完成了。