It appears that the PHP team is not willing to change this behavior (source), so we have to find a workaround instead.
One way is to simply do the encoding yourself in the PHP code, as such:
$header = $dom->createElement("h2", "Lorem & Ipsum");
However, this isn't always convenient, as the text printed may be inside of a variable or contain other special characters besides &
. So, you can use the htmlentities
function.
$text = "Lorem & Ipsum";
$header = $dom->createElement("h2", htmlentities($text));
If this still is not an ideal solution, another workaround is to use the textContent
property instead of the second argument in createElement
.
In the code below, I've implemented this in a DOMDocument
subclass, so you just have to use the BetterDOM
subclass instead to fix this strange bug.
class BetterDOM extends DOMDocument {
public function createElement($tag, $text = null) {
$base = parent::createElement($tag);
$base->textContent = $text;
return $base;
}
}
// Correctly prints "<h2>Lorem & Ipsum</h2>" with no errors
$dom = new BetterDOM();
$header = $dom->createElement("h2", "Lorem & Ipsum");
$dom->appendChild($header);
print($dom->saveHTML());