1

this is my code for adding a new entry at the end of a sitemap file:

$add_info="
 <url>
 $token
 <lastmod>$date</lastmod>
 </url>
</urlset>";
$end_string = "</urlset>";
$length_end_string = strlen($end_string);
fseek($handle, -$length_end_string, SEEK_END);
fwrite($handle, $add_info);

Which works alright but sometimes messes up the end of the file like for example:

<url>
 <loc>http://example.com/url1.html</loc>
 <lastmod>2011-08-31</lastmod>
 </url>
</url<url>
 <loc>http://example.com/url2.html</loc>
 <lastmod>2011-08-28</lastmod>
 </url>
</urls<url>

Could a reason for this be that php parser is unable to reach the end of file properly?

Artefacto
  • 96,375
  • 17
  • 202
  • 225
Nevyan
  • 11
  • 1
  • 2
    possible duplicate of [A simple program to CRUD node and node values of xml file](http://stackoverflow.com/questions/4906073/a-simple-program-to-crud-node-and-node-values-of-xml-file) – Gordon Sep 06 '11 at 15:19

3 Answers3

1

Add a call to flock (with LOCK_EX) after opening the file. This will prevent intermingled writes due to concurrency.

Artefacto
  • 96,375
  • 17
  • 202
  • 225
1

I think that the cause of the problem is simply that you have

</urlset>

in the $add_info variable.

it should not contain a closing to the urlset.

Also, trying counting the char manually and put the hard coded negative number in the parameter and see what happens. (something interesting might come from that)

Hassan Al-Jeshi
  • 1,450
  • 2
  • 15
  • 20
1

With a properly set up file, this should work, HOWEVER, you are blindly rewinding 9 characters, so if there is extra white space at the end of the file, this will break. The fact that your urlset close tag is truncated two different ways might be a hint that your file does not conform to your expectation.

You might look into ways to validate your file pointer position or use an xml library as mentioned in the comment on your Q.

horatio
  • 1,426
  • 8
  • 7
  • could you be more specific one the validating the pointer position ? – Nevyan Sep 06 '11 at 18:48
  • as a quick idea, not elegant, just off the top of my head: seek the end of file, and then read (backwards) 1 byte at a time into a buffer of size `$length_end_string` until the buffer matches `$end_string`. – horatio Sep 06 '11 at 19:44