official_website/app/common/util/SitemapXmlUtil.php

235 lines
8.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @Descripttion : FOXCMS 是一款高效的 PHP 多端跨平台内容管理系统
* @Author : FoxCMS Team
* @Date : 2023/6/26 19:07
* @version : V1.08
* @copyright : ©2021-现在 贵州黔狐科技股份有限公司 版权所有
* @LastEditTime : 2023/6/26 19:07
*/
namespace app\common\util;
class SitemapXmlUtil
{
private $writer; // XMLWriter对象
private $domain = ""; // 网站地图根域名
private $xmlFile = "sitemap"; // 网站地图xml文件不含后缀.xml
private $xmlFileFolder = ""; // 网站地图xml文件夹
private $currXmlFileFullPath = ""; // 网站地图xml文件当前全路径
private $isSchemaMore = true; // 网站地图是否添加额外的schema
private $current_item = 0; // 网站地图item个数序号
private $current_sitemap = 0; // 网站地图的个数(序号)
const SCHEMA_XMLNS = 'http://www.sitemaps.org/schemas/sitemap/0.9';
const SCHEMA_XMLNS_XSI = 'http://www.w3.org/2001/XMLSchema-instance';
const SCHEMA_XSI_SCHEMALOCATION = 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd';
const DEFAULT_PRIORITY = 0.5;
const SITEMAP_ITEMS = 50000;
const SITEMAP_SEPERATOR = '-';
const INDEX_SUFFIX = 'index';
const SITEMAP_EXT = '.xml';
/**
* @param string $domain 初始化网站地图根域名
*/
public function __construct($domain)
{
$this->setDomain($domain);
}
/**
* 设置网站地图根域名,开头用 http:// or https://, 结尾不要反斜杠/
* @param string $domain 网站地图根域名 <br>例如: http://mimvp.com
*/
public function setDomain($domain)
{
if (substr($domain, -1) == "/") {
$domain = substr($domain, 0, strlen($domain) - 1);
}
$this->domain = $domain;
return $this;
}
// 返回网站根域名
private function getDomain()
{
return $this->domain;
}
// 设置网站地图的xml文件名
public function setXmlFile($xmlFile)
{
$base = basename($xmlFile);
$dir = dirname($xmlFile);
if (!is_dir($dir)) {
$res = mkdir(iconv("UTF-8", "GBK", $dir), 0777, true);
if ($res) {
echo "mkdir $dir success";
} else {
echo "mkdir $dir fail.";
}
}
$this->xmlFile = $xmlFile;
return $this;
}
// 返回网站地图的xml文件名
private function getXmlFile()
{
return $this->xmlFile;
}
public function setIsChemaMore($isSchemaMore)
{
$this->isSchemaMore = $isSchemaMore;
}
private function getIsSchemaMore()
{
return $this->isSchemaMore;
}
// 设置XMLWriter对象
private function setWriter(\XMLWriter $writer)
{
$this->writer = $writer;
}
// 返回XMLWriter对象
private function getWriter()
{
return $this->writer;
}
// 返回网站地图的当前item
private function getCurrentItem()
{
return $this->current_item;
}
// 设置网站地图的item个数加1
private function incCurrentItem()
{
$this->current_item = $this->current_item + 1;
}
// 返回当前网站地图默认50000个item则新建一个网站地图
private function getCurrentSitemap()
{
return $this->current_sitemap;
}
// 设置网站地图个数加1
private function incCurrentSitemap()
{
$this->current_sitemap = $this->current_sitemap + 1;
}
private function getXMLFileFullPath()
{
$xmlfileFullPath = "";
if ($this->getCurrentSitemap()) {
$xmlfileFullPath = $this->getXmlFile() . self::SITEMAP_SEPERATOR . $this->getCurrentSitemap() . self::SITEMAP_EXT; // 第n个网站地图xml文件名 + -n + 后缀.xml
} else {
$xmlfileFullPath = $this->getXmlFile() . self::SITEMAP_EXT; // 第一个网站地图xml文件名 + 后缀.xml
}
$this->setCurrXmlFileFullPath($xmlfileFullPath); // 保存当前xml文件全路径
return $xmlfileFullPath;
}
public function getCurrXmlFileFullPath()
{
return $this->currXmlFileFullPath;
}
private function setCurrXmlFileFullPath($currXmlFileFullPath)
{
$this->currXmlFileFullPath = $currXmlFileFullPath;
}
private function startSitemap()
{
$this->setWriter(new \XMLWriter());
$this->getWriter()->openURI($this->getXMLFileFullPath()); // 获取xml文件全路径
$this->getWriter()->startDocument('1.0', 'UTF-8');
$this->getWriter()->setIndentString("\t");
$this->getWriter()->setIndent(true);
$this->getWriter()->startElement('urlset');
if ($this->getIsSchemaMore()) {
$this->getWriter()->writeAttribute('xmlns:xsi', self::SCHEMA_XMLNS_XSI);
$this->getWriter()->writeAttribute('xsi:schemaLocation', self::SCHEMA_XSI_SCHEMALOCATION);
}
$this->getWriter()->writeAttribute('xmlns', self::SCHEMA_XMLNS);
}
// 写入item元素url、loc、priority字段必选changefreq、lastmod可选
public function addItem($loc, $priority = self::DEFAULT_PRIORITY, $changefreq = NULL, $lastmod = NULL)
{
if (($this->getCurrentItem() % self::SITEMAP_ITEMS) == 0) {
if ($this->getWriter() instanceof \XMLWriter) {
$this->endSitemap();
}
$this->startSitemap();
$this->incCurrentSitemap();
}
$this->incCurrentItem();
$this->getWriter()->startElement('url');
$this->getWriter()->writeElement('loc', $loc); // 必选
$this->getWriter()->writeElement('priority', $priority); // 必选
if ($changefreq) {
$this->getWriter()->writeElement('changefreq', $changefreq); // 可选
}
if ($lastmod) {
$this->getWriter()->writeElement('lastmod', $this->getLastModifiedDate($lastmod)); // 可选
}
$this->getWriter()->endElement();
return $this;
}
// 转义时间格式,返回时间格式为 2021-09-12
private function getLastModifiedDate($date = null)
{
if (null == $date) {
$date = time();
}
if (ctype_digit($date)) {
return date('Y-m-d', $date); // Y-m-d
} else {
$date = strtotime($date);
return date('Y-m-d', $date);
}
}
// 结束网站xml文档配合开始xml文档使用
public function endSitemap()
{
if (!$this->getWriter()) {
$this->startSitemap();
}
$this->getWriter()->endElement();
$this->getWriter()->endDocument();
$this->getWriter()->flush();
}
public function createSitemapIndex($loc, $lastmod = 'Today')
{
$indexwriter = new XMLWriter();
$indexwriter->openURI($this->getXmlFile() . self::SITEMAP_SEPERATOR . self::INDEX_SUFFIX . self::SITEMAP_EXT);
$indexwriter->startDocument('1.0', 'UTF-8');
$indexwriter->setIndent(true);
$indexwriter->startElement('sitemapindex');
$indexwriter->writeAttribute('xmlns:xsi', self::SCHEMA_XMLNS_XSI);
$indexwriter->writeAttribute('xsi:schemaLocation', self::SCHEMA_XSI_SCHEMALOCATION);
$indexwriter->writeAttribute('xmlns', self::SCHEMA_XMLNS);
for ($index = 0; $index < $this->getCurrentSitemap(); $index++) {
$indexwriter->startElement('sitemap');
$indexwriter->writeElement('loc', $loc . $this->getFilename() . ($index ? self::SITEMAP_SEPERATOR . $index : '') . self::SITEMAP_EXT);
$indexwriter->writeElement('lastmod', $this->getLastModifiedDate($lastmod));
$indexwriter->endElement();
}
$indexwriter->endElement();
$indexwriter->endDocument();
}
}