PHP技术问题:如何在数组中返回接口实例?
解决数组中返回接口实例的问题
你当前代码的核心问题是:BonesSites::getSites返回的是普通关联数组,而非实现了Site接口的对象实例,所以instanceof Site检查必然失败。PHP里接口无法直接实例化,必须先定义类实现接口,再通过类创建实例。
步骤1:创建实现Site接口的实体类
定义一个类来实现Site接口,把站点数据(siteId、name、bone)作为类属性,通过构造方法初始化:
class ConcreteSite implements Site { public function __construct( public int $siteId, public string $name, public string $bone ) {} }
步骤2:修改BonesSites::getSites方法,返回接口实例数组
把原来返回关联数组的逻辑,替换为返回ConcreteSite的实例数组:
class BonesSites { public function getSites(string $site): array { if ($site === 'Egypt') { return [ new ConcreteSite(1, 'Cairo', 'T-Rex bones'), new ConcreteSite(2, 'Giza', 'Raptors bones'), new ConcreteSite(3, 'Alexandria', 'Bronchiosaurus bones'), ]; } // 错误处理建议改为抛出异常,避免返回混合类型数组 throw new \Exception("Site not found!"); } }
关于PHP接口与instanceof的工作机制
- 接口是一种"契约",定义类必须实现的方法(你的
Site接口目前为空,后续可按需添加方法)。 $site instanceof Site检查的不是对象的具体类,而是该对象是否实现了Site接口。只要是实现了Site的类的实例,无论类名是什么,这个检查都会返回true。
额外优化:调整Action类的依赖逻辑
你的Action::call方法调用了$this->getSites($bone),但Action本身没有这个方法,建议把BonesSites注入进来:
abstract class Action { public function __construct(protected BonesSites $bonesSites) {} final public function call(Bone $bone) { // 假设用$bone的getName获取站点名称 $sites = $this->bonesSites->getSites($bone->getName()); foreach ($sites as $site) { if (!$site instanceof Site) { throw new \Exception("Invalid entry"); } // 现在可安全使用$site的属性,比如$site->name } } }
调整后,call方法里的instanceof检查就能正常通过,数组中的每个元素都是Site接口的实例。
内容的提问来源于stack exchange,提问作者Shinjuo
相关产品推荐
相关产品推荐

