checkParentMethodCanBeOverridden()'s internal-parent branch only checked
the PRIVATE and FINAL modifiers via reflection and then stopped, so an
override of any Zend built-in method was never signature-checked:
narrowed parameters, static/instance mismatches, narrowed visibility and
incompatible real return types were all accepted (all fatal in Zend,
e.g. "Declaration of C::offsetGet(int $key): string must be compatible
with ArrayObject::offsetGet(mixed $key): mixed").
Add validateInternalMethodOverrideSignature(), mirroring Zend's
zend_do_perform_implementation_check on host ReflectionMethod data:
- visibility may widen but not narrow; staticness must match;
- a by-ref return may be added but not dropped;
- the child may not require more arguments; extra parameters must be
optional or variadic;
- parameters are contravariant with invariant by-ref-ness, and a
trailing child variadic absorbs remaining parent positions (a
variadic parent requires a variadic child);
- the return type is covariant, enforced ONLY for real return types:
ReflectionMethod::getReturnType() is null for TENTATIVE return
types, which Zend merely deprecates on mismatch, never fatals.
ReflectionType data (named/nullable/union/intersection, incl. self,
parent and static) is mapped into the existing accepted-types DNF so the
comparison reuses isReturnTypeCoveredBy()/isAcceptedTypeSubset().