【问题标题】:Save Sitemap XML Files Limit by 1000 URLs per each File将站点地图 XML 文件限制为每个文件 1000 个 URL
【发布时间】:2013-11-14 01:18:01
【问题描述】:

如何保存多个站点地图文件,每个文件受限于 1000 个 URL,例如 sitemap1.xmlsitemap2.xml

基本上我想通过put_file_content来限制foreach每个文件。

我的代码是:

$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);

【问题讨论】:

    标签: php xml for-loop foreach sitemap


    【解决方案1】:

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

    1. 创建一些模板 XML,您可以在其中添加网站。
    2. NoRewindIteratorLimitIterator 的帮助下将$websites 分块

    让我们从第二点开始,创建这个伪造的 URL 和 XML,看看这是否容易连接:

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

    首先我们为每个文件设置一个限制(这里三个以保持较低的测试),然后我们为 URL 设置数据源。这里有 10 个假网址,只是从零到九的数字。

    这些 URL 被重绕,因为它们随后被包装到 NoRewindIterator 中,并且永远不会重绕,但我们想重绕数据源一次(这不是所有迭代器都必需的,但对于相当多的迭代器,所以我们这样做是正确的)。

    回退操作被NoRewindIterator 阻止,这样我们就可以继续获取$limit 大小的X 个块。这正是现在所做的:

    $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);
        }
    }
    

    只要$it 有效(阅读:只要有要输出的 URL),就会创建一个新文件(从一个开始),然后通过LimitIterator 对三个网站进行 foreach 编辑。当该迭代完成时,它会继续进行,直到所有网站 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
    

    到目前为止,这显示了如何进行分块(或者有时这也称为分页)。如示例所示,仅缺少有关创建 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();
    

    此代码示例展示了如何创建文档,然后如何将元素及其适当的命名空间添加到其中。它还展示了如何创建样板文件 &lt;url&gt; 元素,可以通过克隆轻松修改和添加它。

    那么这个例子的输出是:

    <?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>
    

    所以现在所有的一般问题都已经解决了。所需要的只是将这两者连接在一起并存储到磁盘上。为了这个例子,我省略了后面的部分(你只需将文件名作为参数传递给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();
    }
    

    然后输出是 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>
    

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

    就 XML 站点地图而言,您还可以创建一个文件来链接其他文件。 IIRC 的限制要高一些,与 Multiple Sitemap: entries in robots.txt? 相比。

    我希望这可以帮助您以一种成熟的方式实现您正在寻找的东西。

    【讨论】:

      【解决方案2】:

      您可以尝试一个 for 循环( for ( $x = 0 ; $x

      $i = 1;
      foreach ($websites as $website)
      {
      if ($i === 1000) break;
      $i++;
      
      #do your thing
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 1970-01-01
        • 2023-01-09
        相关资源
        最近更新 更多