antares/pool

一个简单的PHP资源池。

v1.2 2015-12-23 11:35 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:42:07 UTC


README

SensioLabsInsight Build Status Latest Stable Version License

这个库为您提供简单的资源池。这在与 React 一起工作时特别有用:这样您可以共享资源,例如数据库连接,并提高应用程序的性能。

欢迎建议和贡献!

安装

您可以使用composer将此库作为依赖项添加,如下所示

composer require antares/pool

兼容性

此库与PHP 5.4+、PHP 7和HHVM兼容。

文档

资源池接受的资源

首先,请注意,提供的资源池仅存储对象。整数、字符串或数组等值不能存储。如果需要,您可以将这些值包装在 stdClass 中。

PoolInterface

提供的资源池实现了 PoolInterface 接口,它提供了以下方法

interface PoolInterface
{
    // Associate a resource to an id
    public function set($id, $generator, $eventsCallbacks = null);

    // Get an instance of the resource
    public function get($id);

    // Free the instance of the resource
    public function dispose($instance);

    // Clear the pool
    public function clear();

    // Set a set of callbacks for the events a resource can trigger
    public function addEventsCallbacks($id, $callbacks);

    // Set a callback to call when an event is triggered for given resource
    public function addEventCallback($id, $event, $callback);
}

Pool

提供的基本资源池是 Pool 类。让我们看看它是如何使用的。

use Pool\Pool;

class Foo {}

$pool = new Pool(); // Instantiate the pool
$pool->set('foo', function() { return new Foo(); }); // Assign to the id 'foo' a generator returning an instance of Foo

// If an instance is already available, the pool will return it
// Else, a new instance will be created
$foo = $pool->get('foo');

// We don't need $foo anymore, so the instance can be released
// It will be available from the pool again
$pool->dispose($foo);

如本例所示,当不再需要资源时,释放资源很重要。如果不这样做,每次请求资源时都将创建一个新的实例,并且将保留在内存中。

StaticPool

考虑到您的应用程序结构,您定义资源池的代码可能多次无意义地执行。在这种情况下,StaticPool 可以很有用。内部,它包含 Pool 的静态实例,该实例在 StaticPool 的每个实例之间共享。看看以下代码片段

use Pool\StaticPool;

class Foo {}

$pool = new StaticPool();

if (!$pool->isAlreadyDefined()) {
    $pool->set('foo', function() { return new Foo(); });
}

$foo = $pool->get('foo');
$pool->dispose($foo);

在这里,第一次实例化池时,其资源将被定义。接下来的时间,定义步骤将被跳过。每个 StaticPool 实例将使用相同的内部池,其使用更加简单。

资源池事件

您可以将回调附加到资源池触发的事件上。

可能发生4个事件

  • PoolInterface::EVENT_GET 当从资源池中拉取资源实例时(当调用 $pool->get($id)
  • PoolInterface::EVENT_DISPOSE 当实例被释放时(当调用 $pool->dispose($instance)
  • PoolInterface::EVENT_CREATE 当实例被创建时(当调用 $pool->get($id) 如果实例尚未创建)
  • PoolInterface::EVENT_DESTRUCT 当实例被销毁时(当调用 $pool->clear()

有3种定义回调的方式

use Pool\PoolInterface;

$pool = new Pool\Pool();

$callbacks = [
    PoolInterface::EVENT_GET => [function($instance) {}],
    PoolInterface::EVENT_DISPOSE => [function($instance) {}]
];

// 1. Define it with the generator
$pool->set('foo', function() { return new Foo(); }, $callbacks);

// 2. Define each event
$pool->addEventCallback('foo', PoolInterface::EVENT_GET, $callbacks[PoolInterface::EVENT_GET][0]);
$pool->addEventCallback('foo', PoolInterface::EVENT_DISPOSE, $callbacks[PoolInterface::EVENT_DISPOSE][0]);

// 3. Define all callbacks in one method call
$pool->addEventsCallbacks('foo', $callback);

请注意,回调是可以组合的。

$pool->addEventCallback('foo', PoolInterface::EVENT_GET, function($instance) { echo 'a'; });
$pool->addEventCallback('foo', PoolInterface::EVENT_GET, function($instance) { echo 'b'; });

$pool->get('foo'); // will echo 'a' and 'b'

以下是如何使用回调的示例。

class Foo {
    public function bar() { echo 'blablabla'; }
}

$counter = 0;
$pool = new Pool\Pool();
$pool->set('foo', function() { return new Foo(); }, [
    PoolInterface::EVENT_GET => [function($instance) { $instance->bar(); }],
    PoolInterface::EVENT_DISPOSE => [function($instance) use (&$counter) { $counter++; }]
]);

$foo = $pool->get('foo'); // $foo->bar() is called

$pool->dispose($foo); // the counter is incremented