Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP返回静态类_Php_Oop_Instance_Static Methods - Fatal编程技术网

PHP返回静态类

PHP返回静态类,php,oop,instance,static-methods,Php,Oop,Instance,Static Methods,我正在为a构建一个插件接口,并试图解决一个概念问题。我决定制作的第一个“插件”是条带集成,本质上是将PHP库作为条带,并将其包装为插件。我有一种工厂模式,允许检索插件实例,如: $stripe = Iceberg::getPlugin('Stripe'); 在可以实例化类的情况下非常简单,但对于条带库,所有类都是静态的。在他们的示例中,他们建议对主条带文件执行include(),然后您可以像这样使用它: Stripe::setApiKey('xyz'); 我的断开连接是如何使我的getPlu

我正在为a构建一个插件接口,并试图解决一个概念问题。我决定制作的第一个“插件”是条带集成,本质上是将PHP库作为条带,并将其包装为插件。我有一种工厂模式,允许检索插件实例,如:

$stripe = Iceberg::getPlugin('Stripe');
在可以实例化类的情况下非常简单,但对于条带库,所有类都是静态的。在他们的示例中,他们建议对主条带文件执行
include()
,然后您可以像这样使用它:

Stripe::setApiKey('xyz');
我的断开连接是如何使我的
getPlugin()
方法与只公开静态接口的类一起工作的。显然,我无法实例化该类并期望它正常工作,但同时,我希望该方法无论是实例还是静态对象都能正常工作

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

在控制器中使用插件

$stripe = Iceberg::getPlugin('Stripe');
$stripe->setApiKey('xyz');
public function __call( $name, $arguments ) 
{
    Stripe::$name($arguments);
}
插件中的

$stripe = Iceberg::getPlugin('Stripe');
$stripe->setApiKey('xyz');
public function __call( $name, $arguments ) 
{
    Stripe::$name($arguments);
}
我不确定这样的事情是否会奏效,即使会,如果那是最好的方式


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

只要正确地转发参数,
\u调用
转发应该可以工作:

public function __call($name, $arguments) 
{
    return call_user_func_array(['Stripe', $name], $arguments);
}
一般来说,这可能会有问题,因为您的插件看起来像是基于实例的,而实际上不是(状态在所有实例之间共享,因为它是
静态的
)。在您的情况下,这可能不是一个真正的问题,因为
Iceberg::getPlugin
可能被记录为每次为每个不同的插件名称返回相同的实例

也就是说,您的问题源于这样一个事实:Stripe库作者犯了一个新手错误,将库设置为静态,这导致了各种问题(共享状态,很难模拟库进行单元测试)

不要自己犯同样的错误:
冰山
中丢失所有公共静态成员。如果有人想非常方便地访问您的服务,他们随时可以这样做:

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

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

好的,所有插件都实现了
插件
摘要。我们的目标是抽象静态调用,就用户所知,他们只需在实例上调用一个方法就可以了。这是一个非常好的主意,Jon,谢谢你的架构建议!我意识到有无数的PHP框架,我只是用这个项目来实践一个完整的实现。