保存Sitemap XML文件每个文件限制1000个URL

Yaa*_*ssa 1 php xml sitemap foreach for-loop

如何保存多个站点地图文件,每个文件限制为1000个URL,如sitemap1.xml,sitemap2.xml

基本上我想限制foreach每个文件put_file_content.

我的代码是:

$sitemap = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
    <urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">
    <url>
    <loc>". Yii::app() -> getBaseUrl(true) ."</loc>
    <priority>1</priority>
    </url>
";
foreach($websites as $website) {
    $sitemap .= "<url>
        <loc>".$website['domain']."</loc>
        <priority>0.5</priority>
        </url>
    ";
}
$sitemap .= "</urlset>";
file_put_contents("sitemap.xml", $sitemap, LOCK_EX);
Run Code Online (Sandbox Code Playgroud)

hak*_*kre 5

让我们快速创建该应用程序:

  1. 创建一些您添加网站的模板XML.
  2. $websitesa NoRewindIterator和a 的帮助下大块化LimitIterator

让我们从第二点开始,并创建这个伪造URL和XML,只是为了看看这是否容易接线:

$limit = 3;

$urls = new ArrayIterator(range(0, 9)); // 10 Fake URLs
$urls->rewind();

$it = new NoRewindIterator($urls);
Run Code Online (Sandbox Code Playgroud)

首先,我们为每个文件设置一个限制(此处为三个以保持低测试),然后我们设置URL的数据源.这些是10个虚假URL,只是从0到9的数字.

那些URL被重绕了,因为它们被包装成a NoRewindIterator并且那个永远不会倒带但是我们想要倒回数据源一次(这对于所有迭代器来说都不是必需的,但是对于相当多的因此我们这样做是正确的).

倒带操作被阻止,NoRewindIterator以便我们可以继续获得X块的大小$limit.这正是现在所做的:

$fileCounter = 0;
while ($it->valid()) {    
    $fileCounter++;

    printf("File %d:\n", $fileCounter);

    $websites = new LimitIterator($it, 0, $limit);
    foreach($websites as $website) {
        printf(" * Website: %s\n", $website);
    }
}
Run Code Online (Sandbox Code Playgroud)

只要$it有效(读取:只要有要输出的URL),就会创建一个新文件(从一开始),然后通过该文件预览三个网站LimitIterator.完成该迭代后,将继续进行,直到所有网站URL都已消耗完为止.输出如下:

File 1:
 * Website: 0
 * Website: 1
 * Website: 2
File 2:
 * Website: 3
 * Website: 4
 * Website: 5
File 3:
 * Website: 6
 * Website: 7
 * Website: 8
File 4:
 * Website: 9
Run Code Online (Sandbox Code Playgroud)

到目前为止,这显示了如何进行分块(有时这也称为分页).如示例所示,仅缺少有关创建XML文档的部分.

要创建XML文档,您可以连接一个字符串,但是,我们不这样做.我们使用现有的库来完成这一切.该库名为DOMDocument,以下是如何在urlset中创建具有两个示例性位置的站点地图文件的示例:

$doc = new DOMDocument();
$doc->formatOutput = TRUE;

$nsUri    = 'http://www.sitemaps.org/schemas/sitemap/0.9';
$urlset = $doc->appendChild($doc->createElementNS($nsUri, 'urlset'));

$url = $doc->createElementNS($nsUri, 'url');
$location = $url->appendChild($doc->createElementNS($nsUri, 'loc', 'BASEURL'));
$priority = $url->appendChild($doc->createElementNS($nsUri, 'priority', '1'));

$urlset->appendChild(clone $url);

$priority->nodeValue = '0.5';
$location->nodeValue = 'TEST';
$urlset->appendChild(clone $url);

echo $doc->saveXML();
Run Code Online (Sandbox Code Playgroud)

此代码示例演示如何创建文档,然后如何使用适当的命名空间添加元素.它还展示了如何<url>通过克隆来创建可以轻松修改和添加的样板元素.

这个例子的输出是:

<?xml version="1.0"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>BASEURL</loc>
    <priority>1</priority>
  </url>
  <url>
    <loc>TEST</loc>
    <priority>0.5</priority>
  </url>
</urlset>
Run Code Online (Sandbox Code Playgroud)

所以现在所有的一般问题都已经解决了.所需要的只是将这两者结合在一起并存储到磁盘.为了这个例子,我省略了后面的部分(您只需将文件名作为参数传入saveXML)并输出XML:

<?php
/**
 * Save Sitemap XML Files Limit by 1000 URLs per each File
 *
 * @link https://stackoverflow.com/q/19750485/367456
 */

$limit = 3;

$urls = new ArrayIterator(range(0, 9)); // 10 Fake URLs
$urls->rewind();

$it = new NoRewindIterator($urls);

$fileCounter = 0;

$baseDoc               = new DOMDocument();
$baseDoc->formatOutput = TRUE;

$nsUri = 'http://www.sitemaps.org/schemas/sitemap/0.9';

while ($it->valid()) {
    $fileCounter++;

    $doc = clone $baseDoc;

    $urlset = $doc->appendChild($doc->createElementNS($nsUri, 'urlset'));
    $url    = $doc->createElementNS($nsUri, 'url');

    $location = $url->appendChild($doc->createElementNS($nsUri, 'loc', 'BASEURL'));
    $priority = $url->appendChild($doc->createElementNS($nsUri, 'priority', '1'));

    $urlset->appendChild(clone $url);
    $priority->nodeValue = '0.5';

    printf("File %d:\n", $fileCounter);

    $websites = new LimitIterator($it, 0, $limit);
    foreach ($websites as $website) {
        $location->nodeValue = $website;
        $urlset->appendChild(clone $url);
    }

    echo $doc->saveXML();
}
Run Code Online (Sandbox Code Playgroud)

然后输出是XML而不是纯文本:

File 1:
<?xml version="1.0"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>BASEURL</loc>
    <priority>1</priority>
  </url>
  <url>
    <loc>0</loc>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>1</loc>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>2</loc>
    <priority>0.5</priority>
  </url>
</urlset>
File 2:
<?xml version="1.0"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>BASEURL</loc>
    <priority>1</priority>
  </url>
  <url>
    <loc>3</loc>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>4</loc>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>5</loc>
    <priority>0.5</priority>
  </url>
</urlset>
File 3:
<?xml version="1.0"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>BASEURL</loc>
    <priority>1</priority>
  </url>
  <url>
    <loc>6</loc>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>7</loc>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>8</loc>
    <priority>0.5</priority>
  </url>
</urlset>
File 4:
<?xml version="1.0"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>BASEURL</loc>
    <priority>1</priority>
  </url>
  <url>
    <loc>9</loc>
    <priority>0.5</priority>
  </url>
</urlset>
Run Code Online (Sandbox Code Playgroud)

所以剩下要做的就是在最开始时提供原始数据源作为迭代器,将URL数量(限制)增加到自己的值,并为每个添加正确的Base-URL每个文件(如果你真的需要).

就XML Sitemaps而言,您还可以创建一个链接其他文件的文件.IIRC的限制有点高,与以下内容相比:多个站点地图:robots.txt中的条目?.

我希望这可以帮助您以完善的方式实现您所寻求的目标.