PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, November 13, 2022

[FIXED] How to delete items with same prefix key in memcached using PHP memcache extension?

 November 13, 2022     memcached, php     No comments   

Issue

Very similar questions have been posted and answered. However every solution I found so far is using php Memcached extension rather than Memcache. I am trying to delete/expire all memcache items that begin with a predefined key. For example, so_something, so_something_else .... Any help is much appreciated.


Solution

After some research I figured how to do it using standard Memcache commands. But, unfortunately this will man trips to the memcache server so it is to be used with care; in my case it is used only after deployment:

/**
 * Helper function to expire memcache entries with a specific key prefix.
 *
 * @param string $key_prefix
 *  The memcache key prefix.
 * @param array $servers
 *  Array of used memcache servers.
 * @return array
 *
 */
function memcache_delete_by_key($key_prefix = '', $servers = array()) {
  $mc = new Memcache();
  $delete_keys = array();
  foreach ($servers as $server => $default) {
    list($host, $port) = explode(':', $server);
    $mc->addServer($host, $port);
    // Extract all the keys from Memcache.
    $stats = memcache_command($server, $port, "stats items");
    $stat_lines = explode("\r\n", $stats);
    $slabs = array();
    $keys = array();
    foreach ($stat_lines as $line) {
      if (preg_match("/STAT items:([\d]+):number ([\d]+)/", $line, $matches)) {
        if (isset($matches[1]) && !in_array($matches[1], $slabs)) {
          $slabs[] = $matches[1];
          $string = memcache_command($server, $port, "stats cachedump " . $matches[1] . " " . $matches[2]);
          preg_match_all("/ITEM (.*?) /", $string, $matches);
          $keys[] = $matches[1];
        }
      }
    }
    $delete_keys = call_user_func_array('array_merge', $keys);
    // Locate all keys that begin with our prefix.
    foreach ($delete_keys as $index => $key) {
      // If strpos returns 0 (not false) then we have a match.
      if (strpos($key, $key_prefix) === 0) {
        $mc->delete($key);
      }
    }
  }

  return $delete_keys;
}

/*
 * Helper function to send memcache commands to a given Memcache Server
 */
function memcache_command($server, $port, $command) {
  $s = @fsockopen($server, $port);
  if (!$s) {
    return die("Cant connect to:" . $server . ":" . $port);
  }
  fwrite($s, $command . "\r\n");
  $buf = "";
  while ((!feof($s))) {
    $buf .= fgets($s, 256);
    // Stat says 'END'.
    if (strpos($buf, "END\r\n") !== FALSE) {
      break;
    }
    // Delete says DELETED or NOT_FOUND.
    if (strpos($buf, "DELETED\r\n") !== FALSE || strpos($buf, "NOT_FOUND\r\n") !== FALSE) {
      break;
    }
    // Flush_all says ok.
    if (strpos($buf, "OK\r\n") !== FALSE) {
      break;
    }
  }
  fclose($s);
  return ($buf);
}


Answered By - awm
Answer Checked By - Terry (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing