class variables not sticking?
Posted: Fri Feb 02, 2007 2:02 am
OK - I'm beating my head against the wall on this one:
I'm extending the stock DOM classes in php5 to add db save and load functions, plus an extra element type:
A Thing is a special class of element that I've defined to group sets of elements. A Thing is also just an element.
Saving and loading works fine, I've even managed to get Thing caching working.
The Problem
When I save an existing node, there doesn't seem to be any way of verifying the node_id property of the node, nor can I getAttribute('node_id'). This leads my program to believe it's a new node and creates a duplicate node for it. Oddly enough, this is only true for child nodes of the Thing.
I hope one of you who is more class savvy can tell me what I'm doing wrong... and I have a feeling that will be Hockey for some reason
All Files+SQL: http://kieran.ca/www.rar
Snippet from the Thing class:
The XML it's loading / saving:
Thanks for getting this far!
Kieran
I'm extending the stock DOM classes in php5 to add db save and load functions, plus an extra element type:
A Thing is a special class of element that I've defined to group sets of elements. A Thing is also just an element.
Saving and loading works fine, I've even managed to get Thing caching working.
The Problem
When I save an existing node, there doesn't seem to be any way of verifying the node_id property of the node, nor can I getAttribute('node_id'). This leads my program to believe it's a new node and creates a duplicate node for it. Oddly enough, this is only true for child nodes of the Thing.
I hope one of you who is more class savvy can tell me what I'm doing wrong... and I have a feeling that will be Hockey for some reason
All Files+SQL: http://kieran.ca/www.rar
Snippet from the Thing class:
Code: Select all
function save(){
global $doc, $db, $xpath;
// save this element
$this->saveNode($this);
// if this is a thing, build the cache
if($this->parentNode === $doc->root){
// get XML
$rawxml = $doc->saveXML($this);
// save it as a file in the cache dir
if($rawxml){
touch(THING_CACHE.$this->thing_id);
file_put_contents(THING_CACHE.$this->thing_id,$rawxml);
}
}
}
function saveNode($n){ // until I can upgrade to php 5.2.0
global $doc, $db, $xpath;
MySQL_select_db('allyourbase',$db) or die(MySQL_error($db));
// is this a Thing?
if($n->parentNode === $doc->root) $this->saveThing($n);
// if element doesn't exist, make it
// problem area begins
// neither of these work...
if(!$n->getAttribute('node_id')){
// if(!isset($n->node_id)){
// problem area ends
// only continue if the parent is NOT the doc root
if($n->parentNode !== $doc->root){
// if the parent has no node_id, save it before continuing
if(!$n->parentNode->node_id) $n->parentNode->save();
//now get the parent_node_id
$fields['parentNode'] = $n->parentNode->node_id;
}
// populate other info
if(isset($n->parentNode->thing_id)) $n->thing_id = $n->parentNode->thing_id;
$fields['thing'] = @$n->thing_id;
$fields['nodeType'] = @$n->nodeType;
$fields['created'] = $n->node_created = time();
// prepare query field names and values
foreach($fields as $field=>$value){
$query['fields'][]=$field;
$query['values'][]=mysql_real_escape_string($value);
}
// query-encode the names and values
$fields = "`".implode("`,`",$query['fields'])."`";
$values = "'".implode("','",$query['values'])."'";
// create the node
$result = MySQL_query("INSERT INTO nodes ({$fields}) VALUES ({$values})",$db) or die('line:'.__LINE__.', can\'t save node: '.MySQL_error());
unset($query,$fields);
// now fetch the node's shiny new id
$n->node_id = MySQL_insert_id($db);
}
// what kind of node is this?
switch($n->nodeType){
case XML_ELEMENT_NODE: // Node is a DOMElement
$this->saveElement($n);
if($n->parentNode == $doc->root) $n->setAttribute('thing_id',@$n->thing_id);
$n->setAttribute('element_id',@$n->element_id);
$n->setAttribute('node_id',@$n->node_id);
// echo 'node '.$n->node_id.'<br/>';
// $n->setAttribute('created',@$n->created);
// $n->setAttribute('modified',@$n->modified);
break;
case XML_ATTRIBUTE_NODE: // Node is a DOMAttr
$this->saveAttr($n);
break;
case XML_TEXT_NODE: // Node is a DOMText
$this->saveText($n);
break;
case XML_CDATA_SECTION_NODE: // Node is a DOMCharacterData
$this->saveCData($n);
break;
default: // no nodeType? I doubt this is possible, but it shoudl definitely error out.
die('There\'s no nodeType! The sky is falling!');
break;
}
// save each child to the DB
if(!is_null($n->childNodes)) for($i=0;$i<$n->childNodes->length;$i++){
// save the element
$this->saveNode($n->childNodes->item($i));
}
// save each attribute to the DB
if(!is_null($n->attributes)) for($i=0;$i<$n->attributes->length;$i++){
// save the attribute
if(!property_exists($n,$n->attributes->item($i)->name)) $this->saveAttr($n->attributes->item($i));
}
}Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<xml>
<stop thing_id="4" node_id="46" element_id="25" node_created="1170387040" element_modified="1170387040" thing_name="stop">
<name element_id="26" node_id="47" node_created="1170387040" element_modified="1170387040">Lawrence West</name>
<lat element_id="27" node_id="49" node_created="1170387040" element_modified="1170387040">43.71572083597938</lat>
<lon element_id="28" node_id="51" node_created="1170387040" element_modified="1170387040">-79.44428443908691</lon>
<street element_id="29" node_id="53" node_created="1170387040" element_modified="1170387040">655 Lawrence Ave. West</street>
<city element_id="30" node_id="55" node_created="1170387040" element_modified="1170387040">Toronto</city>
<region element_id="31" node_id="57" node_created="1170387040" element_modified="1170387040">Ontario</region>
<country element_id="32" node_id="59" node_created="1170387040" element_modified="1170387040">Canada</country>
</stop>
<stop thing_id="61" node_id="901" element_id="481" node_created="1170387042" element_modified="1170387042" thing_name="stop">
<name element_id="482" node_id="902" node_created="1170387042" element_modified="1170387042">Lawrence East</name>
<lat element_id="483" node_id="904" node_created="1170387042" element_modified="1170387042">43.75051320325138</lat>
<lon element_id="484" node_id="906" node_created="1170387042" element_modified="1170387042">-79.27056312561035</lon>
<street element_id="485" node_id="908" node_created="1170387042" element_modified="1170387042">2444 Lawrence Ave. East</street>
<city element_id="486" node_id="910" node_created="1170387042" element_modified="1170387042">Toronto</city>
<region element_id="487" node_id="912" node_created="1170387042" element_modified="1170387042">Ontario</region>
<country element_id="488" node_id="914" node_created="1170387042" element_modified="1170387042">Canada</country>
</stop>
<stop thing_id="26" node_id="376" element_id="201" node_created="1170387041" element_modified="1170387041" thing_name="stop">
<name element_id="202" node_id="377" node_created="1170387041" element_modified="1170387041">Lawrence</name>
<lat element_id="203" node_id="379" node_created="1170387041" element_modified="1170387041">43.72483950684785</lat>
<lon element_id="204" node_id="381" node_created="1170387041" element_modified="1170387041">-79.40179824829102</lon>
<street element_id="205" node_id="383" node_created="1170387041" element_modified="1170387041">3101 Yonge St.</street>
<city element_id="206" node_id="385" node_created="1170387041" element_modified="1170387041">Toronto</city>
<region element_id="207" node_id="387" node_created="1170387041" element_modified="1170387041">Ontario</region>
<country element_id="208" node_id="389" node_created="1170387041" element_modified="1170387041">Canada</country>
</stop>
</xml>Kieran