DomAppendMovesNodeUnexpectedly
warning native off by defaultGroup: Probable bugs
Clone the node when preserving its existing parent. This inspection is disabled by default; enabling it selects the stated policy.
Example
<?php
$d=new DOMDocument(); $a=$d->createElement('a'); $b=$d->createElement('b'); $n=$d->createElement('n'); $a->appendChild($n); $b->appendChild($n);Reported:
- line 2: Clone the node when preserving its existing parent.
Detection
- The same proven node is appended consecutively to distinct proven parents. Enabling establishes that both parents must retain a copy. An intervening explicit detachment or clone excludes the finding (E3); do not infer this policy from identifiers.
- Resolve builtin functions, extension classes, constants and method receivers, including aliases and supported named arguments. Inspect reachable operations in one lexical scope with bounded local flow.
- Emit one finding per violating operation. Never infer policy from names or comments. When the proof is inconclusive, nothing is reported.
Exceptions (no report)
Exclude shadowed or unresolved symbols, incomplete code, unknown required constants, ambiguous receiver identity and unsupported versions. Reassignment, escaping aliases, and unknown calls invalidate dependent flow facts.
Both @custos-ignore DomAppendMovesNodeUnexpectedly and @noinspection DomAppendMovesNodeUnexpectedly suppress this native rule.
E3. A call that executes on every path between the two appends counts as an explicit detachment when it is one of:
remove()orreplaceWith(...)called on the node itself;removeChildorreplaceChildnaming the node, positionally or through thechild/nodenamed arguments, on any receiver;replaceChildren(...)called on the first parent;removeChildorreplaceChildcalled on the first parent with a removed child that is not proven to be another node. The removed child is proven distinct only when it and the appended node both resolve to different local allocation calls (DOMDocument::createElement,createElementNS,createTextNode,createComment,createCDATASection,createDocumentFragment, orcloneNode);$parent->firstChildand similar navigations are never proven distinct.
The same calls on unrelated nodes or parents keep the finding, as does removing the first parent itself.
Fix
None. A safe repair requires choosing values, error handling, or application behavior.
PHP versions
Apply throughout PHP 5.3–8.5 only where the extension API and syntax exist. Do not flag API unavailability through this rule. Legacy DOM classes are the initial target; modern Dom namespace classes require independently established matching contracts.
Options
None. Use normal rule configuration to enable or disable the inspection.
Configure
In custos.json:
{
"rules": {
"DomAppendMovesNodeUnexpectedly": {
"enabled": true
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
// @custos-ignore DomAppendMovesNodeUnexpectedly