PHP项目站点地图如何PHP自动生成

wen PHP项目 29

本文目录导读:

PHP项目站点地图如何PHP自动生成

  1. 基础XML站点地图生成
  2. 数据库驱动站点地图
  3. 大型站点分片生成
  4. 自动生成脚本
  5. 提交到搜索引擎
  6. 集成到框架(Laravel示例)
  7. 使用建议
  8. 注意事项

我来详细说明PHP自动生成站点地图的几种方法:

基础XML站点地图生成

简单URL列表生成器

<?php
class SitemapGenerator {
    private $urls = [];
    private $filePath;
    public function __construct($filePath = 'sitemap.xml') {
        $this->filePath = $filePath;
    }
    // 添加URL
    public function addUrl($loc, $lastmod = null, $changefreq = 'weekly', $priority = '0.5') {
        $this->urls[] = [
            'loc' => $loc,
            'lastmod' => $lastmod ?? date('Y-m-d'),
            'changefreq' => $changefreq,
            'priority' => $priority
        ];
    }
    // 生成XML
    public function generate() {
        $dom = new DOMDocument('1.0', 'UTF-8');
        $dom->formatOutput = true;
        $urlset = $dom->createElement('urlset');
        $urlset->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
        foreach ($this->urls as $url) {
            $urlElement = $dom->createElement('url');
            $loc = $dom->createElement('loc', htmlspecialchars($url['loc']));
            $urlElement->appendChild($loc);
            $lastmod = $dom->createElement('lastmod', $url['lastmod']);
            $urlElement->appendChild($lastmod);
            $changefreq = $dom->createElement('changefreq', $url['changefreq']);
            $urlElement->appendChild($changefreq);
            $priority = $dom->createElement('priority', $url['priority']);
            $urlElement->appendChild($priority);
            $urlset->appendChild($urlElement);
        }
        $dom->appendChild($urlset);
        return $dom->save($this->filePath);
    }
}
// 使用示例
$sitemap = new SitemapGenerator();
$sitemap->addUrl('https://example.com/', '2024-01-01', 'daily', '1.0');
$sitemap->addUrl('https://example.com/about', '2024-01-01', 'monthly', '0.8');
$sitemap->addUrl('https://example.com/blog', '2024-01-01', 'weekly', '0.9');
$sitemap->generate();
?>

数据库驱动站点地图

<?php
class DatabaseSitemapGenerator {
    private $db;
    private $baseUrl;
    public function __construct($host, $dbname, $user, $pass, $baseUrl) {
        try {
            $this->db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch(PDOException $e) {
            die("Connection failed: " . $e->getMessage());
        }
        $this->baseUrl = rtrim($baseUrl, '/');
    }
    public function generateSitemap() {
        $dom = new DOMDocument('1.0', 'UTF-8');
        $dom->formatOutput = true;
        $urlset = $dom->createElement('urlset');
        $urlset->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
        // 从数据库获取文章
        $articles = $this->getArticles();
        foreach ($articles as $article) {
            $url = $dom->createElement('url');
            $loc = $dom->createElement('loc', 
                $this->baseUrl . '/article/' . $article['slug']
            );
            $url->appendChild($loc);
            $lastmod = $dom->createElement('lastmod', $article['updated_at']);
            $url->appendChild($lastmod);
            $urlset->appendChild($url);
        }
        // 添加静态页面
        $staticPages = ['', 'about', 'contact', 'blog'];
        foreach ($staticPages as $page) {
            $url = $dom->createElement('url');
            $loc = $dom->createElement('loc', $this->baseUrl . '/' . $page);
            $url->appendChild($loc);
            $urlset->appendChild($url);
        }
        $dom->appendChild($urlset);
        return $dom->save('sitemap.xml');
    }
    private function getArticles() {
        $stmt = $this->db->query("SELECT slug, updated_at FROM articles WHERE status = 'published'");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
}
// 使用示例
$generator = new DatabaseSitemapGenerator(
    'localhost', 
    'your_database', 
    'username', 
    'password', 
    'https://example.com'
);
$generator->generateSitemap();
?>

大型站点分片生成

<?php
class LargeSitemapGenerator {
    private $baseUrl;
    private $maxUrls = 50000; // 单个站点地图最大URL数
    private $sitemapDir = 'sitemaps/';
    public function __construct($baseUrl) {
        $this->baseUrl = rtrim($baseUrl, '/');
        if (!is_dir($this->sitemapDir)) {
            mkdir($this->sitemapDir, 0755, true);
        }
    }
    public function generateAll() {
        $sitemapFiles = [];
        // 生成不同部分的站点地图
        $sitemapFiles = array_merge(
            $sitemapFiles,
            $this->generateSectionSitemap('articles', $this->getArticles())
        );
        $sitemapFiles = array_merge(
            $sitemapFiles,
            $this->generateSectionSitemap('categories', $this->getCategories())
        );
        // 生成索引文件
        $this->generateIndex($sitemapFiles);
        return true;
    }
    private function generateSectionSitemap($prefix, $data) {
        $files = [];
        $chunks = array_chunk($data, $this->maxUrls);
        foreach ($chunks as $index => $chunk) {
            $filename = $prefix . '_' . ($index + 1) . '.xml';
            $filepath = $this->sitemapDir . $filename;
            $dom = new DOMDocument('1.0', 'UTF-8');
            $dom->formatOutput = true;
            $urlset = $dom->createElement('urlset');
            $urlset->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
            foreach ($chunk as $url) {
                $urlElement = $dom->createElement('url');
                $loc = $dom->createElement('loc', $url['loc']);
                $urlElement->appendChild($loc);
                $urlset->appendChild($urlElement);
            }
            $dom->appendChild($urlset);
            $dom->save($filepath);
            $files[] = $filename;
        }
        return $files;
    }
    private function generateIndex($sitemapFiles) {
        $dom = new DOMDocument('1.0', 'UTF-8');
        $dom->formatOutput = true;
        $sitemapindex = $dom->createElement('sitemapindex');
        $sitemapindex->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
        foreach ($sitemapFiles as $file) {
            $sitemap = $dom->createElement('sitemap');
            $loc = $dom->createElement('loc', 
                $this->baseUrl . '/' . $this->sitemapDir . $file
            );
            $sitemap->appendChild($loc);
            $lastmod = $dom->createElement('lastmod', date('Y-m-d'));
            $sitemap->appendChild($lastmod);
            $sitemapindex->appendChild($sitemap);
        }
        $dom->appendChild($sitemapindex);
        $dom->save('sitemap_index.xml');
    }
}
?>

自动生成脚本

CRON任务脚本

<?php
// generate_sitemap.php
require_once __DIR__ . '/vendor/autoload.php';
// 设置执行时间和内存限制
ini_set('max_execution_time', 300);
ini_set('memory_limit', '256M');
class AutoSitemap {
    private $baseUrl;
    private $cacheTime = 3600; // 1小时
    public function __construct($baseUrl) {
        $this->baseUrl = $baseUrl;
    }
    public function shouldRegenerate() {
        $sitemapFile = 'sitemap.xml';
        if (!file_exists($sitemapFile)) {
            return true;
        }
        // 检查是否需要重新生成
        $fileTime = filemtime($sitemapFile);
        if (time() - $fileTime > $this->cacheTime) {
            return true;
        }
        // 检查内容是否有更新
        return $this->checkContentUpdated($fileTime);
    }
    private function checkContentUpdated($lastGenerated) {
        // 这里实现检查数据库最新更新时间
        // 如果数据库有更新,返回true
        return false;
    }
    public function generate() {
        // 记录开始时间
        $start = microtime(true);
        // 生成站点地图逻辑
        // ...
        // 更新生成时间
        file_put_contents('sitemap_last_generated.txt', date('Y-m-d H:i:s'));
        $elapsed = microtime(true) - $start;
        file_put_contents('sitemap_generation.log', 
            "Generated at " . date('Y-m-d H:i:s') . 
            " (took {$elapsed} seconds)\n", 
            FILE_APPEND
        );
        return true;
    }
}
// 执行生成
$generator = new AutoSitemap('https://example.com');
if ($generator->shouldRegenerate()) {
    $generator->generate();
}
?>

提交到搜索引擎

<?php
class SitemapSubmitter {
    private $searchEngines = [
        'google' => 'https://www.google.com/ping?sitemap=%s',
        'bing' => 'https://www.bing.com/ping?sitemap=%s'
    ];
    public function submit($sitemapUrl) {
        $results = [];
        foreach ($this->searchEngines as $name => $url) {
            $pingUrl = sprintf($url, urlencode($sitemapUrl));
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $pingUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            $results[$name] = ($httpCode === 200);
        }
        return $results;
    }
}
// 使用示例
$submitter = new SitemapSubmitter();
$results = $submitter->submit('https://example.com/sitemap.xml');
?>

集成到框架(Laravel示例)

<?php
// app/Console/Commands/GenerateSitemap.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Article;
use Spatie\Sitemap\SitemapGenerator;
use Spatie\Sitemap\Tags\Url;
class GenerateSitemap extends Command
{
    protected $signature = 'sitemap:generate';
    protected $description = 'Generate the sitemap';
    public function handle()
    {
        // 使用Spatie的包
        SitemapGenerator::create(config('app.url'))
            ->getSitemap()
            ->add(Url::create('/about'))
            ->add(Url::create('/contact'))
            ->add(Article::all()->map(function ($article) {
                return Url::create("/article/{$article->slug}")
                    ->setLastModificationDate($article->updated_at)
                    ->setChangeFrequency(Url::CHANGE_FREQUENCY_WEEKLY)
                    ->setPriority(0.9);
            }))
            ->writeToFile(public_path('sitemap.xml'));
        $this->info('Sitemap generated successfully!');
    }
}

使用建议

定时任务配置(Crontab)

# 每天凌晨2点生成站点地图
0 2 * * * /usr/bin/php /path/to/your/project/generate_sitemap.php
# 提交到搜索引擎
0 3 * * * /usr/bin/php /path/to/your/project/submit_sitemap.php

Robots.txt配置

User-agent: *
Allow: /
Sitemap: https://example.com/sitemap.xml
Sitemap: https://example.com/sitemap_index.xml

注意事项

  1. 文件大小限制:单个站点地图不超过50MB或50,000个URL
  2. 压缩:可以使用gzip压缩减少带宽
  3. 更新频率:根据网站更新频率设置,一般每天或每周更新
  4. 优先级:首页和重要页面设高优先级(1.0)
  5. 错误处理:添加详细的错误日志

这样,PHP就能自动生成并维护网站地图,提高搜索引擎抓取效率。

抱歉,评论功能暂时关闭!