Skip to content
SQKo edited this page Dec 11, 2022 · 5 revisions

DiscordPHP caching is powered by react/cache or any compatible psr/simple-cache. The Interface can be accessed from any repositories, e.g. $repository->cache

// 115233618997149700 is User ID for D.PHP#6809 Bot
$discord->users->cache->get('115233618997149700')->then(function ($user) {
    // $user is a cached Part
});

Albeit example, it's preferred to fetch user like usual:

$discord->users->fetch('115233618997149700', true)->then(function ($user) {
    // $user fetched from Discord API will automatically update the cache
});

The cache interfaces are handled in Promise manner, while it may speed up when combined with async, it is not as fast as previous in-memory caching existed since DiscordPHP v5.x. The caching interface suits for those who wants to scale up their Bot and not bound to PHP memory limit & process, at cost of the speed.

All methods deriving from AbstractRepository (no more Collection) handles the cache implementation already.

The cache prefix can be retrieved from the repository which in the case above $discord->users->cache->getPrefix() would return User., where User is the name of the Part class.

Note: Caching libraries containing namespace "Redis" or "Memcached" will by default use the : colon instead of . dot for separator. If you found implementation without the name containing "Redis" or "Memcached", please specify the $separator manually with CacheConfig class.

$psr6Cache = new RedisAdapter($redis, 'dphp', 0); // "Redis" in "RedisAdapter" here can not be detected
$cache = new Psr16Cache($psr6Cache); // Since the wrapper class name does not have "Redis", it will not use colon
'cache' => new CacheConfig(interface: $cache, separator = ':'); // set separator to colon

Known available implementation:

Bundled in ReactPHP Cache, uses in-memory Array, and is used by default.

$cache = new ArrayCache(100); // 100 is the limit with LRU policy

Does not work on Windows

use React\EventLoop\Loop;
use React\Filesystem\Filesystem as ReactFilesystem;
use WyriHaximus\React\Cache\Filesystem;

$loop = Loop::get();
$filesystem = ReactFilesystem::create($loop);
$cache = new Filesystem($filesystem, '/tmp/cache/dphp/');

$discord = new Discord([
    'token' => 'bot token',
    'loop' => $loop, // note the same loop
    'cache' => $cache,
]);

Note the examples below uses ReactPHP-Redis v2.x

use React\EventLoop\Loop;
use WyriHaximus\React\Cache\Redis;

$loop = Loop::get();
$redis = (new Clue\React\Redis\Factory($loop))->createLazyClient('localhost:6379');
$cache = new Redis($redis, 'dphp:'); // prefix is "dphp:"

$discord = new Discord([
    'token' => 'bot token',
    'loop' => $loop, // note the same loop
    'cache' => $cache,
]);

By default the cache key is prefixed reach:cache:, in example above the prefix is changed to dphp: so you can get the data as: dphp:User:115233618997149700.

If you are not fan of ReactPHP Asynchronous Cache library, you can try a compatible PSR-16 Synchronous Cache library, Please note this implementation is slower as it blocks the event loop and may break your bot if not used carefully.

Note the following section uses PSR-16 Adapter

Equivalent to ArrayCache from ReactPHP.

use Symfony\Component\Cache\Adapter\ArrayAdapter;

$psr6Cache = new ArrayAdapter(0, false, 0, 100); // 100 is the limit
$cache = new \Symfony\Component\Cache\Psr16Cache($psr6Cache);

$discord = new Discord([
    'token' => 'bot token',
    'cache' => $cache,
]);

Note the examples below uses Redis PECL

use Symfony\Component\Cache\Adapter\RedisAdapter;

$redis = new \Redis();
$redis->connect('localhost');
$psr6Cache = new RedisAdapter($redis, 'dphp', 0); // prefix is "dphp:"
$cache = new \Symfony\Component\Cache\Psr16Cache($psr6Cache);

$discord = new Discord([
    'token' => 'bot token',
    'cache' => $cache,
]);

Note the examples below uses Memcached PECL

use Symfony\Component\Cache\Adapter\MemcachedAdapter;

$memcached = new \Memcached();
$memcached->addServer('localhost', 11211);
$psr6Cache = new MemcachedAdapter($memcached, 'dphp', 0); // prefix is "dphp:"
$cache = new \Symfony\Component\Cache\Psr16Cache($psr6Cache);

$discord = new Discord([
    'token' => 'bot token',
    'cache' => $cache,
]);
Clone this wiki locally