首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 生成百度 Sitemap 站點地圖:分批導出 70 萬數據、自動建立索引文件

     編輯:PHP 綜合知識

業務背景

問答百科站 70 萬問題,需生成符合百度規範的 Sitemap:每個 XML 含 5000 條 URL,共 140 個文件,外加一個 sitemapindex.xml 索引。為避免單次查詢過大影響線上性能,採用「每次查 1000 條、累積寫入」策略。

核心邏輯流程

  1. 讀取索引文件 Index.txt 獲取上次進度(文件名、最大 ID、最小 ID、已寫入條數)。
  2. 根據進度決定本次查詢 LIMIT 起始位置與數量。
  3. 查詢 1000 條數據,循環生成移動版/PC 版 URL XML 片段。
  4. 追加寫入當前 XML 文件(如 0.xml),更新索引文件進度。
  5. 累積達 5000 條時,新建下一個 XML 文件,在索引文件新增一行。
  6. 索引文件同步更新 sitemapindex.xml(<sitemap><loc><lastmod>)。

關鍵代碼片段(簡化版)

<?php
class SitemapAction {
    private static $baseURL = 'https://www.xxx.cn';
    private static $askMobileUrl = 'https://m.xxx.cn/ask/';
    private static $askPcUrl = 'https://www.xxx.cn/ask/';
    private $questionObj; // 模型對象

    public function askSetMap() {
        header('Content-Type: text/html; charset=utf-8');
        $maxXml = 5000;   // 單文件上限
        $psize  = 1000;   // 每次查詢量
        $indexFile = APP_PATH . 'setmapxml/Index.txt';
        $indexXml  = '../siteditu/ask/ask.xml'; // sitemapindex.xml

        // 1. 讀取/初始化索引進度
        $progress = $this->readProgress($indexFile, $maxXml, $psize);
        // $progress = ['filename'=>0, 'maxid'=>0, 'minid'=>0, 'psize'=>1000, 'isNewFile'=>true, 'record'=>0]

        // 2. 查詢數據
        $list = self::$questionObj->getQuestionSetMap($where, $progress['maxid'], $progress['psize']);
        if (!$list) { echo '無新數據'; exit; }

        // 3. 生成 XML 內容
        $xml = '';
        foreach ($list as $k => $q) {
            if ($k === 0) $progress['minid'] = $q['id'];
            $q['lastmod'] = substr($q['lasttime'], 0, 10);
            $q['mobileurl'] = self::$askMobileUrl . $q['id'] . '.html';
            $q['pcurl'] = self::$askPcUrl . $q['id'] . '-p1.html';
            $xml .= $this->buildMobileUrl($q);
            $xml .= $this->buildPcUrl($q);
        }
        $progress['maxid'] = end($list)['id'];
        $progress['record'] += count($list);

        // 4. 寫入數據 XML
        $this->writeDataXml($progress['filename'], $xml, $progress['isNewFile']);

        // 5. 更新索引文件
        $this->updateIndexTxt($indexFile, $progress);

        // 6. 更新 sitemapindex.xml
        if ($progress['isNewFile']) {
            $this->updateIndexXml($indexXml, $progress['filename']);
        }
    }

    private function buildMobileUrl($q) {
        return "<url>\n<loc>{$q['mobileurl']}</loc>\n<mobile:mobile type=\"mobile\"/>\n<lastmod>{$q['lastmod']}</lastmod>\n<changefreq>daily</changefreq>\n<priority>0.8</priority>\n</url>\n";
    }
    private function buildPcUrl($q) {
        return "<url>\n<loc>{$q['pcurl']}</loc>\n<lastmod>{$q['lastmod']}</lastmod>\n<changefreq>daily</changefreq>\n<priority>0.8</priority>\n</url>\n";
    }
    // ... 文件讀寫、進度管理等輔助方法省略 ...
}
?>

生成文件結構示例

索引文件 Index.txt

0,3146886,3145887,5000
1,3148886,3147887,1000

Sitemap 索引 ask.xml

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex>
  <sitemap>
    <loc>https://www.xxx.cn/ask/setmapxml/0.xml</loc>
    <lastmod>2014-05-12</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://www.xxx.cn/ask/setmapxml/1.xml</loc>
    <lastmod>2014-05-12</lastmod>
  </sitemap>
</sitemapindex>

單個數據文件 0.xml

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9" xmlns:mobile="https://www.baidu.com/schemas/sitemap-mobile/1/">
  <url>
    <loc>https://m.xxx.cn/ask/7460.html</loc>
    <mobile:mobile type="mobile"/>
    <lastmod>2013-01-11</lastmod>
    <changefreq>daily</changefreq>
    <priority>0.8</priority>
  </url>
  ...
</urlset>

性能優化要點

  • 分批查詢:LIMIT 1000 避免長事務鎖表、內存溢出。
  • 增量寫入:file_put_contents(..., FILE_APPEND) 或讀取修改重寫,避免佔用大量內存拼接巨大字符串。
  • 斷點續傳:索引文件記錄進度,腳本中斷重跑不重複不遺漏。
  • 移動端適配:輸出 xmlns:mobile 命名空間及 <mobile:mobile type="mobile"/>,符合百度移動 Sitemap 規範。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved