diff -u b/core/lib/Drupal/Component/PhpStorage/FileReadOnlyStorage.php b/core/lib/Drupal/Component/PhpStorage/FileReadOnlyStorage.php --- b/core/lib/Drupal/Component/PhpStorage/FileReadOnlyStorage.php +++ b/core/lib/Drupal/Component/PhpStorage/FileReadOnlyStorage.php @@ -93,2 +93,20 @@ + /** + * {@inheritdoc} + */ + public function listAll() { + $names = array(); + if (file_exists($this->directory)) { + foreach (new \DirectoryIterator($this->directory) as $fileinfo) { + if (!$fileinfo->isDot()) { + $name = $fileinfo->getFilename(); + if ($name != '.htaccess') { + $names[] = $name; + } + } + } + } + return $names; + } + } diff -u b/core/lib/Drupal/Component/PhpStorage/FileStorage.php b/core/lib/Drupal/Component/PhpStorage/FileStorage.php --- b/core/lib/Drupal/Component/PhpStorage/FileStorage.php +++ b/core/lib/Drupal/Component/PhpStorage/FileStorage.php @@ -191,13 +191,6 @@ } /** - * {@inheritdoc} - */ - public function getPath($name) { - return $this->getFullPath($name); - } - - /** * Implements Drupal\Component\PhpStorage\PhpStorageInterface::writeable(). */ public function writeable() { @@ -209,6 +202,13 @@ } /** + * {@inheritdoc} + */ + public function getPath($name) { + return $this->getFullPath($name); + } + + /** * Implements Drupal\Component\PhpStorage\PhpStorageInterface::writeable(). */ public function writeable() { @@ -257,2 +257,21 @@ } + + /** + * {@inheritdoc} + */ + public function listAll() { + $names = array(); + if (file_exists($this->directory)) { + foreach (new \DirectoryIterator($this->directory) as $fileinfo) { + if (!$fileinfo->isDot()) { + $name = $fileinfo->getFilename(); + if ($name != '.htaccess') { + $names[] = $name; + } + } + } + } + return $names; + } + } diff -u b/core/lib/Drupal/Component/PhpStorage/PhpStorageInterface.php b/core/lib/Drupal/Component/PhpStorage/PhpStorageInterface.php --- b/core/lib/Drupal/Component/PhpStorage/PhpStorageInterface.php +++ b/core/lib/Drupal/Component/PhpStorage/PhpStorageInterface.php @@ -93,2 +93,10 @@ + /** + * Lists all the files in the storage. + * + * @return array + * Array of filenames. + */ + public function listAll(); + } diff -u b/core/lib/Drupal/Core/Cache/PhpBackend.php b/core/lib/Drupal/Core/Cache/PhpBackend.php --- b/core/lib/Drupal/Core/Cache/PhpBackend.php +++ b/core/lib/Drupal/Core/Cache/PhpBackend.php @@ -38,16 +38,19 @@ */ public function __construct($bin) { $this->bin = $bin; - $this->loadCache(); } /** * {@inheritdoc} */ public function get($cid, $allow_invalid = FALSE) { - $cids = array($cid); - $cache = $this->getMultiple($cids, $allow_invalid); - return reset($cache); + if ($file = $this->storage()->getPath($cid)) { + $cache = @include $file; + } + if (isset($cache)) { + return $this->prepareItem((object) $cache, $allow_invalid); + } + return FALSE; } /** @@ -56,11 +59,8 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) { $ret = array(); - $items = array_intersect_key($this->cache, array_flip($cids)); - - foreach ($items as $item) { - $item = $this->prepareItem($item, $allow_invalid); - if ($item) { + foreach ($cids as $cid) { + if ($item = $this->get($cid, $allow_invalid)) { $ret[$item->cid] = $item; } } @@ -102,65 +102,67 @@ * {@inheritdoc} */ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array()) { - $this->cache[$cid] = (object) array( + if (is_object($data) && !method_exists($data, '__set_state')) { + throw new \InvalidArgumentException( + "Invalid argument given, PhpBackend only allows objects that implement __set_state() " . + "and fully support var_export(). You can use the PhpBackend to save arbitrary object " . + "graphs using serialize()/unserialize()." + ); + } + $item = array( 'cid' => $cid, 'data' => $data, 'created' => REQUEST_TIME, 'expire' => $expire, 'tags' => $this->flattenTags($tags), ); - $this->writeCache(); + $this->writeItem($cid, $item); } /** * {@inheritdoc} */ public function delete($cid) { - unset($this->cache[$cid]); - $this->writeCache(); + $this->storage()->delete($cid); } /** * {@inheritdoc} */ public function deleteMultiple(array $cids) { - $this->cache = array_diff_key($this->cache, array_flip($cids)); - $this->writeCache(); + foreach ($cids as $cid) { + $this->delete($cid); + } } /** * {@inheritdoc} */ public function deleteTags(array $tags) { - $this->cache = array(); - $this->writeCache(); - return; - $flat_tags = $this->flattenTags($tags); - foreach ($this->cache as $cid => $item) { + foreach ($this->storage()->listAll() as $cid) { + $item = $this->get($cid); if (array_intersect($flat_tags, $item->tags)) { - unset($this->cache[$cid]); + $this->delete($cid); } } - $this->writeCache(); } /** * {@inheritdoc} */ public function deleteAll() { - $this->cache = array(); - $this->writeCache(); + $this->storage()->deleteAll(); } /** * {@inheritdoc} */ public function invalidate($cid) { - if (isset($this->cache[$cid])) { - $this->cache[$cid]->expire = REQUEST_TIME - 1; + if ($item = $this->get($cid)) { + $item->expire = REQUEST_TIME - 1; + $this->writeItem($cid, (array) $item); } - $this->writeCache(); } /** @@ -168,40 +170,28 @@ */ public function invalidateMultiple(array $cids) { foreach ($cids as $cid) { - $this->cache[$cid]->expire = REQUEST_TIME - 1; + $this->invalidate($cid); } - $this->writeCache(); } /** * {@inheritdoc} */ public function invalidateTags(array $tags) { - $this->cache = array(); - $this->writeCache(); - return; - - $change = FALSE; $flat_tags = $this->flattenTags($tags); - foreach ($this->cache as $cid => $item) { - if (array_intersect($flat_tags, $item->tags)) { - $this->cache[$cid]->expire = REQUEST_TIME - 1; - $change = TRUE; + foreach ($this->storage()->listAll() as $cid) { + $item = $this->get($cid); + if ($item && array_intersect($flat_tags, $item->tags)) { + $this->invalidate($cid); } } - if ($change) { - $this->writeCache(); - } } /** * {@inheritdoc} */ public function invalidateAll() { - foreach ($this->cache as $cid => $item) { - $this->cache[$cid]->expire = REQUEST_TIME - 1; - } - $this->writeCache(); + $this->invalidateMultiple($this->storage()->listAll()); } /** @@ -236,7 +226,8 @@ * {@inheritdoc} */ public function isEmpty() { - return empty($this->cache); + $names = $this->storage()->listAll(); + return empty($names); } /** @@ -254,36 +245,21 @@ } /** - * Writes the cache to PHP storage. + * Writes a cache item to PhpStorage. + * + * @param string $cid + * The cache ID of the data to store. + * @param array $item + * The cache item to store. */ - protected function writeCache() { + protected function writeItem($cid, array $item) { $storage = $this->storage(); - $data = Variable::export($this->cache); + $data = var_export($item, TRUE); $content =<<save($this->bin, $content); - } - - /** - * Loads the cache from PHP storage. - */ - protected function loadCache() { - $storage = $this->storage(); - - // Whether or not Drupal\Component\PhpStorage\PhpStorageInterface::getPath() - // checks for the existence of the file is an implementation of the storage. - if ($filename = $storage->getPath($this->bin)) { - // If this file exists it'll set a variable called $cache. - @include_once $filename; - } - if (isset($cache)) { - $this->cache = $cache; - } - else { - $this->cache = array(); - } + $storage->save($cid, $content); } /** @@ -293,7 +269,13 @@ */ protected function storage() { if (!isset($this->storage)) { - $this->storage = PhpStorageFactory::get('cache'); + if ($this->bin != 'cache') { + $store = 'cache_' . $this->bin; + } + else { + $store = 'cache'; + } + $this->storage = PhpStorageFactory::get($store); } return $this->storage; } only in patch2: unchanged: --- a/core/lib/Drupal/Component/PhpStorage/MTimeProtectedFastFileStorage.php +++ b/core/lib/Drupal/Component/PhpStorage/MTimeProtectedFastFileStorage.php @@ -149,6 +149,17 @@ protected function getFullPath($name, &$directory = NULL, &$directory_mtime = NU } /** + * {@inheritdoc} + */ + public function delete($name) { + $path = $this->getContainingDirectoryFullPath($name); + if (file_exists($path)) { + return $this->unlink($path); + } + return FALSE; + } + + /** * Returns the full path of the containing directory where the file is or should be stored. */ protected function getContainingDirectoryFullPath($name) {