Dead simple memcached counter.
composer require dorantor/mcounter
NB! There are only abstract classes, because it's meant to be extended.
class MyCounter extends \Dorantor\AbstractCounter
{
/**
* Method for building cache key based on $item value
*
* @return string
*/
protected function getKey()
{
return 'myCounter' . (int) $this->item->id;
}
}
And in your code:
$client = new Memcached();
// .. client setup
//
// basically, $client creation is up to you.
// Most probably you already created one earlier, so just reuse it here.
$counter = new MyCounter($user, $client);
if ($counter->value() < 100) {
$counter->inc();
}
By default it's set to never expire. But if you need to use self expiring counter(flag?), you can set third parameter in the constructor:
$counter = new MyCounter($user, $client, 3600); // hour, in this case
or you can define expiry logic/value inside counter by overriding
getExpiry()
method, p.ex.:
protected function getExpiry()
{
return 3600; // also hour, but this way it's defined inside counter
// or it could be some logic based on value(s) in $this->item
}
NB! Expiry is not updated on inc() call. It's default Memcached
behaviour. If you need to update expiry use touch()
, p.ex.:
$counter->inc();
$counter->touch();
// or
$counter->incWithTouch();
Second option is more convenient but you loose control over touch()
success/fail.
In case you need to reset counter you have two options:
// this will delete counter, so it will be recreated
$counter->delete();
// this will get data from getInitialData() method
// and put it as current counter value
$counter->reload();
delete()
is more viable for cache reset cases, reload()
- for cases when you need to sync counter with current
values from your system if counter is used for caching purposes. For example, if your counter value is
select count(*) from tablename
.
Important note. You will have to use binary protocol in memcached. For example, it could be enabled this way:
$client->setOption(\Memcached::OPT_SERIALIZER, \Memcached::SERIALIZER_IGBINARY);
$client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
But you will also need a binary serializer installed, as you can see. Igbinary in my example.