سؤال

Let's assume I have these variables saved in apc, memcached and eaccelerator:

  • article_1_0
  • article_1_1
  • article_3_2
  • article_3_3
  • article_2_4

How can I delete all cached variables that starts with article_3_ (they can reach up to 10000) ?

is there any way to list the cached variables ?

هل كانت مفيدة؟

المحلول

The slow solution

For APC:

$iterator = new APCIterator('user', '#^article_3_#', APC_ITER_KEY);
foreach($iterator as $entry_name) {
    apc_delete($entry_name);
}

For eaccelerator:

foreach(eaccelerator_list_keys() as $name => $infos) {
    if (preg_match('#^article_3_#', $name)) {
        eaccelerator_rm($name);
    }
}

For memcached, look at @rik's answer

The proper solution

The general solution for expiring multiple keys at once is to namespace them. For expiring them, you just have to change the namespace:

Say you have a group of keys "article_3_1", "article_3_2", .... You can store them like this:

$ns = apc_fetch('article_3_namespace');
apc_store($ns."_article_3_1", $value);
apc_store($ns."_article_3_2", $value);

Fetch them like this:

$ns = apc_fetch('article_3_namespace');
apc_fetch($ns."_article_3_1");

And expire them all by just incrementing the namespace:

apc_inc('article_3_namespace');

نصائح أخرى

Although the docs say APCIterator is available in apc >= 3.1.1, I'm on several systems that claim to have apc 3.1.9, however there is no APCIterator present. If you don't have APCIterator at your disposal, give something like this a whirl:

$aCacheInfo = apc_cache_info('user');

foreach($aCacheInfo['cache_list'] as $_aCacheInfo)
    if(strpos($_aCacheInfo['info'], 'key_prefix:') === 0)
        apc_delete($_aCacheInfo['info']);

In this example we're checking for a prefix in the key, but you could use preg_match et. al and achieve something closer to what APCIterator provides.

There is a way to retrieve all keys from memcache but it's very expensive.

If there is possibility to use alternatives for memcached, scache supports structured keyspaces. With it you could store data to nested paths :

scache_shset($conn, 'article/1/0', $data10);
scache_shset($conn, 'article/3/0', $data30);
scache_shset($conn, 'article/3/1', $data31);

and eventually destroy data by deleting the parent node

scache_shunset($conn, 'article/3');

There is an APCIterator which helps you search through the keys in APC. Instantiate the APCIterator.

APCIterator::valid() means that there are keys still to iterate trough. APCIterator::key() returns you the apc key. APCIterator::next() moves the iterator position to the next item.

// APC
$iterator = new APCIterator('user', '/^article_3_/');

while($iterator->valid()) {
     apc_delete($iterator->key());
     // You can view the info for this APC cache value and so on by using 
     // $iterator->current() which is array
     $iterator->next();
}

For memcache you can use Memcached and use getAllKeys method

// Memcached 
$m = new Memcached();
$m->addServer('mem1.domain.com', 11211);

$items = $m->getAllKeys();

foreach($items as $item) {
    if(preg_match('#^article_3_#', $item)) {
        $m->delete($item);
    }
}  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top