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

时间:2013-11-03 06:41:37

标签: php xml for-loop foreach sitemap

如何保存多个站点地图文件,每个文件限制为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);

2 个答案:

答案 0 :(得分:5)

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

  1. 创建一些模板XML,您可以在其中添加网站。
  2. 借助$websitesNoRewindIterator
  3. LimitIterator进行分块

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

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

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

    这些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),就会创建一个新文件(从1开始),然后通过{{1}预览三个网站}。完成该迭代后,将继续进行,直到所有网站URL都已消耗完为止。输出如下:

    LimitIterator

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

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

    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
    

    此代码示例演示如何创建文档,然后介绍如何使用适当的命名空间添加元素。它还展示了如何通过克隆来创建可以轻松修改和添加的样板$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(); 元素。

    这个例子的输出是:

    <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> )并输出XML:

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

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

    就XML Sitemaps而言,您还可以创建一个链接其他文件的文件。 IIRC的限制要高一些,与Multiple Sitemap: entries in robots.txt?进行比较。

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

答案 1 :(得分:1)

你可以尝试for循环(for($ x = 0; $ x&lt; 1000; $ x ++){$ websites [$ x]})或者你可以使用外部变量退出foreach循环:< / p>

$i = 1;
foreach ($websites as $website)
{
if ($i === 1000) break;
$i++;

#do your thing

}