From ceb5e5963f2d80ce5cb80d41710b419464d5a5ef Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sat, 13 Jun 2026 16:00:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E5=AD=90?= =?UTF-8?q?=E7=B1=BB=E4=BD=9C=E4=B8=BA=E7=88=B6=E7=B1=BB=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了内部接口类型的检查条件 - 实现了接口继承链的递归验证逻辑 - 支持传递性接口继承关系的检查 - 修复了Iterator等扩展Traversable的接口验证问题 --- src/Php/CompilerBase.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 413f2ca8..6350c935 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1573,7 +1573,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->fatalError($v, 'The return type is `' . $returnClass . '`, cannot return an instance of `' . $objectClass . '`'); } // 把子类当做父类返回时,父类必须是抽象类或者接口 - if ($objectClass and $objectClass !== $returnClass and !$this->isAbstractClass($returnClass) and !$this->hasInterface($returnClass)) { + if ($objectClass and $objectClass !== $returnClass and !$this->isAbstractClass($returnClass) and !$this->hasInterface($returnClass) and !$this->isInternalInterface($returnClass)) { $this->fatalError($v, "When returning a subclass `$objectClass` instance as parent type, the parent class `$returnClass` must be abstract/interface"); } } @@ -3564,6 +3564,19 @@ class CompilerBase extends \PhpAot\Core\Translator if ($classDef->implements and in_array($expected, $classDef->implements)) { return true; } + // Check transitive interface inheritance (e.g., Iterator extends Traversable) + foreach ($classDef->implements as $iface) { + $check = $iface; + while ($check && $this->hasInterface($check)) { + if (strcasecmp($check, $expected) === 0) { + return true; + } + $check = $this->getInterface($check)->extends; + } + if (is_subclass_of($iface, $expected)) { + return true; + } + } } else { if (strcasecmp($class, $expected) === 0) { return true;