php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #74203 unset($element->{0}) on SimpleXMLElement does not work in PHP 7.0+
Submitted: 2017-03-04 11:22 UTC Modified: 2017-03-05 13:12 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: alepane at gmail dot com Assigned:
Status: Re-Opened Package: SimpleXML related
PHP Version: 7.0.16 OS: macOS and linux
Private report: No CVE-ID: None
 [2017-03-04 11:22 UTC] alepane at gmail dot com
Description:
------------
The instruction unset($seg_ref->{0}) works in PHP5.6 but not in PHP7 ... I haven't found this behaviour's change in any doc, so it's probably a bug.

The attached example in PHP 5.6 returns the dom without <seg id="A1"/>, in PHP 7 returns also that element (so the unset is not working).

Using $seg_ref[0] works in both version.

Test script:
---------------
<?php
$data='<data>
    <seg id="A1"/>
    <seg id="A2"/>
    <seg id="A3"/>
    <seg id="A4"/>
    <seg id="A5"/>
</data>';
$doc=new SimpleXMLElement($data);
$seg_ref = $doc->seg;
unset($seg_ref->{0});
echo $doc->asXml();

Expected result:
----------------
<data>
    <seg id="A2"/>
    <seg id="A3"/>
    <seg id="A4"/>
    <seg id="A5"/>
</data>

Actual result:
--------------
<data>
    <seg id="A1"/>
    <seg id="A2"/>
    <seg id="A3"/>
    <seg id="A4"/>
    <seg id="A5"/>
</data>

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-03-04 11:38 UTC] requinix@php.net
-Summary: unset on SimpleXMLElement not working +Summary: unset($element->{0}) on SimpleXMLElement not working -Status: Open +Status: Not a bug
 [2017-03-04 11:38 UTC] requinix@php.net
I wouldn't have expected that to work in the first place - it looks like you're trying to remove a <0/>.
On that note, if I remember correctly there were a few improvements to consistency in PHP 7's SimpleXMLElement, regarding how object (->) and array ([]) notation behaves, so that's probably why your example doesn't work anymore.

Besides that, unset($seg_reg[0]) works in all versions, so I'm calling the other behavior undesirable and therefore this not a bug.
https://3v4l.org/rtSBr
 [2017-03-05 09:58 UTC] alepane at gmail dot com
Ok, fair enough.
But shouldn't this be documentated as a breaking change between PHP5 and PHP7?
 [2017-03-05 10:08 UTC] requinix@php.net
->{0} wasn't supported to begin with; like I said it should have corresponded to a <0> element, but that's not valid XML. The fact that it did work was a side-effect of SimpleXMLElement's buggy implementation of the -> and [] operators, and in the 15 months since 7.0 it seems nobody else was making use of it.

Do you feel strongly that it should be documented?
 [2017-03-05 13:02 UTC] alepane at gmail dot com
Yes.
I think it's rarely noticed because XML is not widespread used in the PHP world (and, just to be clear, I'm happy about this :D).
But, in the Magento world, lots of extensions are manipulating XML tree using SimpleXML, and I lost almost a day to find this bug; it took so long partly because in the migration document there is not even a notice that SimpleXML behaviour changed.

I feel that just writing that because of a change in the internals in SimpleXML the property access behaviour changed, could save some devs from having the same troubles I had.
 [2017-03-05 13:12 UTC] requinix@php.net
-Summary: unset($element->{0}) on SimpleXMLElement not working +Summary: unset($element->{0}) on SimpleXMLElement does not work in PHP 7.0+ -Status: Not a bug +Status: Re-Opened -Type: Bug +Type: Documentation Problem
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Oct 15 06:01:26 2024 UTC