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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: alepane at gmail dot com
New email:
PHP Version: OS:

 

 [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 Nov 05 06:01:28 2024 UTC