File problem

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
jdanthinne
Forum Newbie
Posts: 4
Joined: Sun Feb 09, 2003 2:35 pm

File problem

Post by jdanthinne »

I've written a little guestbook script with PHP and XML, and everything was fine untill a few days ago... there are many articles now, but sometimes, words are deleted in in the first articles. It is not a problem of writing the file because the XML structure is still good, but the content of the tags change... Stange... i've put locks, but it doesn't change anything...

The Code (the essential part of it):

<?php
class xItem {
var $xDate;
var $xNom;
var $xEmail;
var $xTexte;
}

$arItems = array();
$itemCount = -1;
$uFile = "guestbook.xml";

function startElement($parser, $name, $attrs) {
global $curTag;
$curTag .= "^$name";
}

function endElement($parser, $name) {
global $curTag;
$caret_pos = strrpos($curTag,'^');
$curTag = substr($curTag,0,$caret_pos);
}

function characterData($parser, $data) {
global $curTag, $arItems, $itemCount;
$itemDate = "^MSGS^MSG^DATE";
$itemNom = "^MSGS^MSG^NOM";
$itemEmail = "^MSGS^MSG^EMAIL";
$itemTexte = "^MSGS^MSG^TEXTE";

if ($curTag == $itemDate) {
$itemCount++;
$arItems[$itemCount] = new xItem();
$arItems[$itemCount]->xDate = $data;
}
elseif ($curTag == $itemNom) {
$arItems[$itemCount]->xNom = $data;
}
elseif ($curTag == $itemEmail) {
$arItems[$itemCount]->xEmail = $data;
}
elseif ($curTag == $itemTexte) {
$arItems[$itemCount]->xTexte = $data;
}
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($uFile,"r"))) {
die ("could not open XML file to read");
}
flock($fp,1);
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)));
}
}
xml_parser_free($xml_parser);
flock($fp,3);
fclose($fp);

if (!($fp = fopen($uFile,"w"))) {
die ("could not open XML file to write");
}
flock($fp,2);
fwrite($fp,"<msgs>\n");
fwrite($fp,"<msg>\n<date><![CDATA[".date ("d/m/y")."]]></date>\n<texte><![CDATA[");
fwrite($fp,$HTTP_GET_VARS["texte"]);
fwrite($fp,"]]></texte>\n");
if (strlen($HTTP_GET_VARS["nom"]) != 0) {
fwrite($fp,"<nom><![CDATA[");
fwrite($fp,$HTTP_GET_VARS["nom"]);
fwrite($fp,"]]></nom>\n");
}
if (strlen($HTTP_GET_VARS["email"]) != 0) {
fwrite($fp,"<email><![CDATA[");
fwrite($fp,$HTTP_GET_VARS["email"]);
fwrite($fp,"]]></email>\n");
}
fwrite($fp,"</msg>\n");
for ($i=0;$i<count($arItems);$i++) {
$txItem = $arItems[$i];
fwrite($fp,"<msg>\n<date><![CDATA[");
fwrite($fp,$txItem->xDate);
fwrite($fp,"]]></date>\n<texte><![CDATA[");
fwrite($fp,$txItem->xTexte);
fwrite($fp,"]]></texte>\n");
if (strlen($txItem->xNom) != 0) {
fwrite($fp,"<nom><![CDATA[");
fwrite($fp,$txItem->xNom);
fwrite($fp,"]]></nom>\n");
}
if (strlen($txItem->xEmail) != 0) {
fwrite($fp,"<email><![CDATA[");
fwrite($fp,$txItem->xEmail);
fwrite($fp,"]]></email>\n");
}
fwrite($fp,"</msg>\n");
}
fwrite($fp,"</msgs>");
flock($fp,3);
fclose($fp);
?>
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

i didn't get exactly what the problem was, the content in the file is changed?

just a note ragrding flock, as far as I know flock is based on process id, so if you had simultaneous access to your script thru apache with mod_php this could be the same process, try run the script as a cgi instead, that will start one process for all instances of the script, and flock will be more reliable..

btw, wouldnt it have been more efficient to store the data in a relational database, and then when you need XML output just use some functions to produce that from the data, perhaps with caching..
jdanthinne
Forum Newbie
Posts: 4
Joined: Sun Feb 09, 2003 2:35 pm

Post by jdanthinne »

<msg>
<date><![CDATA[20/01/03]]></date>
<texte><![CDATA[Patience! <br>A+ les gars et bonne chance... ]]></texte>
<nom><![CDATA[jULES]]></nom>
<email><![CDATA[stardust@proximus.be]]></email>
</msg>

becomes :

<msg>
<date><![CDATA[20/01/03]]></date>
<texte><![CDATA[ars et bonne chance... <br>jULES]]></texte>
<nom><![CDATA[jULES]]></nom>
<email><![CDATA[stardust@proximus.be]]></email>
</msg>

I can't use a database, because it isn't available on the server... and i need XML for Flash.
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

I haven't studied your code in depth, but does it handle multiple/split cdata strings, putting them back together, if it is split by the 4096 byte count or by multiple cdata finds on the same tag/level from the parser?
jdanthinne
Forum Newbie
Posts: 4
Joined: Sun Feb 09, 2003 2:35 pm

the 4096 bytes thing

Post by jdanthinne »

In fact, to be honest, it's a code i've download and i've changed many things, but not the parser code and i don't know why there a 4096bytes count... Do you think i can remove it? How?
I'm not a PHP expert. I just use it to expand Flash capabilities...
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

the byte count is not a "bad" or wrong thing, its is just ment to limit how much you read from the file to memory at the time, in case it was a 10Megabyte file you don't use more than 4K memory for the data..

Myself I would have thought the parsing would fail if it was more than 4K, as you run xml_parse on incomplete data...

The other concern was about thye cdata being broken apart, depnding on the parser settings it will often break with newline..

--

But, perhaps a better approach to this would be if you explain what data you are getting and where you get it from, what to do with it and how/where to put it, then we can try figure out the right way to do it :)

Does flash require the comment-cdata tag like that? it should have been able to use plain cdata, with stanard entities converted (the < and > and such)..
jdanthinne
Forum Newbie
Posts: 4
Joined: Sun Feb 09, 2003 2:35 pm

Fixed

Post by jdanthinne »

I've fixed the problem (i think). I've replaced 4096 abd i've put filesize($uFile). It reads the entire file... Seems to work... thanks...
Post Reply