1

我有一些连接到购物车 API (SOAP) 端点的 PHP 代码。这不是针对一个中央服务器,而是针对任意数量的用户的特定端点 URL。

现在我有几个不同的类,它们都创建了自己与用户 API 的连接。

例如,

CartProduct.php -> updateProduct() (创建 api 连接)

CartCategory.php -> updateCategory() (创建 api 连接)

我正在考虑使用单例来共享远程连接,但是在阅读了关于 SO 的问题和一些博客之后,显然每个人都讨厌单例。

就我而言,我认为连接池没有意义。我正在连接到远程用户的网站,所以我不只是想打开 5 个连接并可能减慢他们的网站速度。我认为在这种情况下,我真的想在对应用程序的调用之间共享一个连接。我认为在数据库的情况下,连接池是有意义的,但对于远程用户 API 则不然。现在理论上,我想我们应该考虑如果用户尝试同时运行 updateProduct 和 updateCategory 会发生什么......这会破坏系统吗?

这里是否有一种有意义的设计模式来打开几个不同类可以共享的连接?

4

1 回答 1

6

我不知道这个模式是否有名字

在我看来,连接池实际上是有意义的。只有您不应该立即初始化所有连接。而是使用延迟初始化:

class LazyPool
{

    private $connections = [];
    private $providers = [];

    public function addProvider($name, callable $provider)
    {
        $this->providers[$name] = $provider;
        return $this;
    }

    public function getConnection($name)
    {
        if (array_key_exists($name, $this->connections) === false)
        {
            $this->connections[$name] = call_user_func($this->providers[$name]);
        }
        return $this->connections[$name];
    }

}

这个类可以这样使用:

$pool = new LazyPool;

$pool->addProvider('lorem', function() use ($config){
    $instance = new SoapThing($config['wsdl_1']);
    return $instance;
});

$pool->addProvider('ipsum', function() use ($config){
    $instance = new SoapThing($config['i_think_it_was_wsdl']);
    return $instance;
});

$foo = new Foo($pool);
$bar = new Bar($pool);

这样,两个实例都将能够初始化 SOAP 连接,但如果Foo初始化的连接名为"ipsum",则Bar实例将从池中获取已初始化的 SOAP 客户端。

免责声明:
此代码未经测试。它是使用我的旧帖子中的一些复制粘贴直接在 SO 帖子编辑器中编写的。这种特殊语法也需要 PHP 5.4+,因此您可能需要调整它以在较旧的 PHP 5.* 版本中运行。

于 2013-08-01T16:36:56.650 回答