Differences in setting values ​​in SimpleXML and foreach loop

Answering the previous question, I found the following behavior that I cannot understand. The following code shows the problem ...

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

$data = <<< XML
<?xml version="1.0" standalone="yes"?>
<Base>
    <Data>
        <Value></Value>
    </Data>
</Base>
XML;

$xml = simplexml_load_string($data);
foreach ( $xml->Data->Value as $value ) {
    $value = 1;
}
echo $xml->asXML().PHP_EOL;
foreach ( $xml->Data as $value ) {
    $value->Value = 1;
}
echo $xml->asXML().PHP_EOL;

I expect the output at each point to be the same, but the output will be ...

<?xml version="1.0" standalone="yes"?>
<Base>
    <Data>
        <Value/>
    </Data>
</Base>

<?xml version="1.0" standalone="yes"?>
<Base>
    <Data>
        <Value>1</Value>
    </Data>
</Base>

Thus, this indicates that the first cycle that directly accesses the element <Value>does not set a value, and yet the second cycle that indirectly accesses it works fine.

What is the difference?

+4
source share
1 answer

The difference has nothing to do with loops or links, but with what exactly means =in each case.

The first version can be simplified:

$value = $xml->Data->Value;
$value = 1;

, , . , $xml .


:

$data = $xml->Data;
$data->Value = 1;
// Or just $xml->Data->Value = 1;

, , , - . SimpleXML libxml XML . , $data->setValueOfChild('Value', 1);.


, :

$value =& $xml->Data->Value;
$value = 1;

$value , 1 . , , SimpleXML.


, : , SimpleXMLElement , $foo->NameThatOccursMoreThanOnce[3] $some_element['Attribute']. , :

$value = $xml->Data->Value;
$value[0] = 1;

$value - SimpleXMLElement, $value[0] = 1 - $value->setValueOfItem(0, 1).

, <Value> <Data>; , , [0] , :

$value = $xml->Data->Value[0];
$value[0] = 1;

, , ! __get, __set __unset , ArrayAccess.

+2

Source: https://habr.com/ru/post/1691692/


All Articles