Bug #75137 [Ver]: marijn@suninet.org
| From: | marijn at suninet dot org | Date: | Mon, 11 Sep 2017 04:55:19 +0000 |
| Subject: | Bug #75137 [Ver]: marijn@suninet.org | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-211051@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75137&edit=1
ID: 75137
User updated by: marijn at suninet dot org
Reported by: marijn at suninet dot org
-Summary: Breaking change in 7.0.12 using XML namespaces and
assigning value by key.
+Summary: marijn@suninet.org
Status: Verified
Type: Bug
Package: SimpleXML related
Operating System: Linux
PHP Version: 7.0.22
Block user comment: N
Private report: N
New Comment:
That sounds reasonable, however it would be great if information like that could be added to the
documentation. The SimpleXMLElement documentation is so sparse, especially regarding namespace
usage, that in my opinion it's impossible to know, not even through inference, that code like
the example should be written like you suggested. That is also probably how this code was birthed. A
developer had to figure out how to do this and due to lack of documentation came to this working
solution through trial and error. However then in a patch version and without mentioning it in the
release notes this behaviour was broken/changed.
Previous Comments:
------------------------------------------------------------------------
[2017-09-01 16:59:06] nikic@php.net
Based on vague memory, the "incomplete" part here is that it inherits the foo namespace
rather than inserting it without namespace. I believe the fully correct output in this case would
be:
<?xml version="1.0"?>
<xml xmlns="http://xml" xmlns:foo="http://foo" xmlns:bar="http://bar">
<foo:foo>
<bar:bar/>
<bar>Hello World!</bar>
</foo:foo>
</xml>
The correct way to write this code is:
$foo->children('http://bar')->bar[0] = 'Hello
World!';
SimpleXML requires you to explicitly specify the namespace. Prior to the referenced bug/commits this
was somewhat hit-and-miss, with some places using the namespace and some places changing *all*
elements with a given name regardless of namespace.
------------------------------------------------------------------------
[2017-09-01 16:34:02] cmb@php.net
A git bisect points at
<http://git.php.net/?p=php-src.git;a=commit;h=6adb7e0>,
and the
commit message indeed states that the fix is incomplete. So yes,
this is a bug.
------------------------------------------------------------------------
[2017-08-31 17:42:14] marijn at suninet dot org
I guess it may be a bug then after all.
------------------------------------------------------------------------
[2017-08-31 14:31:41] cmb@php.net
According to <https://3v4l.org/W5n3d> the behavioral
change has
been introduced in PHP 7.0.12.
------------------------------------------------------------------------
[2017-08-30 13:46:56] marijn at suninet dot org
Description:
------------
Hi,
I've been looking around but I haven't been able to find anything. If you assign a value
to an XML element by using an array key when XML namespaces are used the behaviour is changed
between PHP 5.6 and PHP 7.0. This is something we couldn't anywhere in the documentation around
backwards incompatibility. It could have something to do with "Changes to the handling of
indirect variables, properties, and methods" but from my understanding reading that section
that is about when you use dynamic variable assignments which is not the case here.
In the expected/actual result you can see the difference. The expected result is what you get when
running the sample code in PHP 5.6 and the actual result is what you get when running the sample
code in PHP 7.0.
My guess is that this is not a bug but rather an undocumented backward incompatible change between
the PHP versions.
Regards,
Marijn.
Test script:
---------------
<?php
$xml = new SimpleXMLElement('<xml xmlns="http://xml" xmlns:foo="http://foo" xmlns:bar="http://bar" />');
$foo = $xml->addChild('foo', null, 'http://foo');
$tag = $foo->addChild('bar', null, 'http://bar');
$foo->bar[0] = 'Hello World!';
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();
Expected result:
----------------
$ php-5.6 test.php
<?xml version="1.0"?>
<xml xmlns="http://xml" xmlns:foo="http://foo" xmlns:bar="http://bar">
<foo:foo>
<bar:bar>Hello World!</bar:bar>
</foo:foo>
</xml>
Actual result:
--------------
$ php-7.0 test.php
<?xml version="1.0"?>
<xml xmlns="http://xml" xmlns:foo="http://foo" xmlns:bar="http://bar">
<foo:foo>
<bar:bar/>
<foo:bar>Hello World!</foo:bar>
</foo:foo>
</xml>
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75137&edit=1