views:

86

answers:

2

Hi there, I have been trying to get my head around how simplexml and dom updates XML between functions. The reason i ask is that the code i have written seems to work, but without me having to declare anything as global, and im a little confused as to why it does this.

For example, i have this (simplified) code:

<?

foreach ($filenames as $filename) {
    $xml = simplexml_load_file($filename);
    updateXml($xml);
    $xml->last_update = date('Y-m-d H:i:s');
    $xml->asXML($filename);
}

function updateXml($xml) {
    //...
    if ($data = $xml->xpath('//data/info[product_id="' . $product_data['id'] . '"]')) {
        $parent = $data[0]->xpath("parent::*");
        $data = updateItem($parent[0], $product_data);
    } else {
        $product = addItem($xml->products, $product_data['id']);
        $data = updateItem($product, $product_data);
    }
}

function updateItem($parent, $product_data) {

    $node = dom_import_simplexml($parent);
    $dom = $node->ownerDocument;

    $product = $dom->createElement('product');
    $node->appendChild($product);
    $item = $dom->createElement('id', $product_data['id']);
    $product->appendChild($item);
    $item = $dom->createElement('name', $product_data['name']);
    $product->appendChild($item);
    $item = $dom->createElement('url');
    $product->appendChild($item);
    $cdata = $dom->createCDATASection($product_data['url']);
    $item->appendChild($cdata);
    $item = $dom->createElement('price', $product_data['price']);
    $product->appendChild($item);

    return $node;
}

?>

Can you please help me understand how the XML is being updated between the functions without needing to declare it as global? I know it seems strange to ask about something that works, but i need to get my head around it :-)

Thanks

+1  A: 

You are passing a copy of the instance of an object through each of your functions.

You can think of parameter passing as sharing the same instance of an object to each of your functions, opposed to declaring it global.

Anthony Forloney
Ok interesting, thanks for the reply. So if i update just one part of the xml, it will apply to the whole object? Also, do i need to retun $node in the final function, is it required?
Peter John
If you update one part of the xml inside the `$filename` it would apply to the object. Depending on how your code will be used depends on when to return variables. If you want to do something with that `$node`, such as `echo` the `$node` in `updateItem`, it will `echo` because it is returned.
Anthony Forloney
Ok great! So if i just want to use updateItem to modify the xml, the save using asXML, i dont need to return anything from the function?
Peter John
Look at this line, `$data = updateItem($product, $product_data);`, you are setting `$data` to be the value returned from calling `updateItem` so you would need to return `$node` in this situation.
Anthony Forloney
Ok i understand much better now, thanks for your help, really appreciate it!
Peter John
A: 

You think you're only passing the nodes that you stored in $product (or other var): you're not. You're passing the original object, with some parameters set about a selected nodeset.

dnagirl
Ahhh ok, so as long as i pass something back which relates to a part of $xml, i will be ok?
Peter John