public function clear($prefix = '') { $prefix = $this->getNamespace() . $prefix; $allKeys = self::$cache->getAllKeys(); $keys = array(); $prefixLength = strlen($prefix); foreach ($allKeys as $key) { if (substr($key, 0, $prefixLength) === $prefix) { $keys[] = $key; } } self::$cache->deleteMulti($keys); return true; }
/** * {@inheritdoc} */ public function deleteMulti(array $keys) { if (!method_exists($this->client, 'deleteMulti')) { /* * HHVM doesn't support deleteMulti, so I'll hack around it by * setting all items expired. * I could also delete() all items, but that would probably take * more network requests (this version always takes 2) * * @see http://docs.hhvm.com/manual/en/memcached.deletemulti.php */ $values = $this->getMulti($keys); $this->client->setMulti(array_fill_keys(array_keys($values), ''), time() - 1); $return = array(); foreach ($keys as $key) { $return[$key] = array_key_exists($key, $values); } return $return; } $result = (array) $this->client->deleteMulti($keys); /* * Contrary to docs (http://php.net/manual/en/memcached.deletemulti.php) * deleteMulti returns an array of [key => true] (for successfully * deleted values) and [key => error code] (for failures) * Pretty good because I want an array of true/false, so I'll just have * to replace the error codes by falses. */ foreach ($result as $key => $status) { $result[$key] = $status === true; } return $result; }
/** * Purges the cache deleting all items within it. * * @return boolean True on success. False otherwise. */ public function purge() { if ($this->isready) { // Only use delete multi if we have the correct extension installed and if the memcached // server is shared (flushing the cache is quicker otherwise). $candeletemulti = $this->candeletemulti && $this->isshared; if ($this->clustered) { foreach ($this->setconnections as $connection) { if ($candeletemulti) { $keys = self::get_prefixed_keys($connection, $this->prefix); $connection->deleteMulti($keys); } else { // Oh damn, this isn't multi-site safe. $connection->flush(); } } } else { if ($candeletemulti) { $keys = self::get_prefixed_keys($this->connection, $this->prefix); $this->connection->deleteMulti($keys); } else { // Oh damn, this isn't multi-site safe. $this->connection->flush(); } } } // It never fails. Ever. return true; }
public function clear($prefix = '') { $prefix = $this->getNamespace() . $prefix; $allKeys = self::$cache->getAllKeys(); if ($allKeys === false) { // newer Memcached doesn't like getAllKeys(), flush everything self::$cache->flush(); return true; } $keys = array(); $prefixLength = strlen($prefix); foreach ($allKeys as $key) { if (substr($key, 0, $prefixLength) === $prefix) { $keys[] = $key; } } if (method_exists(self::$cache, 'deleteMulti')) { self::$cache->deleteMulti($keys); } else { foreach ($keys as $key) { self::$cache->delete($key); } } return true; }
/** * {@inheritdoc} */ public function flush() : StorageInterface { if ($keys = $this->memcached->get($this->prefix)) { $this->memcached->delete($this->prefix); $this->memcached->deleteMulti(explode('|', $keys)); } return $this; }
/** * Removes multiple items from Memcached. * If using memcached, this method requires php5-memcached package version >=2.0! * * @param array $keys of items to be removed * * @return bool true on success, also if memcached has been disabled */ public function deleteMulti(array $keys) { $keys2 = array(); foreach ($keys as $key) { $keys2[] = md5($this->uniqId . '_' . $key); } return $this->memcached->deleteMulti($keys2); }
/** * Removes multiple items from Memcached. * * @param string[] $keys of items to be removed * * @return bool true on success */ public function deleteMulti(array $keys) { if ($this->hasMultiDelete) { return $this->memcached->deleteMulti($keys); } foreach ($keys as $key) { $this->deleteItem($key); } return true; }
/** * @inheritdoc */ public function removeTag($tag) { $tag = $this->prepareTag($tag); if (!($value = $this->storage->get($tag))) { return false; } $value = $this->unserialize($value); $value[] = $tag; $this->storage->deleteMulti($value); return true; }
/** * Delete many keys from the cache at once * * @param array $keys An array of identifiers for the data * @return array of boolean values that are true if the key was successfully * deleted, false if it didn't exist or couldn't be removed. */ public function deleteMany($keys) { $cacheKeys = []; foreach ($keys as $key) { $cacheKeys[] = $this->_key($key); } $success = $this->_Memcached->deleteMulti($cacheKeys); $return = []; foreach ($keys as $key) { $return[$key] = $success; } return $return; }
/** * Internal method to remove multiple items. * * @param array $normalizedKeys * @return array Array of not removed keys * @throws Exception\ExceptionInterface */ protected function internalRemoveItems(array &$normalizedKeys) { // support for removing multiple items at once has been added in ext/memcached-2.0.0 if (static::$extMemcachedMajorVersion < 2) { return parent::internalRemoveItems($normalizedKeys); } $rsCodes = $this->memcached->deleteMulti($normalizedKeys); $missingKeys = array(); foreach ($rsCodes as $key => $rsCode) { if ($rsCode !== true && $rsCode != MemcachedResource::RES_SUCCESS) { if ($rsCode != MemcachedResource::RES_NOTFOUND) { throw $this->getExceptionByResultCode($rsCode); } $missingKeys[] = $key; } } return $missingKeys; }
/** * Internal method to remove multiple items. * * Options: * - namespace <string> * - The namespace to use * - ignore_missing_items <boolean> * - Throw exception on missing item * * @param array $keys * @param array $options * @return boolean * @throws Exception\ExceptionInterface */ protected function internalRemoveItems(array &$normalizedKeys, array &$normalizedOptions) { // support for removing multiple items at once has been added in ext/memcached-2.0.0 if (static::$extMemcachedMajorVersion < 2) { return parent::internalRemoveItems($normalizedKeys, $normalizedOptions); } $this->memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $normalizedOptions['namespace']); $rsCodes = $this->memcached->deleteMulti($normalizedKeys); $missingKeys = null; foreach ($rsCodes as $key => $rsCode) { if ($rsCode !== true && $rsCode != 0) { if ($rsCode != MemcachedResource::RES_NOTFOUND) { throw $this->getExceptionByResultCode($rsCode); } $missingKeys[] = $key; } } if ($missingKeys && !$normalizedOptions['ignore_missing_items']) { throw new Exception\ItemNotFoundException("Keys '" . implode("','", $missingKeys) . "' not found within namespace '{$normalizedOptions['namespace']}'"); } return true; }
/** * Remove items. * * Options: * - namespace <string> optional * - The namespace to use (Default: namespace of object) * * @param array $keys * @param array $options * @return boolean * @throws Exception * * @triggers removeItems.pre(PreEvent) * @triggers removeItems.post(PostEvent) * @triggers removeItems.exception(ExceptionEvent) */ public function removeItems(array $keys, array $options = array()) { $baseOptions = $this->getOptions(); if (!$baseOptions->getWritable()) { return false; } $this->normalizeOptions($options); $args = new ArrayObject(array('keys' => &$keys, 'options' => &$options)); try { $this->memcached->setOption(MemcachedResource::OPT_PREFIX_KEY, $options['namespace']); $rsCodes = array(); if (static::$extMemcachedMajorVersion >= 2) { $rsCodes = $this->memcached->deleteMulti($keys); } else { foreach ($keys as $key) { $rs = $this->memcached->delete($key); if ($rs === false) { $rsCodes[$key] = $this->memcached->getResultCode(); } } } $missingKeys = null; foreach ($rsCodes as $key => $rsCode) { if ($rsCode !== true && $rsCode != 0) { if ($rsCode != MemcachedResource::RES_NOTFOUND) { throw $this->getExceptionByResultCode($rsCode); } elseif (!$options['ignore_missing_items']) { $missingKeys[] = $key; } } } if ($missingKeys) { throw new Exception\ItemNotFoundException("Keys '" . implode("','", $missingKeys) . "' not found"); } return true; } catch (MemcachedException $e) { throw new RuntimeException($e->getMessage(), 0, $e); } }
/** * Reads from cache in bulk. * @param string key * @return array key => value pairs, missing items are omitted */ public function bulkRead(array $keys) { $prefixedKeys = array_map(function ($key) { return urlencode($this->prefix . $key); }, $keys); $keys = array_combine($prefixedKeys, $keys); $metas = $this->memcached->getMulti($prefixedKeys); $result = []; $deleteKeys = []; foreach ($metas as $prefixedKey => $meta) { if (!empty($meta[self::META_CALLBACKS]) && !Cache::checkCallbacks($meta[self::META_CALLBACKS])) { $deleteKeys[] = $prefixedKey; } else { $result[$keys[$prefixedKey]] = $meta[self::META_DATA]; } if (!empty($meta[self::META_DELTA])) { $this->memcached->replace($prefixedKey, $meta, $meta[self::META_DELTA] + time()); } } if (!empty($deleteKeys)) { $this->memcached->deleteMulti($deleteKeys, 0); } return $result; }
/** * Delete of items for the set Key and throws exception if this is empty. * * @return bool * */ public function deleteAllForKey() { $keys = $this->getAllKeys(); return parent::deleteMulti($keys); }
/** * Clear an array of values from the cache. * * @param array $key An array of keys to clear */ public function mclear(array $keys = array()) { return $this->client->deleteMulti($keys); }
<?php $m = new Memcached(); $m->addServer('localhost', '11211'); function dump_types($v, $k) { echo gettype($v) . "\n"; } $keys = array(100, 'str'); array_walk($keys, 'dump_types'); $deleted = $m->deleteMulti($keys); array_walk($keys, 'dump_types');
private function writeBufferToGS($complete = false) { $headers = $this->getOAuthTokenHeader(parent::WRITE_SCOPE); if ($headers === false) { trigger_error("Unable to acquire OAuth token.", E_USER_ERROR); return false; } $buffer_len = strlen($this->byte_buffer); if ($complete) { $write_size = $buffer_len; } else { // Incomplete writes should never be less than WRITE_CHUNK_SIZE assert($buffer_len >= self::WRITE_CHUNK_SIZE); // Is PHP the only language in the world where the quotient of two // integers is a double? $write_size = floor($buffer_len / self::WRITE_CHUNK_SIZE) * self::WRITE_CHUNK_SIZE; } // Determine the final byte of the buffer we're writing for Range header. if ($write_size !== 0) { $write_end_byte = $this->buffer_start_offset + $write_size - 1; $body = substr($this->byte_buffer, 0, $write_size); } else { $body = null; } if ($complete) { $object_length = $this->buffer_start_offset + $write_size; if ($write_size === 0) { $headers['Content-Range'] = sprintf(parent::FINAL_CONTENT_RANGE_NO_DATA, $object_length); } else { $headers['Content-Range'] = sprintf(parent::FINAL_CONTENT_RANGE_FORMAT, $this->buffer_start_offset, $write_end_byte, $object_length); } } else { $headers['Content-Range'] = sprintf(parent::PARTIAL_CONTENT_RANGE_FORMAT, $this->buffer_start_offset, $write_end_byte); } $url = sprintf("%s?upload_id=%s", $this->url, $this->upload_id); $http_response = $this->makeHttpRequest($url, "PUT", $headers, $body); $code = $http_response['status_code']; // TODO: Retry on some status codes. if ($complete && $code != HttpResponse::OK || !$complete && $code != HttpResponse::RESUME_INCOMPLETE) { trigger_error($this->getErrorMessage($http_response['status_code'], $http_response['body']), E_USER_WARNING); return false; } // Buffer flushed, update pointers if we actually wrote something. if ($write_size !== 0) { $this->buffer_start_offset = $write_end_byte + 1; $this->byte_buffer = substr($this->byte_buffer, $write_size); } // Invalidate any cached object with the same name. Note that there is a // potential race condition when using optimistic caching and invalidate // on write where the old version of an object can still be returned from // the cache. if ($complete && $this->context_options['enable_cache'] === true) { if ($object_length > 0) { $key_names = []; for ($i = 0; $i < $object_length; $i += parent::DEFAULT_READ_SIZE) { $range = $this->getRangeHeader($i, $i + parent::DEFAULT_READ_SIZE - 1); $key_names[] = static::getReadMemcacheKey($this->url, $range['Range']); } $memcached = new \Memcached(); $memcached->deleteMulti($key_names); } } return true; }
/** * Tear down */ public function destruct() { $this->Memcached->deleteMulti($this->keys); }
/** * {@inheritDoc} * * @see http://php.net/manual/en/memcached.deleteMulti.php */ protected function _deleteMulti(array $keys) { return $this->_connection->deleteMulti($keys); }
return false; } if ($check_true && $array[$key] !== true) { return false; } } return true; } $data = array('foo' => 'foo-data', 'bar' => 'bar-data', 'baz' => 'baz-data', 'lol' => 'lol-data', 'kek' => 'kek-data'); $keys = array_keys($data); $null = null; $m->setMulti($data, 3600); /* Check that all keys were stored */ var_dump(has_all_keys($keys, $m->getMulti($keys))); /* Check that all keys get deleted */ $deleted = $m->deleteMulti($keys); var_dump(has_all_keys($keys, $deleted, true)); /* Try to get the deleted keys, should give empty array */ var_dump($m->getMulti($keys)); /* ---- same tests for byKey variants ---- */ $m->setMultiByKey("hi", $data, 3600); var_dump(has_all_keys($keys, $m->getMultiByKey('hi', $keys))); /* Check that all keys get deleted */ $deleted = $m->deleteMultiByKey('hi', $keys); var_dump(has_all_keys($keys, $deleted, true)); /* Try to get the deleted keys, should give empty array */ var_dump($m->getMultiByKey('hi', $keys)); /* Test deleting non-existent keys */ $keys = array(); $keys[] = "nothere"; $keys[] = "nothere2";