跳转到内容

存储组件


概览

The Phalcon\Storage命名空间包含用于在不同存储中存储数据的组件。该组件深度集成到Phalcon\Cache\Cache以及Phalcon\Session。它提供基于各种序列化适配器的数据序列化,以及基于各种存储适配器的数据存储。工厂帮助创建组件工作所需的所有必要对象。

序列化器

The Phalcon\Storage\Serializer命名空间提供了实现Serializable接口并因此暴露serializeunserialize方法的类。这些类的目的是在保存数据到存储之前和从存储中检索数据之后对其进行转换。

注意

所有适配器的默认序列化器是Phalcon\Storage\Serializer\Php,它使用 PHP 的serializeunserialize方法。这些方法可以满足大多数应用程序的需求。然而,开发人员可能希望使用更高效的序列化器,例如igbinary,它更快并且具有更好的压缩效果。

可以配置存储适配器以使用不同的序列化器。可用的序列化器包括:

Base64

此序列化器使用base64_encodebase64_decode方法来序列化数据。输入必须是类型string,因此此序列化器有明显的限制。

Igbinary

The igbinary序列化依赖于igbinary_serializeigbinary_unserialize方法。这些方法由igbinaryPHP 扩展公开,该扩展必须安装并加载到目标系统上。

Json

The JSON序列化器使用json_encodejson_decode。目标系统必须具备 PHP 的 JSON 支持。

MemcachedIgbinary

当使用Memcached时可以使用此序列化器。它对应于Memcached中内置的 PHP 序列化器。

MemcachedJson

当使用Memcached时可以使用此序列化器。它对应于Memcached中内置的 PHP 序列化器。

MemcachedPhp

当使用Memcached时可以使用此序列化器。它对应于Memcached中内置的 PHP 序列化器。

Msgpack

类似于igbinary超全局变量。如果cookie存在于任一集合中,则返回msgpack序列化器使用msgpack_packmsgpack_unpack进行数据的序列化和反序列化。这与igbinary之一是最快的和最有效的序列化器之一。但是,它要求目标系统加载了msgpackPHP 扩展。

None

此序列化器不转换数据。它的serializeunserialize获取和设置数据而不改变它。

Php

这是默认的序列化器。它使用 PHP 的serializeunserialize方法进行数据转换。

RedisIgbinary

当使用Redis时可以使用此序列化器。它对应于Redis中内置的 PHP 序列化器。

RedisJson

当使用Redis时可以使用此序列化器。它对应于Redis中内置的 PHP 序列化器。

RedisMsgpack

当使用Redis时可以使用此序列化器。它对应于Redis中内置的 PHP 序列化器。

RedisNone

当使用Redis时可以使用此序列化器。它对应于Redis中内置的 PHP 序列化器。

RedisPhp

当使用Redis时可以使用此序列化器。它对应于Redis中内置的 PHP 序列化器。

自定义

Phalcon 还提供了Phalcon\Storage\Serializer\SerializerInterface`,可以在自定义类中实现。该类可以提供您需要的序列化功能。

<?php

namespace MyApp\Storage\Serializer;

use Phalcon\Storage\SerializerInterface;

class Garble implements SerializerInterface
{
    /**
     * Data storage
     * 
     * @var string
     */
    private $data = '';

    /**
     * Return the stored data
     * 
     * @return string
     */
    public function getData(): string
    {
        return $this->data;
    }       

    /**
     * Serializes data
     */
    public function serialize(): string
    {
        return rot13($this->data);
    }

    /**
     * Set the data
     * 
     * @var Garble
     *
     * @return Garble
     */
    public function setData($data): Garble
    {
        $this->data = (string) $data;

        return $this;
    }       

    /**
     * Unserializes data
     */
    public function unserialize($data): void
    {
        $this->data = str_rot13($data);
    }
}

使用它:

<?php

namespace MyApp;

use MyApp\Storage\Serializer\Garble;

$data = 'I came, I saw, I conquered.';
$garble = new Garble();

$garble
    ->setData($data)
    ->serialize()  
;

echo $garble->getData(); // "V pnzr, V fnj, V pbadhrerq."

$encrypted = 'V pnzr, V fnj, V pbadhrerq.';

$garble->unserialize($encrypted);

echo $garble->getData(); // "I came, I saw, I conquered."

序列化工厂

虽然所有的序列化类都可以通过new关键字实例化,Phalcon 提供了Phalcon\Storage\SerializerFactory类,以便开发者可以轻松实例化序列化类。上述所有序列化器都在工厂中注册,并在调用时延迟加载。工厂还允许您注册额外的(自定义)序列化类。唯一需要考虑的是选择序列化器名称时要与现有的进行比较。如果定义了相同的名称,则会覆盖内置的序列化器。工厂中的对象会被缓存,因此如果您在同一个请求中使用相同参数调用newInstance()方法,你会得到相同的对象返回。

下面的例子展示了如何创建一个Json序列化器,可以使用new关键字或工厂:

<?php

use Phalcon\Storage\Serializer\Json; 
use Phalcon\Storage\SerializerFactory;

$jsonSerializer = new Json();

$factory        = new SerializerFactory();
$jsonSerializer = $factory->newInstance('json');
你可以用于工厂的参数是:

名称
base64 Phalcon\Storage\Serializer\Base64
igbinary Phalcon\Storage\Serializer\Igbinary
json Phalcon\Storage\Serializer\Json
memcached_igbinary Phalcon\Storage\Serializer\MemcachedIgbinary
memcached_json Phalcon\Storage\Serializer\MemcachedJson
memcached_php Phalcon\Storage\Serializer\MemcachedPhp
msgpack Phalcon\Storage\Serializer\Msgpack
none Phalcon\Storage\Serializer\None
php Phalcon\Storage\Serializer\Php
redis_igbinary Phalcon\Storage\Serializer\RedisIgbinary
redis_json Phalcon\Storage\Serializer\RedisJson
redis_msgpack Phalcon\Storage\Serializer\RedisMsgpack
redis_none Phalcon\Storage\Serializer\RedisNone
redis_php Phalcon\Storage\Serializer\RedisPhp

适配器

The Phalcon\Storage\Adapter命名空间提供了实现Phalcon\Storage\Adapter\AdapterInterface接口的类。它公开了用于在存储适配器上执行操作的通用方法。这些适配器充当各自后端代码的包装器。

可用的方法有:

方法 描述
clear 清空/清除存储
decrement 减少存储的数字
delete 从适配器中删除数据
get 从适配器读取数据
getAdapter 返回已连接的适配器或连接到后端服务器(们)
getKeys 返回存储的所有键(可选过滤参数)
getPrefix 返回键的前缀
has 检查元素是否存在于存储中
increment 增加存储的数字
set 在适配器中存储数据

注意

The getAdapter()方法返回连接的适配器。这为开发者提供了更大的灵活性,因为它可以用于执行每个适配器提供的其他方法。例如,对于Redis适配器你可以用来获取连接的对象并调用getAdapter(),以获取连接的对象并调用zAdd, zRange,以及Phalcon适配器未公开的其他方法。

要构造这些对象之一,你需要传递一个Phalcon\Storage\SerializerFactory对象到构造函数中,并可选地为所选适配器提供一些参数。下面列出了选项列表。

可用的适配器有:

Apcu

此适配器使用Apcu存储数据。为了使用此适配器,你需要在目标系统中启用apcu。这个类并不使用实际的适配器,因为功能是通过apcuPHP函数暴露的。apcu_*选项

选项 默认值
defaultSerializer Php
lifetime 3600
serializer null
prefix ph-apcu-

下面的例子演示了如何创建一个新的Apcu存储适配器,它将使用Phalcon\Storage\Serializer\Json序列化器,并具有默认生命周期7200。

<?php

use Phalcon\Storage\Adapter\Apcu;
use Phalcon\Storage\SerializerFactory;

$serializerFactory = new SerializerFactory();

$options = [
    'defaultSerializer' => 'Json',
    'lifetime'          => 7200,
];

$adapter = new Apcu($serializerFactory, $options);

上面的例子使用了Phalcon\Storage\SerializerFactory对象和defaultSerializer选项来告诉适配器实例化相关的序列化器。

Libmemcached

此适配器利用PHP的memcached扩展连接到Memcached服务器。使用的适配器是Memcached类的一个实例,在第一次需要活动连接的事件后创建。

选项 默认值
defaultSerializer Php
lifetime 3600
serializer null
prefix ph-memc-
servers[0]['host'] 127.0.0.1
servers[0]['port'] 11211
servers[0]['weight'] 1
persistentId ph-mcid-
saslAuthData['user']
saslAuthData['pass']
client[\Memcached::OPT_CONNECT_TIMEOUT] 10
client[\Memcached::OPT_DISTRIBUTION] \Memcached::DISTRIBUTION_CONSISTENT
client[\Memcached::OPT_SERVER_FAILURE_LIMIT] 2
client[\Memcached::OPT_REMOVE_FAILED_SERVERS] true
client[\Memcached::OPT_RETRY_TIMEOUT] 1

你可以在构造函数中传递的选项数组中指定多个服务器。如果定义了SASL数据,适配器将尝试使用传递的数据进行身份验证。如果选项中有错误,或者该类无法向池中添加一个或多个服务器,则会抛出异常。Phalcon\Storage\Exception异常。

下面的例子演示了如何创建一个新的Libmemcached存储适配器,它将使用Phalcon\Storage\Serializer\Json序列化器,并具有默认生命周期7200。它将使用10.4.13.100作为第一台服务器,权重为1连接到端口1121110.4.13.110作为第二台服务器,权重为5再次连接到端口11211.

<?php

use Phalcon\Storage\Adapter\Libmemcached;
use Phalcon\Storage\SerializerFactory;

$serializerFactory = new SerializerFactory();

$options = [
    'defaultSerializer' => 'Json',
    'lifetime'          => 7200,
    'servers'           => [
        0 => [
            'host'   => '10.4.13.100',
            'port'   => 11211,
            'weight' => 1,
        ],
        1 => [
            'host'   => '10.4.13.110',
            'port'   => 11211,
            'weight' => 5,
        ],
    ],
];

$adapter = new Libmemcached($serializerFactory, $options);

上面的例子使用了Phalcon\Storage\SerializerFactory对象和defaultSerializer选项来告诉适配器实例化相关的序列化器。

序列化器:该Memcached类是Phalcon\Storage\Adapter\Libmemcached使用的适配器,提供了开箱即用的序列化支持。内置的序列化器包括:

  • \Memcached::SERIALIZER_PHP
  • \Memcached::SERIALIZER_JSON
  • \Memcached::SERIALIZER_IGBINARY

The igbinary内置序列化器仅在igbinary存在于目标系统并且Memcached扩展已编译时可用。要启用这些序列化器,可以使用Phalcon\Storage\Serializer\MemcachedIgbinary, Phalcon\Storage\Serializer\MemcachedJsonPhalcon\Storage\Serializer\MemcachedPhp

Memory

此适配器使用计算机的内存存储数据。由于所有数据都存储在内存中,因此没有持久性,这意味着一旦请求完成,数据就会丢失。此适配器可用于测试或特定请求期间的临时存储。构造函数的可用选项包括:

选项 默认值
defaultSerializer Php
lifetime 3600
serializer null
prefix ph-memo-

下面的例子演示了如何创建一个新的Memory存储适配器,它将使用Phalcon\Storage\Serializer\Json序列化器,并具有默认生命周期7200。

<?php

use Phalcon\Storage\Adapter\Memory;
use Phalcon\Storage\SerializerFactory;

$serializerFactory = new SerializerFactory();

$options = [
    'defaultSerializer' => 'Json',
    'lifetime'          => 7200,
];

$adapter = new Memory($serializerFactory, $options);

上面的例子使用了Phalcon\Storage\SerializerFactory对象和defaultSerializer选项来告诉适配器实例化相关的序列化器。

Redis

此适配器利用PHP的redis扩展连接到Redis服务器。使用的适配器是Redis类的一个实例,在第一次需要活动连接的事件后创建。

选项 默认值
defaultSerializer Php
lifetime 3600
serializer null
prefix ph-reds-
host 127.0.0.1
port 6379
index 1
persistent false
auth
socket
ssl

如果auth数据定义了,适配器将尝试使用传递的数据进行身份验证。如果选项中有错误,或者服务器无法连接或身份验证失败,则会抛出异常。Phalcon\Storage\Exception异常。

下面的例子演示了如何创建一个新的Redis存储适配器,它将使用Phalcon\Storage\Serializer\Json序列化器,并具有默认生命周期7200。它将使用10.4.13.100作为主机,连接到端口6379,并选择索引1.

<?php

use Phalcon\Storage\Adapter\Redis;
use Phalcon\Storage\SerializerFactory;

$serializerFactory = new SerializerFactory();

$options = [
    'defaultSerializer' => 'Json',
    'lifetime'          => 7200,
    'host'              => '10.4.13.100',
    'port'              => 6379,
    'index'             => 1,
];

$adapter = new Redis($serializerFactory, $options);

上面的例子使用了Phalcon\Storage\SerializerFactory对象和defaultSerializer选项来告诉适配器实例化相关的序列化器。

序列化器:该Redis类是Phalcon\Storage\Adapter\Redis使用的适配器,提供了开箱即用的序列化支持。内置的序列化器包括:

  • \Redis::SERIALIZER_NONE
  • \Redis::SERIALIZER_PHP
  • \Redis::SERIALIZER_IGBINARY
  • \Redis::SERIALIZER_MSGPACK

The igbinary和内置序列化器仅在igbinary存在于目标系统并且Redis扩展已编译时可用。同样的规则适用于msgpack内置序列化器。它仅在msgpack存在于目标系统且Redis扩展已编译时可用。要启用这些序列化器,可以使用Phalcon\Storage\Serializer\RedisIgbinary, Phalcon\Storage\Serializer\RedisJson, Phalcon\Storage\Serializer\RedisMsgpack, Phalcon\Storage\Serializer\RedisNonePhalcon\Storage\Serializer\RedisPhp.

注意 increment - decrement

目前存在一个问题与Redis,其中内部Redis序列化器不会跳过标量值,因为它只能存储字符串。结果是,如果你在increment后使用set对于数字,将不会返回一个数字:

存储数字并使用increment(或decrement的方法是删除内部序列化器Redis

$storage->getAdapter()->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_NONE);

或者你可以使用increment代替使用set在设置键值对的第一个设置时:

$storage->delete('my-key');
$storage->increment('my-key', 2);
echo $storage->get('my-key');      // 2
$storage->increment('my-key', 3);
echo $storage->get('my-key');      // 3

Stream

此适配器是最简单的设置,因为它使用目标系统的文件系统(只需要一个可写的存储路径)。它是速度最慢的存储适配器之一,因为数据必须写入文件系统。每个创建的文件对应一个存储的键。文件包含额外的元数据以计算存储元素的生命周期,从而导致对文件系统的更多读写操作。

选项 默认值
defaultSerializer Php
lifetime 3600
serializer null
prefix phstrm-
storageDir

如果storageDir未定义,则Phalcon\Storage\Exception异常。

注意

适配器利用逻辑根据传递的键名将文件存储在单独的子目录中,从而避免了too many files in one folder在 Windows 或 Linux 系统中存在的限制。

下面的例子演示了如何创建一个新的Stream存储适配器,它将使用Phalcon\Storage\Serializer\Json序列化器,并且默认生命周期为 7200。它会将数据存储在/data/storage.

<?php

use Phalcon\Storage\Adapter\Stream;
use Phalcon\Storage\SerializerFactory;

$serializerFactory = new SerializerFactory();

$options = [
    'defaultSerializer' => 'Json',
    'lifetime'          => 7200,
    'storageDir'        => '/data/storage',
];

$adapter = new Stream($serializerFactory, $options);

上面的例子使用了Phalcon\Storage\SerializerFactory对象和defaultSerializer选项来告诉适配器实例化相关的序列化器。

自定义

Phalcon 还提供了Phalcon\Storage\Adapter\AdapterInterface可以在自定义类中实现。该类可以提供你所需的存储适配器功能。

<?php

namespace MyApp\Storage\Adapter;

use Phalcon\Storage\Adapter\AdapterInterface;

class Custom implements AdapterInterface
{
    /**
     * Flushes/clears the cache
     */
    public function clear(): bool
    {
        // Custom implementation
    }

    /**
     * Decrements a stored number
     */
    public function decrement(string $key, int $value = 1)
    {
        // Custom implementation
    }

    /**
     * Deletes data from the adapter
     */
    public function delete(string $key): bool
    {
        // Custom implementation
    }

    /**
     * Reads data from the adapter
     */
    public function get(string $key)
    {
        // Custom implementation
    }

    /**
     * Returns the already connected adapter or connects to the backend server(s)
     */
    public function getAdapter()
    {
        // Custom implementation
    }

    /**
     * Returns all the keys stored. If a filter has been passed the 
     * keys that match the filter will be returned
     */
    public function getKeys(string $prefix = ""): array
    {
        // Custom implementation
    }

    /**
     * Returns the prefix for the keys
     */
    public function getPrefix(): string
    {
        // Custom implementation
    }

    /**
     * Checks if an element exists in the cache
     */
    public function has(string $key): bool
    {
        // Custom implementation
    }

    /**
     * Increments a stored number
     */
    public function increment(string $key, int $value = 1)
    {
        // Custom implementation
    }

    /**
     * Stores data in the adapter
     */
    public function set(string $key, $value, $ttl = null): bool
    {
        // Custom implementation
    }
}

使用它:

<?php

namespace MyApp;

use MyApp\Storage\Adapter\Custom;

$custom = new Custom();

$custom->set('my-key', $data);

适配器工厂

虽然所有适配器类都可以通过new关键字实例化,Phalcon 提供了 [Phalcon\Storage\AdapterFactory][cache-adapterfactory] 类,以便你可以轻松实例化缓存适配器类。上述所有适配器都已在工厂中注册,并在调用时惰性加载。工厂还允许你注册其他(自定义)适配器类。唯一需要考虑的是选择适配器名称时与现有名称进行比较。如果定义了相同的名称,将会覆盖内置的适配器。对象会在工厂中缓存,因此如果你在同一请求中使用相同参数调用newInstance()方法,你会得到相同的对象返回。

下面的例子展示了如何创建一个Apcu缓存适配器,使用new关键字或工厂:

<?php

use Phalcon\Storage\Adapter\Apcu;
use Phalcon\Storage\Serializer\Json;

$jsonSerializer = new Json();

$options = [
    'defaultSerializer' => 'Json',
    'lifetime'          => 7200,
    'serializer'        => $jsonSerializer,
];

$adapter = new Apcu(null, $options);

<?php

use Phalcon\Storage\AdapterFactory;
use Phalcon\Storage\SerializerFactory;

$serializerFactory = new SerializerFactory();
$adapterFactory    = new AdapterFactory($serializerFactory);

$options = [
    'defaultSerializer' => 'Json',
    'lifetime'          => 7200,
];

$adapter = $adapterFactory->newInstance('apcu', $options);

你可以用于工厂的参数是:

名称 适配器
apcu [Phalcon\Storage\Adapter\Apcu][cache-adapter-apcu]
libmemcached [Phalcon\Storage\Adapter\Libmemcached][cache-adapter-libmemcached]
memory [Phalcon\Storage\Adapter\Memory][cache-adapter-memory]
redis [Phalcon\Storage\Adapter\Redis][cache-adapter-redis]
stream [Phalcon\Storage\Adapter\Stream][cache-adapter-stream]

事件

The Phalcon\Storage\AbstractAdapter对象实现了Phalcon\Events\EventsAware接口。因此,getEventsManager()setEventsManager()可供您使用。

事件 描述 可以停止操作
beforeSet 在设置值之前触发
afterSet 在值设置后触发
beforeGet 在请求值之前触发
afterGet 在值请求后触发
beforeHas 在请求值之前触发
afterHas 在值请求后触发
beforeDelete 在删除值之前触发
afterDelete 在值删除后触发
beforeIncrement 在值递增之前触发
afterIncrement 在值递增后触发
beforeDecrement 在值递减之前触发
afterDecrement 在值递减后触发
无噪 Logo
无噪文档
25 年 6 月翻译
文档源↗