我正在尝试自动化网站上的sitemap.xml文件,因为内容不断变化。我当前打开文件以追加:fopen($file_name, 'a');
,以便我可以添加新的标记集。但是,我只是注意到整个站点地图文件必须以标签结束,这意味着每次打开文件时,我都需要将文本追加到文件的末尾,而不是从末尾追加到1行。 / p>
基本上,在打开文件后如何移动文件指针以便我可以实现这个目的?感谢。
更新:以下是网站地图的样子:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">
<url>
<loc>...</loc>
<lastmod>2009-08-23</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
</urlset>
所以每当我追加时,我都需要添加必须在结束<url>..</url>
标记之前的</urlset>
部分。我已经有了可以将xml附加到文件末尾的代码。我只需要弄清楚如何在结束标记之前附加新部分。
答案 0 :(得分:7)
使用php fseek()寻找文件的末尾(使用filesize()查找),然后向后迭代一行。读取最后一行并暂时存储它。用您要插入的内容覆盖最后一行,然后附加先前存储的临时行。
要向后迭代一行,请使用fseek与fgetc()
结合使用$offset = filesize($fhandle) - 1;
fseek($fhandle, $offset--); //seek to the end of the line
while(fgetc($fhandle) != '\n') {
fseek($fhandle, $offset--);
}
现在你的内部文件指针应该指向最后一行之前的一行。当然,当你的文件只有一行时,你将不得不处理极端情况,但我会让你弄清楚细节;)
现在将最后一行存储在tmp变量
中$lastline = fgets($fhandle);
fseek($fhandle, $offset); //go back to where the last line began
插入您的行,并在文件末尾附加最后一行
fwrite($fhandle, $myLine);
fwrite($fhandle, $lastline);
答案 1 :(得分:3)
如果没有看到你正在谈论的XML,并且不知道你想要添加什么(请提供这些以获得完整的编码答案),我可以建议这种方法...
正如我所说,如果没有看到XML或更多代码,很难提供和回答
答案 2 :(得分:1)
加入Charles Ma的答案。您可以将其保存在名为sitemapper.php
的文件中,并使用GET查询调用此文件,但我建议您添加更多安全性,如果您可能有并发写入,则建议使用flock()。
使用它的另一个原因是如果您使用的是没有SimpleXMLParser的PHP4。
<?php
/*--------------------------------------------------------
==================
sitemapper.php 1.0
==================
Pass me a path to a page, and I will add it to your XML sitemap.
Paths are passed from root, as
www.example.com/sitemapper.php?path=/test/index.html
for a page at http://www.example.com/test/index.html
This script is faster than parsing XML, for large sitemaps.
--------------------------------------------------------*/
if (isset($_GET[path])) {
// Get the path to the new page to add to our sitemap.
$fname = urldecode($_GET[path]);
// Real path to files is different on some hosts.
$current_path = realpath(dirname(__FILE__));
if (!is_file("./sitemap.xml")){
$xml = '';
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"."\n";
$xml .= "<urlset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\" xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">"."\n";
$xml .= "</urlset>"."\n";
$sitemap = fopen("./sitemap.xml", "x");
fwrite($sitemap, $xml);
fclose($sitemap);
}
// Write sitemap.xml entry for current file
// This is a very old-school 'C' style of doing it.
// The modern way would be to open the file in an XML parser,
// add the elements you want, serialise it to a new file
// and swap them over (so that nothing reads the XML in
// the middle of you writing it)
//
// However I expect this XML file to become *huge* shortly
// So I am avoiding use of the PHP XML Parser.
$date = date('Y-m-dTH:i:sP', time()); //Date in w3c format for XML sitemaps
$xml = '';
$xml .= "<url>"."\n";
$xml .= " <loc>http://". $_SERVER["HTTP_HOST"] . $fname . "</loc>"."\n";
$xml .= " <lastmod>" . $date . "</lastmod>"."\n";
$xml .= " <priority>0.50</priority>"."\n";
$xml .= " <changefreq>never</changefreq>"."\n";
$xml .= "</url>"."\n";
if ($sitemap = @fopen("./sitemap.xml", "r+"))
{
// seek to the end of the file, then iterate backwards one line.
// read the last line and store it temporarily. overwrite the
// last line with what you want to insert, then append the
// temporary line you stored previously.
$offset = filesize("./sitemap.xml") - 1;
fseek($sitemap, ($offset - 1)); //seek to before the last character in the file
while( (($char = fgetc($sitemap)) !== "\n") && ($offset > -2000) && ($offset < 2000)) {
// Go backwards, trying to find a line-break.
// The offset range is just a sanity check if something goes wrong.
$offset = $offset - 1;
fseek($sitemap, $offset);
}
$offset = $offset + 1; // Come to the beginning of the next line
fseek($sitemap, $offset);
$lastline = fgets($sitemap); // Copy the next line into a variable
fseek($sitemap, $offset); //go back to where the last line began
fwrite($sitemap, $xml); // add the current entry
fwrite($sitemap, $lastline); // add the </urlset> line back.
fclose($sitemap);
}
}
?>
答案 3 :(得分:0)
保留文件的两个版本:站点地图和没有结束标记的tmp。 当你想扩展时,首先扩展tmp一个;然后将其复制到sitemap,并在那里添加结束标记。
答案 4 :(得分:0)
fseek($ fp,-n,SEEK_END);,但您必须将文件打开为“r +”而不是“a”。
像这样处理XML通常不是一个好主意;依赖于精确的字节位置是非常脆弱的。更好的方法是在XML解析器中打开文件,添加所需的元素,将其序列化为新文件并将其交换(以便在编写它时不会读取XML)。
在数据库支持的站点上,您还可以考虑使用PHP本身动态生成站点地图XML。