You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 06:54:23