PHP 8.1 introduced a seemingly unintentional BC break in ca94d55a19 by
blocking the (un)serialization of DOM objects.
This was done because the serialization never really worked and just
resulted in an empty object, which upon unserialization just resulted in
an object that you can't use.
Users can however implement their own serialization methods, but the
commit made that impossible as the ACC flag gets passed down to the
child class. An approach was tried in #10307 with a new ACC flag to
selectively allow serialization with subclasses if they implement the
right methods. However, that was found to be too ad hoc.
Instead, let's abuse how the __sleep and __wakeup methods work to throw
the exception instead. If the child class implements the __serialize /
__unserialize method, then the throwing methods won't be called.
Similarly, if the child class implements __sleep and __wakeup, then
they're overridden and it doesn't matter that they throw.
For the user, this PR has the exact same behaviour for (sub)classes that
don't implement the serialization methods: an exception will be thrown.
For code that previously implemented subclasses with these methods, this
approach will make that code work again. This approach should be both BC
preserving and unbreak user's code.
Closes GH-12388.
For the test:
Co-authored-by: wazelin <contact@sergeimikhailov.com>
The entry points are duplicated: they add bloat and make it easier to forget
to change something. Make maintenance easier by using @implementation-alias.
Also, this has the nice side-effect of slightly reducing the amount of
code and binary size.
Closes GH-12158.
According to https://www.php.net/manual/en/class.domdocument:
When using json_encode() on a DOMDocument object the result will be
that of encoding an empty object.
But this was broken in 8.1. The output was `{"config": null}`.
That's because the config property is defined with a default value of
NULL, hence it was included. The other properties are not included
because they don't have a default property, and nothing is ever written
to their backing field. Hence, the JSON encoder excludes them.
Similarly, `(array) $doc` would yield the same `config` key in the
array.
Closes GH-11840.
For the past 20 years this threw a "not yet implemented" exception. But
the function was actually there (albeit not documented) and could be called...
Closes GH-11333.
Not explicitly documenting the possibility of returning DOMElement causes
the Intelephense linter (a popular PHP linter with ~9 million downloads:
https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client)
to think this code is bad:
$xp->query("whatever")->item(0)->getAttribute("foo");
DOMNode does not have getAttribute (while DOMElement does).
Documenting the DOMElement return type should fix Intelephense's linter.
Closes GH-11342.
@cname currently refers to the constant name in C. However, it is not always a (constant) name, but sometimes a function invocation, so naming it as @cvalue would be more appropriate.
A number of error conditions in DOM can only occur if libxml2 runs
out of memory, at least as far as I can see. In such cases we
currently do a silent "return false", which violates the DOM spec,
and which code is very unlikely to handle sensibly.
Switch these to throw a DomException with INVALID_STATE_ERR type.
This error type is chosen because we use for similar checks
elsewhere, for example:
a733b1ada7/ext/dom/documentfragment.c (L45-L48)
This changes some of the more obvious cases I spotted, but there are probably more.
Closes GH-7049.
According to the DOM specification, this argument should be
nullable. It's also supposed to be a required argument, but
not changing that at this point.