---
title: "Cache"
version: "5.15"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.phalcon.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Cache

## Overview

The [Phalcon\Cache\Cache][cache-cache] is a component that offers a lightweight yet flexible caching mechanism to be
used with your Phalcon applications.

Frequently used data or already processed/calculated data, can be stored in a cache storage for easier and faster
retrieval. Since [Phalcon\Cache\Cache][cache-cache] is written in
Zephir, and therefore compiled as C code, it can achieve higher performance while reducing the overhead that comes with
getting data from any storage container. Some examples that
warrant the use of a cache are:

* You are making complex calculations and the output does not change frequently
* You are producing HTML using the same data all the time (same HTML)
* You are accessing database data constantly which does not change often.

:::info[NOTE]
Even after implementing the cache, you should always check the hit ratio of your cache backend over a period of time, to ensure that your cache strategy is optimal.
:::

[Phalcon\Cache\Cache][cache-cache] components rely on `Phalcon\Storage` components. `Phalcon\Storage` is split into two
categories: Serializers and Adapters.

## Cache

In order to instantiate a new [Phalcon\Cache\Cache][cache-cache] component, you will need to pass a
`Phalcon\Cache\Adapter\*` class in it or one that implements
the [Phalcon\Cache\Adapter\AdapterInterface][cache-adapter-adapterinterface]. For a detailed explanation of adapters and
serializers, see below.

```php
<?php

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

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

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

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

$cache = new Cache($adapter);
```

### Operations

The cache component implements methods that are inline with [PSR-16][psr-16], but does not implement the particular
interface. A package that implements [PSR-16][psr-16] is
available, that uses [Phalcon\Cache\Cache][cache-cache]. The package is located [here][proxy-psr16]. To use it, you will
need to have Phalcon installed and then using composer you
can install the proxy package.

```sh
composer require phalcon/proxy-psr16
```

Using the proxy classes allows you to follow [PSR-16][psr-16] and use it with any other package that needs that
interface.

Each Cache component contains a supplied Cache adapter which in turn is responsible for all operations.

:::info[NOTE]
Cache keys are validated on every operation. A key must be a non-empty string containing only the characters `A-Z`, `a-z`, `0-9`, `-`, `_`, and `.`. An empty key, or one containing any other character, throws `Phalcon\Cache\Exception\InvalidArgumentException` before the operation runs. The same validation applies to every key in the `*Multiple` operations.
:::

### `get` - `getMultiple`

To get data from the cache you need to call the `get()` method with a key and a default value. If the key exists, or it
has not expired, the data stored in it will be returned.
Alternatively the passed `defaultValue` will be returned (default `null`).

```php
$value = $cache->get('my-key');

$value = $cache->get('my-key', 'default');
```

If you wish to retrieve more than one key with one call, you can call `getMultiple()`, passing an array with the keys
needed. The method will return an array of `key` => `value`
pairs. Cache keys that do not exist or have expired will have `defaultValue` as a value (default `null`).

```php
$value = $cache->getMultiple(['my-key1', 'my-key2']);

$value = $cache->getMultiple(['my-key1', 'my-key2'], 'default');
```

:::info[NOTE]
With the Redis adapter, `getMultiple()` uses a single `mget` call to retrieve every key at once, which is more efficient than one round trip per key. Each key is validated first, `Traversable` inputs are accepted, and a corrupt stored entry returns the default value, so the Redis path behaves like the per-key path used by the other adapters.
:::

### `has`

To check whether a key exists in the cache (or it has not expired) you can call the `has()` method. The method will
return `true` if the key exists, or `false` otherwise.

```php
$exists = $cache->has('my-key');
```

### `set` - `setMultiple`

To save the data in the cache, you will need to use the `set()` method. The method accepts the key we wish to store the
data under and the value of the item to store. The data
needs to be of a type that supports serialization i.e. PHP type or an object that implements serialization. The last (
optional) parameter is the TTL (time to live) value for this
item. This option might not always be available if the underlying adapter does not support it. The method will return
`true` if the key exists, or `false` otherwise. If even one
key is not successfully stored, the method will return `false`.

```php
$result = $cache->set('my-key', $data);
```

If you wish to store more than one element with one call, you can call `setMultiple()`, passing an array of key => value
pairs for the multiple-set operation. As with `set` the
last (optional) parameter is the TTL (time to live). The method will return `true` if the key exists, or `false`
otherwise.

```php
$value = $cache->setMultiple(
[
    'my-key1' => $data1, 
    'my-key2' => $data2,
],
9600
);
```

:::info[NOTE]
Every key is validated before any value is written. If one of the keys is not a legal value, the operation throws `Phalcon\Cache\Exception\InvalidArgumentException` without storing any of the pairs.
:::

### `delete` - `deleteMultiple` - `clear`

To delete an item from the cache you need to call the `delete()` method with a key. The method returns `true` on success
and `false` on failure.

```php
$result = $cache->delete('my-key');
```

If you wish to delete more than one key with one call, you can call `deleteMultiple()`, passing an array with the keys
needed. The method returns `true` if all keys were
successfully deleted, or `false` if any key did not exist or could not be deleted. The keys are validated before
deletion - if a key contains invalid characters, a
`Phalcon\Cache\Exception\InvalidArgumentException` will be thrown.

```php
$result = $cache->deleteMultiple(['my-key1', 'my-key2']);
```

If you wish to clear all the keys, you can call the `clear()` method. The method returns `true` on success and `false`
on failure.

## Factory

### `newInstance`

We can easily create a [Phalcon\Cache\Cache][cache-cache] class using the `new` keyword. However, Phalcon offers
the [Phalcon\Cache\CacheFactory][cache-cachefactory] class, so that
developers can easily instantiate cache objects. The factory accepts
a [Phalcon\Cache\AdapterFactory][cache-adapterfactory] object (which in turn requires
a `Phalcon\Storage\SerializerFactory` object) and can instantiate the necessary Cache class with the selected adapter
and options. The factory always returns a new instance
of [Phalcon\Cache\Cache][cache-cache].

The example below shows how you can create a cache object using the `Apcu` adapter and `Json` serializer:

```php
<?php

use Phalcon\Cache\CacheFactory;
use Phalcon\Cache\AdapterFactory;
use Phalcon\Storage\SerializerFactory;

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

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

$cacheFactory = new CacheFactory($adapterFactory);

$cache = $cacheFactory->newInstance('apcu');
```

### `load`

The Cache Factory also offers the `load` method, which accepts a configuration object. This object can be an array or
a [Phalcon\Config\Config][config] object, with directives that
are used to set up the cache. The object requires the `adapter` element, as well as the `options` element with the
necessary directives.

```php
<?php

use Phalcon\Cache\CacheFactory;
use Phalcon\Cache\AdapterFactory;
use Phalcon\Storage\SerializerFactory;

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

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

$cacheFactory = new CacheFactory($adapterFactory);

$cacheOptions = [
'adapter' => 'apcu',
'options' => [
    'prefix' => 'my-prefix',
],
];

$cache = $cacheFactory->load($cacheOptions);
```

## Serializers

The `Phalcon\Storage\Serializer` namespace offers classes that implement the [Serializable][serializable] interface and
thus expose the `serialize` and `unserialize` methods. The
purpose of these classes is to transform the data before saving it to the storage and after retrieving it from the
storage.

:::info[NOTE]
The default serializer for all adapters is `Phalcon\Storage\Serializer\Php` which uses PHP's `serialize` and `unserialize` methods. These methods can suit most applications. However, the developer might want to use something more efficient such as [igbinary][igbinary] which is faster and achieves better compression. 
:::

The cache adapter can be configured to use a different serializer. The available serializers are:

### `Base64`

This serializer uses the `base64_encode` and `base64_decode` methods to serialize data. The input must be of type
`string`, therefore this serializer has obvious limitations

### `Igbinary`

The `igbinary` serializes relies on the `igbinary_serialize` and `igbinary_unserialize` methods. Those methods are
exposed via the [igbinary][igbinary] PHP extension, which has to
be installed and loaded on the target system.

### `Json`

The `JSON` serializer uses `json_encode` and `json_decode`. The target system must have JSON support available for PHP.

### `MemcachedIgbinary`

This serializer can be used when using `Memcached`. It corresponds to the built-in Igbinary serializer that `Memcached`
has.

### `MemcachedJson`

This serializer can be used when using `Memcached`. It corresponds to the built-in JSON serializer that `Memcached` has.

### `MemcachedPhp`

This serializer can be used when using `Memcached`. It corresponds to the built-in PHP serializer that `Memcached` has.

### `Msgpack`

Similar to `igbinary` the `msgpack` serializer uses `msgpack_pack` and `msgpack_unpack` for serializing and
unserializing data. This, along with `igbinary` is one of the fastest
and most efficient serializers. However, it requires that the [msgpack][msgpack] PHP extension is loaded on the target
system.

### `None`

This serializer does not transform the data at all. Both its `serialize` and `unserialize` get and set the data without
altering it.

### `Php`

This is the default serializer. It uses PHP's `serialize` and `unserialize` methods for data transformations.

### `RedisIgbinary`

This serializer can be used when using `Redis`. It corresponds to the built-in Igbinary serializer that `Redis` has.

### `RedisJson`

This serializer can be used when using `Redis`. It corresponds to the built-in JSON serializer that `Redis` has.

### `RedisMsgpack`

This serializer can be used when using `Redis`. It corresponds to the built-in Msgpack serializer that `Redis` has.

### `RedisNone`

This serializer can be used when using `Redis`. It corresponds to the built-in None serializer that `Redis` has.

### `RedisPhp`

This serializer can be used when using `Redis`. It corresponds to the built-in PHP serializer that `Redis` has.

### Custom

Phalcon also offers the [Phalcon\Storage\Serializer\SerializerInterface][storage-serializer-serializerinterface]` which
can be implemented in a custom class. The class can offer
the serialization you require.

```php
<?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);
}
}
```

Using it:

```php
<?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."
``` 

## Serializer Factory

Although all serializer classes can be instantiated using the `new` keyword, Phalcon offers
the [Phalcon\Storage\SerializerFactory][storage-serializerfactory] class, so that
developers can easily instantiate serializer classes. All the above serializers are registered in the factory and lazy
loaded when called. The factory also allows you to register
additional (custom) serializer classes. The only thing to consider is choosing the name of the serializer in comparison
to the existing ones. If you define the same name, you will
overwrite the built-in one. The objects are cached in the factory so if you call the `newInstance()` method with the
same parameters during the same request, you will get the same
object back.

The example below shows how you can create a `Json` serializer either using the `new` keyword or the factory:

```php
<?php

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

$jsonSerializer = new Json();

$factory        = new SerializerFactory();
$jsonSerializer = $factory->newInstance('json');
```

The parameters you can use for the factory are:

| **Name**             | **Class**                                                                             |
|----------------------|---------------------------------------------------------------------------------------|
| `base64`             | [Phalcon\Storage\Serializer\Base64][storage-serializer-base64]                        |
| `igbinary`           | [Phalcon\Storage\Serializer\Igbinary][storage-serializer-igbinary]                    |
| `json`               | [Phalcon\Storage\Serializer\Json][storage-serializer-json]                            |
| `memcached_igbinary` | [Phalcon\Storage\Serializer\MemcachedIgbinary][storage-serializer-memcached-igbinary] |
| `memcached_json`     | [Phalcon\Storage\Serializer\MemcachedJson][storage-serializer-memcached-json]         |
| `memcached_php`      | [Phalcon\Storage\Serializer\MemcachedPhp][storage-serializer-memcached-php]           |
| `msgpack`            | [Phalcon\Storage\Serializer\Msgpack][storage-serializer-msgpack]                      |
| `none`               | [Phalcon\Storage\Serializer\None][storage-serializer-none]                            |
| `php`                | [Phalcon\Storage\Serializer\Php][storage-serializer-php]                              |
| `redis_igbinary`     | [Phalcon\Storage\Serializer\RedisIgbinary][storage-serializer-redis-igbinary]         |
| `redis_json`         | [Phalcon\Storage\Serializer\RedisJson][storage-serializer-redis-json]                 |
| `redis_msgpack`      | [Phalcon\Storage\Serializer\RedisMsgpack][storage-serializer-redis-msgpack]           |
| `redis_none`         | [Phalcon\Storage\Serializer\RedisNone][storage-serializer-redis-none]                 |
| `redis_php`          | [Phalcon\Storage\Serializer\RedisPhp][storage-serializer-redis-php]                   |

## Adapters

The `Phalcon\Cache\Adapter` namespace offers classes that implement
the [Phalcon\Cache\Adapter\AdapterInterface][cache-adapter-adapterinterface] interface. It exposes common
methods that are used to perform operations on the storage adapter or cache backend. These adapters act as wrappers to
respective backend code.

The available methods are:

| Method           | Description                                                                |
|------------------|----------------------------------------------------------------------------|
| `clear`          | Flushes/clears the cache                                                   |
| `decrement`      | Decrements a stored number                                                 |
| `delete`         | Deletes data from the adapter                                              |
| `deleteMultiple` | Deletes multiple keys from the adapter in a single operation               |
| `get`            | Reads data from the adapter                                                |
| `getAdapter`     | Returns the already connected adapter or connects to the backend server(s) |
| `getKeys`        | Returns all the keys stored (optional filter parameter)                    |
| `getPrefix`      | Returns the prefix for the keys                                            |
| `has`            | Checks if an element exists in the cache                                   |
| `increment`      | Increments a stored number                                                 |
| `set`            | Stores data in the adapter                                                 |
| `setForever`     | Stores data in the adapter without an expiration                           |

:::info[NOTE]
The `getAdapter()` method returns the connected adapter. This offers more flexibility to the developer since it can be used to execute additional methods that each adapter offers. For instance, for the `Redis` adapter you can use the `getAdapter()` to obtain the connected object and call `zAdd`, `zRange`, and other methods not exposed by the Phalcon adapter.
:::

:::info[NOTE]
Keys returned by `getKeys()` carry the adapter prefix. As of 5.14.2 the adapters also accept keys that already carry the prefix: `get()`, `has()`, `delete()`, `deleteMultiple()`, `set()`, `setForever()`, `increment()` and `decrement()` strip a leading prefix from the supplied key before applying their own, so the output of `getKeys()` can be passed back to these methods unchanged.
:::

:::warning[NOTE]
A consequence of the stripping is that a key whose name happens to start with the prefix text addresses the same record as the bare key: with prefix `data-`, `set('data-users', ...)` and `set('users', ...)` write to the same stored entry. If your keys are externally generated identifiers, or can legitimately begin with the prefix text, disable the behavior with the `stripPrefix` option (default `true`) when constructing the adapter.
:::

:::info[NOTE]
The adapters differ in counter atomicity and in how `getKeys()` is implemented - for example `Redis` enumerates keys with a non-blocking `SCAN`, while `Stream` walks the directory tree. See the [adapter capability matrix](/5.15/storage/#capability-matrix) in the Storage documentation for the per-adapter details.
:::

To construct one of these objects, you will need to pass
a [Phalcon\Storage\SerializerFactory][storage-serializerfactory] object in the constructor and optionally some
parameters
required for the adapter of your choice. The list of options is outlined below.

The available adapters are:

### `Apcu`

This adapter uses `Apcu` to store the data. In order to use this adapter, you will need to have [apcu][apcu] enabled in
your target system. This class does not use an actual
_adapter_, since the `apcu` functionality is exposed using the `apcu_*` PHP functions.

| Option              | Default    |
|---------------------|------------|
| `defaultSerializer` | `Php`      |
| `lifetime`          | `3600`     |
| `serializer`        | `null`     |
| `prefix`            | `ph-apcu-` |
| `stripPrefix`       | `true`     |

The following example demonstrates how to create a new `Apcu` cache adapter, which will use
the [Phalcon\Storage\Serializer\Json][storage-serializer-json] serializer and have a
default lifetime of 7200.

```php
<?php

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

$serializerFactory = new SerializerFactory();

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

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

The above example used a [Phalcon\Storage\SerializerFactory][storage-serializerfactory] object and the
`defaultSerializer` option to tell the adapter to instantiate the relevant
serializer.

### `Libmemcached`

This adapter utilizes PHP's [memcached][memcached] extension to connect to Memcached servers. The adapter used is an
instance of the `Memcached` class, created after the first
event that requires the connection to be active.

| Option                                          | Default                               |
|-------------------------------------------------|---------------------------------------|
| `defaultSerializer`                             | `Php`                                 |
| `lifetime`                                      | `3600`                                |
| `serializer`                                    | `null`                                |
| `prefix`                                        | `ph-memc-`                            |
| `stripPrefix`                                   | `true`                                |
| `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`                                   |

You can specify more than one server in the options array passed in the constructor. If `SASL` data is defined, the
adapter will try to authenticate using the passed data. If there
is an error in the options or the class cannot add one or more servers in the pool, a `Phalcon\Storage\Exception` will
be thrown.

The following example demonstrates how to create a new `Libmemcached` cache adapter, which will use
the [Phalcon\Storage\Serializer\Json][storage-serializer-json] serializer and
have a default lifetime of 7200. It will use the `10.4.13.100` as the first server with weight `1` connecting to port
`11211` and `10.4.13.110` as the second server with weight `5`
again connecting to port `11211`.

```php
<?php

use Phalcon\Cache\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);
```

The above example used a [Phalcon\Storage\SerializerFactory][storage-serializerfactory] object and the
`defaultSerializer` option to tell the adapter to instantiate the relevant
serializer.

**Serializers**: The `Memcached` class which is the adapter that
the [Phalcon\Cache\Adapter\Libmemcached][cache-adapter-libmemcached] uses, offers support for serializing out of
the box. The built-in serializers are:

* `\Memcached::SERIALIZER_PHP`
* `\Memcached::SERIALIZER_JSON`
* `\Memcached::SERIALIZER_IGBINARY`

The [igbinary][igbinary] built-in serializer is only available if `igbinary` is present in the target system
and [Memcached][memcached] extension is compiled with it. To enable
these serializers, you can use
the [Phalcon\Storage\Serializer\MemcachedIgbinary][storage-serializer-memcached-igbinary], [Phalcon\Storage\Serializer\MemcachedJson][storage-serializer-memcached-json]
or [Phalcon\Storage\Serializer\MemcachedPhp][storage-serializer-memcached-php]

### `Memory`

This adapter uses the computer's memory to store the data. As all data is stored in memory, there is no persistence,
meaning that once the request is completed, the data is lost.
This adapter can be used for testing or temporary storage during a particular request. The options available for the
constructor are:

| Option              | Default    |
|---------------------|------------|
| `defaultSerializer` | `Php`      |
| `lifetime`          | `3600`     |
| `serializer`        | `null`     |
| `prefix`            | `ph-memo-` |
| `stripPrefix`       | `true`     |

The following example demonstrates how to create a new `Memory` cache adapter, which will use
the [Phalcon\Storage\Serializer\Json][storage-serializer-json] serializer and have a
default lifetime of 7200.

```php
<?php

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

$serializerFactory = new SerializerFactory();

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

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

The above example used a [Phalcon\Storage\SerializerFactory][storage-serializerfactory] object and the
`defaultSerializer` option to tell the adapter to instantiate the relevant
serializer.

### `Redis`

This adapter utilizes PHP's [redis][redis] extension to connect to a Redis server. The adapter used is an instance of
the `Redis` class, created after the first event that requires
the connection to be active.

| Option              | Default     |
|---------------------|-------------|
| `defaultSerializer` | `Php`       |
| `lifetime`          | `3600`      |
| `serializer`        | `null`      |
| `prefix`            | `ph-reds-`  |
| `stripPrefix`       | `true`      |
| `host`              | `127.0.0.1` |
| `port`              | `6379`      |
| `index`             | `1`         |
| `persistent`        | `false`     |
| `auth`              |             |
| `socket`            |             |

If `auth` data is defined, the adapter will try to authenticate using the passed data. If there is an error in the
options, or the server cannot connect or authenticate,
a `Phalcon\Storage\Exception` will be thrown.

The following example demonstrates how to create a new `Redis` cache adapter, which will use
the [Phalcon\Storage\Serializer\Json][storage-serializer-json] serializer and have a
default lifetime of 7200. It will use the `10.4.13.100` as the host, connect to port `6379`, and select the index `1`.

```php
<?php

use Phalcon\Cache\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);
```

The above example used a [Phalcon\Storage\SerializerFactory][storage-serializerfactory] object and the
`defaultSerializer` option to tell the adapter to instantiate the relevant
serializer.

**Serializers**: The `Redis` class which is the adapter that the [Phalcon\Cache\Adapter\Redis][cache-adapter-redis]
uses, offers support for serializing out of the box. The
built-in serializers are:

* `\Redis::SERIALIZER_NONE`
* `\Redis::SERIALIZER_PHP`
* `\Redis::SERIALIZER_IGBINARY`
* `\Redis::SERIALIZER_MSGPACK`

The [igbinary][igbinary] and built-in serializer are only available if `igbinary` is present in the target system
and [Redis][redis] extension is compiled with it. The same applies
to [msgpack][msgpack] built-in serializer. It is only available if `msgpack` is present in the target system and
the [Redis][redis] extension is compiled with it. To enable these
serializers, you can use
the [Phalcon\Storage\Serializer\RedisIgbinary][storage-serializer-redis-igbinary], [Phalcon\Storage\Serializer\RedisJson][storage-serializer-redis-json], [Phalcon\Storage\Serializer\RedisMsgpack][storage-serializer-redis-msgpack], [Phalcon\Storage\Serializer\RedisNone][storage-serializer-redis-none]
or [Phalcon\Storage\Serializer\RedisPhp][storage-serializer-redis-php].

**NOTE** `increment` - `decrement`

At this point in time, there is an issue with `Redis`, where the internal `Redis` serializer does not skip scalar values
because it can only store strings. As a result, if you
use `increment` after a `set` for a number, will not return a number:

The way to store numbers and use the `increment` (or `decrement`) is to either remove the internal serializer for
`Redis`

```php
$cache->getAdapter()->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_NONE);
```

or you could use `increment` instead of using `set` at the first setting of the value to the key:

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

### `Stream`

This adapter is the simplest to set up since it uses the target system's file system (it only requires a cache path that
is writeable). It is one of the slowest cache adapters
since the data has to be written to the file system. Each file created corresponds to a key stored. The file contains
additional metadata to calculate the lifetime of the cache
element, resulting in additional reads and writes to the file system.

| Option              | Default   |
|---------------------|-----------|
| `defaultSerializer` | `Php`     |
| `lifetime`          | `3600`    |
| `serializer`        | `null`    |
| `prefix`            | `phstrm-` |
| `stripPrefix`       | `true`    |
| `storageDir`        |           |

If the `storageDir` is not defined a `Phalcon\Storage\Exception` will be thrown.

:::info[NOTE]
The adapter utilizes logic to store files in separate subdirectories based on the name of the key passed, thus avoiding the `too many files in one folder` limit present in Windows or Linux-based systems.
:::

The following example demonstrates how to create a new `Stream` cache adapter, which will use
the [Phalcon\Storage\Serializer\Json][storage-serializer-json] serializer and have a
default lifetime of 7200. It will store the cached data in `/data/storage/cache`.

```php
<?php

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

$serializerFactory = new SerializerFactory();

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

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

The above example used a [Phalcon\Storage\SerializerFactory][storage-serializerfactory] object and the
`defaultSerializer` option to tell the adapter to instantiate the relevant
serializer.

### Custom

Phalcon also offers the [Phalcon\Cache\Adapter\AdapterInterface][cache-adapter-adapterinterface] which can be
implemented in a custom class. The class can offer the cache adapter
functionality you require.

```php
<?php

namespace MyApp\Cache\Adapter;

use Phalcon\Cache\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
}

/**
 * Deletes multiple keys from the adapter
 */
public function deleteMultiple(array $keys): 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
}
}
```

Using it:

```php
<?php

namespace MyApp;

use MyApp\Cache\Adapter\Custom;

$custom = new Custom();

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

## Adapter Factory

Although all adapter classes can be instantiated using the `new` keyword, Phalcon offers
the [Phalcon\Cache\AdapterFactory][cache-adapterfactory] class, so that you can easily
instantiate cache adapter classes. All the above adapters are registered in the factory and lazy loaded when called. The
factory also allows you to register additional (custom)
adapter classes. The only thing to consider is choosing the name of the adapter in comparison to the existing ones. If
you define the same name, you will overwrite the built-in
one. The objects are cached in the factory so if you call the `newInstance()` method with the same parameters during the
same request, you will get the same object back.

The example below shows how you can create an `Apcu` cache adapter with the `new` keyword or the factory:

```php
<?php

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

$jsonSerializer = new Json();

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

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

```php
<?php

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

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

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

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

The parameters you can use for the factory are:

| Name           | Adapter                                                          |
|----------------|------------------------------------------------------------------|
| `apcu`         | [Phalcon\Cache\Adapter\Apcu][cache-adapter-apcu]                 |
| `libmemcached` | [Phalcon\Cache\Adapter\Libmemcached][cache-adapter-libmemcached] |
| `memory`       | [Phalcon\Cache\Adapter\Memory][cache-adapter-memory]             |
| `redis`        | [Phalcon\Cache\Adapter\Redis][cache-adapter-redis]               |
| `stream`       | [Phalcon\Cache\Adapter\Stream][cache-adapter-stream]             |

## Events

The [Phalcon\Cache\AbstractCache][cache-abstract-cache] object implements the
[Phalcon\Events\EventsAware][events-eventsawareinterface] interfaces.
As a result `getEventsManager()` and `setEventsManager()` are available for you to use.

| Event                  | Description                                   | Can stop operation |
|------------------------|-----------------------------------------------|:------------------:|
| `beforeSet`            | Fires before the value is set                 |         No         |
| `afterSet`             | Fires after the value has been set            |         No         |
| `beforeGet`            | Fires before the value is requested           |         No         |
| `afterGet`             | Fires after the value has been requested      |         No         |
| `beforeHas`            | Fires before the value is requested           |         No         |
| `afterHas`             | Fires after the value has been requested      |         No         |
| `beforeDelete`         | Fires before the value is deleted             |         No         |
| `afterDelete`          | Fires after the value has been deleted        |         No         |
| `beforeDeleteMultiple` | Fires before multiple values are deleted      |         No         |
| `afterDeleteMultiple`  | Fires after multiple values have been deleted |         No         |
| `beforeIncrement`      | Fires before the value has been incremented   |         No         |
| `afterIncrement`       | Fires after the value has been incremented    |         No         |
| `beforeDecrement`      | Fires before the value has been decremented   |         No         |
| `afterDecrement`       | Fires after the value has been decremented    |         No         |

### Event Layers

Cache operations can emit `cache:*` events from two layers. The cache facade
([Phalcon\Cache\AbstractCache][cache-abstract-cache]) fires `cache:before*` and
`cache:after*` around each operation, and the underlying `Storage` adapter also
fires `cache:*` events for the same operation. If you wire an events manager
into both the cache object and its adapter, a single operation emits each event
twice. Wire the manager into one layer only. The cache facade is the supported
source for cache-level events, and it is the only layer that emits the multi-key
`*Multiple` events.

The `before*` events fire only after key validation passes, so an operation that
throws on an invalid key does not emit its `before*` event.

## Contracts

The canonical interface for this component lives in the `Phalcon\Contracts\Cache` namespace, with the `Interface`
suffix dropped. `Phalcon\Cache\CacheInterface` remains available: it now extends its contract and is deprecated.
Existing implementations and type hints keep working unchanged; new code should target the contract.

| Deprecated interface           | Canonical contract              |
|---------------------------------|---------------------------------|
| `Phalcon\Cache\CacheInterface`  | `Phalcon\Contracts\Cache\Cache` |

`Phalcon\Contracts\Cache\Cache` declares the PSR-16-shaped cache surface (`get`, `set`, `has`, `delete`, `clear`, and
the `*Multiple` variants). It does not extend `Psr\SimpleCache\CacheInterface`.

## Exceptions

Any exception thrown in the Cache component is of
type [Phalcon\Cache\Exception\Exception][cache-exception-exception]. Invalid arguments — a cache
key that is not a string or contains reserved characters, or a non-iterable set of keys passed to
`getMultiple()` / `setMultiple()` / `deleteMultiple()` — raise
[Phalcon\Cache\Exception\InvalidArgumentException][cache-exception-invalidargumentexception]
instead. Both extend `\Exception`. You can use these exceptions to selectively catch failures from
this component.

```php
<?php

use Phalcon\Cache\Exception\Exception;
use Phalcon\Mvc\Controller;

class IndexController extends Controller
{
public function index()
{
    try {
        $content = $this->cache->get('some-key');
    } catch (Exception $ex) {
        echo $ex->getMessage();
    }
}
}
```

### PSR-16 Compatibility

The class raised for an invalid argument is resolved through
`Phalcon\Cache\AbstractCache::getExceptionClass()`, which returns
`Phalcon\Cache\Exception\InvalidArgumentException` by default.

The Cache component does not implement PSR-16 (`Psr\SimpleCache`), and neither do its exceptions.
For PSR-16 interoperability — including a `Psr\SimpleCache\InvalidArgumentException` that callers
can catch — install the [proxy package][proxy-psr16]. The proxy overrides `getExceptionClass()` to
return a PSR-16-marked exception, so the marker is restored without any catch-and-rethrow overhead.

```sh
composer require phalcon/proxy-psr16
```

[psr-16]: https://www.php-fig.org/psr/psr-16/

[serializable]: https://www.php.net/manual/en/class.serializable.php

[igbinary]: https://github.com/igbinary/igbinary7

[msgpack]: https://msgpack.org/

[apcu]: https://www.php.net/manual/en/book.apcu.php

[memcached]: https://www.php.net/manual/en/book.memcached.php

[redis]: https://github.com/phpredis/phpredis

[cache-cache]: /5.15/api/phalcon_cache/#cachecache

[cache-abstract-cache]: /5.15/api/phalcon_cache/#cacheabstractcache

[cache-adapter-adapterinterface]: /5.15/api/phalcon_cache/#cacheadapteradapterinterface

[cache-adapter-apcu]: /5.15/api/phalcon_cache/#cacheadapterapcu

[cache-adapter-libmemcached]: /5.15/api/phalcon_cache/#cacheadapterlibmemcached

[cache-adapter-memory]: /5.15/api/phalcon_cache/#cacheadaptermemory

[cache-adapter-redis]: /5.15/api/phalcon_cache/#cacheadapterredis

[cache-adapter-stream]: /5.15/api/phalcon_cache/#cacheadapterstream

[cache-adapterfactory]: /5.15/api/phalcon_cache/#cacheadapterfactory

[cache-cachefactory]: /5.15/api/phalcon_cache/#cachecachefactory

[cache-exception-exception]: /5.15/api/phalcon_cache/#cacheexceptionexception

[cache-exception-invalidargumentexception]: /5.15/api/phalcon_cache/#cacheexceptioninvalidargumentexception

[proxy-psr16]: https://github.com/phalcon/proxy-psr16

[storage-adapter-abstractadapter]: /5.15/api/phalcon_storage/#storageadapterabstractadapter

[storage-adapter-adapterinterface]: /5.15/api/phalcon_storage/#storageadapteradapterinterface

[storage-adapter-apcu]: /5.15/api/phalcon_storage/#storageadapterapcu

[storage-adapter-libmemcached]: /5.15/api/phalcon_storage/#storageadapterlibmemcached

[storage-adapter-memory]: /5.15/api/phalcon_storage/#storageadaptermemory

[storage-adapter-redis]: /5.15/api/phalcon_storage/#storageadapterredis

[storage-adapter-stream]: /5.15/api/phalcon_storage/#storageadapterstream

[storage-adapterfactory]: /5.15/api/phalcon_storage/#storageadapterfactory

[storage-exception]: /5.15/api/phalcon_storage/#storageexception

[storage-serializer-abstractserializer]: /5.15/api/phalcon_storage/#storageserializerabstractserializer

[storage-serializer-base64]: /5.15/api/phalcon_storage/#storageserializerbase64

[storage-serializer-igbinary]: /5.15/api/phalcon_storage/#storageserializerigbinary

[storage-serializer-json]: /5.15/api/phalcon_storage/#storageserializerjson

[storage-serializer-msgpack]: /5.15/api/phalcon_storage/#storageserializermsgpack

[storage-serializer-none]: /5.15/api/phalcon_storage/#storageserializernone

[storage-serializer-php]: /5.15/api/phalcon_storage/#storageserializerphp

[storage-serializer-memcached-igbinary]: /5.15/api/phalcon_storage/#storageserializermemcachedigbinary

[storage-serializer-memcached-json]: /5.15/api/phalcon_storage/#storageserializermemcachedjson

[storage-serializer-memcached-php]: /5.15/api/phalcon_storage/#storageserializermemcachedphp

[storage-serializer-redis-igbinary]: /5.15/api/phalcon_storage/#storageserializerredisigbinary

[storage-serializer-redis-json]: /5.15/api/phalcon_storage/#storageserializerredisjson

[storage-serializer-redis-msgpack]: /5.15/api/phalcon_storage/#storageserializerredismsgpack

[storage-serializer-redis-none]: /5.15/api/phalcon_storage/#storageserializerredisnone

[storage-serializer-redis-php]: /5.15/api/phalcon_storage/#storageserializerredisphp

[storage-serializer-serializerinterface]: /5.15/api/phalcon_storage/#storageserializerserializerinterface

[storage-serializerfactory]: /5.15/api/phalcon_storage/#storageserializerfactory

[config]: /5.15/config/

[events-eventsawareinterface]: /5.15/api/phalcon_events/#eventseventsawareinterface

Source: https://docs.phalcon.io/5.15/cache/index.mdx
