sitemap 文件填充示例代码

最近制作网站的 sitemap ,要求每个 txt 文件包含不超过 5w 条 url 。包括 www 站 与 m 站,http 与 https ,即要同时制作四份 sitemap ,并每日自动更新。

CREATE TABLE `z_sitemaps` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `txt_area` enum('m','www') NOT NULL DEFAULT 'www',
  `txt_order` int(10) unsigned NOT NULL COMMENT '文件名称 1.txt 2.txt ..',
  `url_sum` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '包含的url数量',
  `complete` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否填充完毕',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

sitemap 文件填充示例代码

<?php
namespace App\Library\Other;
use DB;
/**
 * 整理 sitemap 文件
 * 制作 sitemap xml 地图
 */
class Sitemap {
    private $max_num; // 单个sitemap最大url个数
    private $area; // www | m
    private $https_dir; // 存放路径
    private $sync_xml_dir; // sitemap xml地图
    // 规范:所有dir路径必须以/结尾
    public function __construct(string $area){
        $this->max_num = 49900;
        $this->area = in_array($area, ['www','m']) ? $area : 'www';
        $this->https_dir = public_path().'/sitemaps/'.$area.'/https/';
        $this->sync_xml_dir = public_path().'/sitemaps/';
    }
    /*
    * @param $urls url数组
    * @return 所放入的文件路径,多个文件以;分隔
    */
    public function createSitemap(array $urls){
        $count = count($urls);
        if($count > $this->max_num){return false;}
        $sitemap = $this->searchSitemap();
        $expect_num = 49900 - $sitemap->url_sum;
        $put_files = [];
        // 文件数量小于期望值直接填充
        if($count <= $expect_num){
            $file_name = $this->fillSitemap($sitemap, $urls);
            $put_files[] = $file_name;
        }else{
            // 先将未填满的sitemap文件填满
            $slice_arr = array_slice($urls, 0, $expect_num);
            $file_name = $this->fillSitemap($sitemap, $slice_arr);
            $put_files[] = $file_name;
            // 再将剩余的添加到新文件
            $remain = array_slice($urls,$expect_num);
            $sitemap = $this->newSitemap();
            $file_name = $this->fillSitemap($sitemap, $remain);
            $put_files[] = $file_name;
        }
        return implode(';', $put_files);
    }
    /*
    * 查找尚未填充完毕的sitemap文件
    * @return 一条表记录
    */
    public function searchSitemap(){
        $sitemap = DB::table('z_sitemaps')->where('txt_area',$this->area)->where('complete',0)->where('url_sum','<',$this->max_num)->orderBy('id','desc')->first();
        return $sitemap ? $sitemap : $this->newSitemap();
    }

    /*
    * 建立空sitemap文件
    * @return 一条数据记录
    */
    public function newSitemap(){
        // 最大文件名
        $max_order = DB::table('z_sitemaps')->where('txt_area',$this->area)->max('txt_order');
        // 最大文件名+1 则是下一个文件名
        if(!$max_order){ $max_order = 1;} else { $max_order = $max_order + 1;}
        // public/sitemaps/{www|m}/https/1.txt
        $file_name = $this->getSitemapFilename($max_order);
        // 建立空文件
        file_put_contents($file_name, '');
        // 同时添加表记录对应文件名
        $sitemap_id = DB::table('z_sitemaps')->insertGetId([
            'txt_area' => $this->area,
            'txt_order' => $max_order,
            'created_at' => date('Y-m-d H:i:s', time()),
        ]);
        return DB::table('z_sitemaps')->where('id',$sitemap_id)->first();
    }

    /*
    * @param $sitemap 一条表记录
    * @param $urls url数组
    * @return 已保存的sitemap文件地址
    */
    public function fillSitemap($sitemap, array $urls){
        $count = count($urls);
        $url_list = implode("\n", $urls)."\n";
        $file_name = $this->getSitemapFilename($sitemap->txt_order);
        $rs = file_put_contents($file_name, $url_list, FILE_APPEND);
        $current = $sitemap->url_sum + $count;
        $is_complete = $current >= $this->max_num ? 1 : 0;
        DB::table('z_sitemaps')->where('id',$sitemap->id)->update([
            'url_sum' => $current,
            'updated_at' => date('Y-m-d H:i:s', time()),
            'complete' => $is_complete,
        ]);
        // 同时生成 http 格式
        $this->syncHttpsToHttp($file_name);
        return $file_name;
    }

    // 文件真实路径
    public function getSitemapFilename($txt_order){
        return $this->https_dir.$txt_order.'.txt';
    }

    // 同步https目录中的sitemap文件到http目录
    // 注意:https目录与http目录必须是同级目录
    public function syncHttpsToHttp($file_name)
    {
        $str = file_get_contents($file_name);
        if($str){
            $http_str = str_replace('https','http',$str);
            $http_dir_path = str_replace('https', 'http', $file_name);
            file_put_contents($http_dir_path, $http_str);
        }
    }

    //生成sitemap地图 XML格式
    public function sitemapXml($is_http=0)
    {
        $area = $this->area;
        $http = $is_http ? 'http' : 'https';
        $strxml = '<sitemapindex></sitemapindex>';
        $xmlobj = new \SimpleXMLElement($strxml);
        $sitemaps = DB::table('z_sitemaps')->where('txt_area',$area)->orderBy('id','desc')->get();
        foreach ($sitemaps as $v) {
            $loc = 'https://xxxx.com/sitemaps/'.$http.'/'.$v->txt_order.'.txt';
            $lastmod = $v->updated_at;
            $sitemap = $xmlobj->addChild('sitemap');
            $sitemap->addChild('loc',$loc);
            $sitemap->addChild('lastmod',$lastmod);
        }
        $file_path = '...';
        $xmlobj->asXML($file_path);
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
welcome come back
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
95
粉丝
24
喜欢
156
收藏
348
排名:324
访问:2.9 万
私信
所有博文
社区赞助商