存储组件¶
概览¶
The Phalcon\Storage
命名空间包含用于在不同存储中存储数据的组件。该组件深度集成到Phalcon\Cache\Cache以及Phalcon\Session。它提供基于各种序列化适配器的数据序列化,以及基于各种存储适配器的数据存储。工厂帮助创建组件工作所需的所有必要对象。
序列化器¶
The Phalcon\Storage\Serializer
命名空间提供了实现Serializable接口并因此暴露serialize
和unserialize
方法的类。这些类的目的是在保存数据到存储之前和从存储中检索数据之后对其进行转换。
注意
所有适配器的默认序列化器是Phalcon\Storage\Serializer\Php
,它使用 PHP 的serialize
和unserialize
方法。这些方法可以满足大多数应用程序的需求。然而,开发人员可能希望使用更高效的序列化器,例如igbinary,它更快并且具有更好的压缩效果。
可以配置存储适配器以使用不同的序列化器。可用的序列化器包括:
Base64
¶
此序列化器使用base64_encode
和base64_decode
方法来序列化数据。输入必须是类型string
,因此此序列化器有明显的限制。
Igbinary
¶
The igbinary
序列化依赖于igbinary_serialize
和igbinary_unserialize
方法。这些方法由igbinaryPHP 扩展公开,该扩展必须安装并加载到目标系统上。
Json
¶
The JSON
序列化器使用json_encode
和json_decode
。目标系统必须具备 PHP 的 JSON 支持。
MemcachedIgbinary
¶
当使用Memcached
时可以使用此序列化器。它对应于Memcached
中内置的 PHP 序列化器。
MemcachedJson
¶
当使用Memcached
时可以使用此序列化器。它对应于Memcached
中内置的 PHP 序列化器。
MemcachedPhp
¶
当使用Memcached
时可以使用此序列化器。它对应于Memcached
中内置的 PHP 序列化器。
Msgpack
¶
类似于igbinary
超全局变量。如果cookie存在于任一集合中,则返回msgpack
序列化器使用msgpack_pack
和msgpack_unpack
进行数据的序列化和反序列化。这与igbinary
之一是最快的和最有效的序列化器之一。但是,它要求目标系统加载了msgpackPHP 扩展。
None
¶
此序列化器不转换数据。它的serialize
和unserialize
获取和设置数据而不改变它。
Php
¶
这是默认的序列化器。它使用 PHP 的serialize
和unserialize
方法进行数据转换。
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。这个类并不使用实际的适配器,因为功能是通过apcu
PHP函数暴露的。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
连接到端口11211
和10.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\MemcachedJson或Phalcon\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\RedisNone或Phalcon\Storage\Serializer\RedisPhp.
注意 increment
- decrement
目前存在一个问题与Redis
,其中内部Redis
序列化器不会跳过标量值,因为它只能存储字符串。结果是,如果你在increment
后使用set
对于数字,将不会返回一个数字:
存储数字并使用increment
(或decrement
的方法是删除内部序列化器Redis
或者你可以使用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 | 在值递减后触发 | 否 |