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

如何在PHP中通过对象间接实例化并禁止直接实例化对象

问题

想要模拟Stripe库的调用逻辑,实现两个核心要求:

  • 禁止直接通过new Products()实例化Products对象,必须通过$someobject->products->retrieve()的方式获取实例
  • 实现延迟实例化:仅调用retrieve()方法时才创建Products对象,而非在Thing类的构造函数中提前初始化

目前已实现部分逻辑的代码如下:

class Thing {
    function __get($name) {
        if ($name === 'products') {
            $p = new Products();
            return $p;
        }
    }
}

class Products {
    public $id;
    public $option;

    function retrieve($id, $option) {
        $this->id = $id;
        $this->option = $option;
        return $this;
    }
}

可以通过$thing->products->retrieve('123', 'bob')获取实例,但仍允许直接new Products()实例化,不符合需求。

解决方案

要实现禁止直接实例化+延迟加载的效果,可通过以下方式修改代码:

核心思路

  1. 将Products类的构造函数设为私有,阻断外部直接实例化的路径
  2. 让Thing类的products属性返回一个代理对象,仅当调用retrieve()时才触发Products实例的创建

最终实现代码

class Thing {
    public function __get($name) {
        if ($name === 'products') {
            // 返回代理对象,延迟Products实例化时机
            return new class {
                public function retrieve($id, $option) {
                    // 通过Products的静态方法创建实例
                    return Products::create($id, $option);
                }
            };
        }
        throw new \Exception("Undefined property: Thing::$name");
    }
}

class Products {
    public $id;
    public $option;

    // 私有构造函数,禁止外部直接new
    private function __construct($id, $option) {
        $this->id = $id;
        $this->option = $option;
    }

    // 静态工厂方法,唯一合法的实例创建入口
    public static function create($id, $option) {
        return new self($id, $option);
    }

    // 禁止克隆,进一步阻断实例获取路径
    private function __clone() {}
}

验证效果

  • 合法调用(正常工作):
$thing = new Thing();
$prod = $thing->products->retrieve('123', 'bob');
var_dump($prod instanceof Products); // 输出 bool(true)
  • 非法调用(触发错误):
$prod = new Products('123', 'bob'); // 报错:Uncaught Error: Call to private Products::__construct() from global scope

补充说明

如果想要完全模拟Stripe"直接实例化提示类不存在"的效果,可以将Products类封装到Thing类的内部(PHP 7.4+支持嵌套类),或者通过命名空间+自动加载机制隐藏类的可见性。上述方案已满足核心需求,是最简洁的实现方式。

内容的提问来源于stack exchange,提问作者russ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 22:22:38