繁体   English   中英

PHP返回静态类

[英]PHP Return Static Class

我正在为我一直在研究微框架构建一个插件界面,并试图解决一个概念性问题。 我决定制作的第一个“插件”是Stripe集成,本质上是将Stripe的PHP库用作包装。 我有一种工厂模式 ,它允许检索插件实例,例如:

$stripe = Iceberg::getPlugin('Stripe');

在可以实例化一个类的情况下非常简单,但是对于Stripe库,所有类都是static 在他们的示例中,他们建议对主Stripe文件执行include() ,然后可以像下面这样使用它:

Stripe::setApiKey('xyz');

我断开连接的方法是如何使getPlugin()方法与仅公开静态接口的类一起使用。 我显然不能实例化该类并期望它能够正常工作,但是与此同时,我希望此方法不管实例还是静态对象都可以工作。

我曾经有一个想法是在我的Stripe插件类中实现__call()方法,然后尝试将这些调用静态传递给Stripe库,例如:

在控制器中使用插件

$stripe = Iceberg::getPlugin('Stripe');
$stripe->setApiKey('xyz');

在插件中

public function __call( $name, $arguments ) 
{
    Stripe::$name($arguments);
}

我不确定类似的方法是否会奏效,即使可行,这是否是最佳方法。

TLDR:如何创建可以在对象上下文和静态上下文中与类交互的对象?

只要您正确转发参数, __call转发就应该起作用:

public function __call($name, $arguments) 
{
    return call_user_func_array(['Stripe', $name], $arguments);
}

通常,这可能会带来问题,因为您的插件看起来像是基于实例的,而实际上却并非基于实例(状态在所有实例之间共享,因为它在后台是static的)。 在您的情况下,这可能并不是真正的问题,因为Iceberg::getPlugin可能被记录为每次为每个不同的插件名称返回相同的实例。

就是说,您的问题来自于这样一个事实:Stripe库作者犯了使库静态化的新手错误,这会导致各种问题(共享状态,难以模拟用于单元测试的库)。

不要自己犯同样的错误:Iceberg失去所有公共静态成员。 如果有人想要超方便地访问您的服务,则可以随时执行以下操作:

function Iceberg() {
    static $instance;
    if ($instance === null) $instance = new Iceberg();
    return $instance;
}

现在,他们可以像以前编写Iceberg::foo()一样编写Iceberg()->foo()了,作为框架作者,您可以享受非静态体系结构带来的好处。 您未来的自我和您的用户将感谢您。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM