/framework/vendor/zend/Zend/Cache/Core.php
PHP | 756 lines | 385 code | 51 blank | 320 comment | 86 complexity | 39e088433166ffde15f548e495276cd5 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1
1<?php 2/** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to license@zend.com so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Cache 17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 18 * @license http://framework.zend.com/license/new-bsd New BSD License 19 * @version $Id: Core.php 21293 2010-03-02 10:26:32Z mabe $ 20 */ 21 22 23/** 24 * @package Zend_Cache 25 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 26 * @license http://framework.zend.com/license/new-bsd New BSD License 27 */ 28class Zend_Cache_Core 29{ 30 /** 31 * Messages 32 */ 33 const BACKEND_NOT_SUPPORTS_TAG = 'tags are not supported by the current backend'; 34 const BACKEND_NOT_IMPLEMENTS_EXTENDED_IF = 'Current backend doesn\'t implement the Zend_Cache_Backend_ExtendedInterface, so this method is not available'; 35 36 /** 37 * Backend Object 38 * 39 * @var object $_backend 40 */ 41 protected $_backend = null; 42 43 /** 44 * Available options 45 * 46 * ====> (boolean) write_control : 47 * - Enable / disable write control (the cache is read just after writing to detect corrupt entries) 48 * - Enable write control will lightly slow the cache writing but not the cache reading 49 * Write control can detect some corrupt cache files but maybe it's not a perfect control 50 * 51 * ====> (boolean) caching : 52 * - Enable / disable caching 53 * (can be very useful for the debug of cached scripts) 54 * 55 * =====> (string) cache_id_prefix : 56 * - prefix for cache ids (namespace) 57 * 58 * ====> (boolean) automatic_serialization : 59 * - Enable / disable automatic serialization 60 * - It can be used to save directly datas which aren't strings (but it's slower) 61 * 62 * ====> (int) automatic_cleaning_factor : 63 * - Disable / Tune the automatic cleaning process 64 * - The automatic cleaning process destroy too old (for the given life time) 65 * cache files when a new cache file is written : 66 * 0 => no automatic cache cleaning 67 * 1 => systematic cache cleaning 68 * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write 69 * 70 * ====> (int) lifetime : 71 * - Cache lifetime (in seconds) 72 * - If null, the cache is valid forever. 73 * 74 * ====> (boolean) logging : 75 * - If set to true, logging is activated (but the system is slower) 76 * 77 * ====> (boolean) ignore_user_abort 78 * - If set to true, the core will set the ignore_user_abort PHP flag inside the 79 * save() method to avoid cache corruptions in some cases (default false) 80 * 81 * @var array $_options available options 82 */ 83 protected $_options = array( 84 'write_control' => true, 85 'caching' => true, 86 'cache_id_prefix' => null, 87 'automatic_serialization' => false, 88 'automatic_cleaning_factor' => 10, 89 'lifetime' => 3600, 90 'logging' => false, 91 'logger' => null, 92 'ignore_user_abort' => false 93 ); 94 95 /** 96 * Array of options which have to be transfered to backend 97 * 98 * @var array $_directivesList 99 */ 100 protected static $_directivesList = array('lifetime', 'logging', 'logger'); 101 102 /** 103 * Not used for the core, just a sort a hint to get a common setOption() method (for the core and for frontends) 104 * 105 * @var array $_specificOptions 106 */ 107 protected $_specificOptions = array(); 108 109 /** 110 * Last used cache id 111 * 112 * @var string $_lastId 113 */ 114 private $_lastId = null; 115 116 /** 117 * True if the backend implements Zend_Cache_Backend_ExtendedInterface 118 * 119 * @var boolean $_extendedBackend 120 */ 121 protected $_extendedBackend = false; 122 123 /** 124 * Array of capabilities of the backend (only if it implements Zend_Cache_Backend_ExtendedInterface) 125 * 126 * @var array 127 */ 128 protected $_backendCapabilities = array(); 129 130 /** 131 * Constructor 132 * 133 * @param array|Zend_Config $options Associative array of options or Zend_Config instance 134 * @throws Zend_Cache_Exception 135 * @return void 136 */ 137 public function __construct($options = array()) 138 { 139 if ($options instanceof Zend_Config) { 140 $options = $options->toArray(); 141 } 142 if (!is_array($options)) { 143 Zend_Cache::throwException("Options passed were not an array" 144 . " or Zend_Config instance."); 145 } 146 while (list($name, $value) = each($options)) { 147 $this->setOption($name, $value); 148 } 149 $this->_loggerSanity(); 150 } 151 152 /** 153 * Set options using an instance of type Zend_Config 154 * 155 * @param Zend_Config $config 156 * @return Zend_Cache_Core 157 */ 158 public function setConfig(Zend_Config $config) 159 { 160 $options = $config->toArray(); 161 while (list($name, $value) = each($options)) { 162 $this->setOption($name, $value); 163 } 164 return $this; 165 } 166 167 /** 168 * Set the backend 169 * 170 * @param object $backendObject 171 * @throws Zend_Cache_Exception 172 * @return void 173 */ 174 public function setBackend(Zend_Cache_Backend $backendObject) 175 { 176 $this->_backend= $backendObject; 177 // some options (listed in $_directivesList) have to be given 178 // to the backend too (even if they are not "backend specific") 179 $directives = array(); 180 foreach (Zend_Cache_Core::$_directivesList as $directive) { 181 $directives[$directive] = $this->_options[$directive]; 182 } 183 $this->_backend->setDirectives($directives); 184 if (in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_backend))) { 185 $this->_extendedBackend = true; 186 $this->_backendCapabilities = $this->_backend->getCapabilities(); 187 } 188 189 } 190 191 /** 192 * Returns the backend 193 * 194 * @return object backend object 195 */ 196 public function getBackend() 197 { 198 return $this->_backend; 199 } 200 201 /** 202 * Public frontend to set an option 203 * 204 * There is an additional validation (relatively to the protected _setOption method) 205 * 206 * @param string $name Name of the option 207 * @param mixed $value Value of the option 208 * @throws Zend_Cache_Exception 209 * @return void 210 */ 211 public function setOption($name, $value) 212 { 213 if (!is_string($name)) { 214 Zend_Cache::throwException("Incorrect option name : $name"); 215 } 216 $name = strtolower($name); 217 if (array_key_exists($name, $this->_options)) { 218 // This is a Core option 219 $this->_setOption($name, $value); 220 return; 221 } 222 if (array_key_exists($name, $this->_specificOptions)) { 223 // This a specic option of this frontend 224 $this->_specificOptions[$name] = $value; 225 return; 226 } 227 } 228 229 /** 230 * Public frontend to get an option value 231 * 232 * @param string $name Name of the option 233 * @throws Zend_Cache_Exception 234 * @return mixed option value 235 */ 236 public function getOption($name) 237 { 238 if (is_string($name)) { 239 $name = strtolower($name); 240 if (array_key_exists($name, $this->_options)) { 241 // This is a Core option 242 return $this->_options[$name]; 243 } 244 if (array_key_exists($name, $this->_specificOptions)) { 245 // This a specic option of this frontend 246 return $this->_specificOptions[$name]; 247 } 248 } 249 Zend_Cache::throwException("Incorrect option name : $name"); 250 } 251 252 /** 253 * Set an option 254 * 255 * @param string $name Name of the option 256 * @param mixed $value Value of the option 257 * @throws Zend_Cache_Exception 258 * @return void 259 */ 260 private function _setOption($name, $value) 261 { 262 if (!is_string($name) || !array_key_exists($name, $this->_options)) { 263 Zend_Cache::throwException("Incorrect option name : $name"); 264 } 265 if ($name == 'lifetime' && empty($value)) { 266 $value = null; 267 } 268 $this->_options[$name] = $value; 269 } 270 271 /** 272 * Force a new lifetime 273 * 274 * The new value is set for the core/frontend but for the backend too (directive) 275 * 276 * @param int $newLifetime New lifetime (in seconds) 277 * @return void 278 */ 279 public function setLifetime($newLifetime) 280 { 281 $this->_options['lifetime'] = $newLifetime; 282 $this->_backend->setDirectives(array( 283 'lifetime' => $newLifetime 284 )); 285 } 286 287 /** 288 * Test if a cache is available for the given id and (if yes) return it (false else) 289 * 290 * @param string $id Cache id 291 * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested 292 * @param boolean $doNotUnserialize Do not serialize (even if automatic_serialization is true) => for internal use 293 * @return mixed|false Cached datas 294 */ 295 public function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false) 296 { 297 if (!$this->_options['caching']) { 298 return false; 299 } 300 $id = $this->_id($id); // cache id may need prefix 301 $this->_lastId = $id; 302 self::_validateIdOrTag($id); 303 $data = $this->_backend->load($id, $doNotTestCacheValidity); 304 if ($data===false) { 305 // no cache available 306 return false; 307 } 308 if ((!$doNotUnserialize) && $this->_options['automatic_serialization']) { 309 // we need to unserialize before sending the result 310 return unserialize($data); 311 } 312 return $data; 313 } 314 315 /** 316 * Test if a cache is available for the given id 317 * 318 * @param string $id Cache id 319 * @return int|false Last modified time of cache entry if it is available, false otherwise 320 */ 321 public function test($id) 322 { 323 if (!$this->_options['caching']) { 324 return false; 325 } 326 $id = $this->_id($id); // cache id may need prefix 327 self::_validateIdOrTag($id); 328 $this->_lastId = $id; 329 return $this->_backend->test($id); 330 } 331 332 /** 333 * Save some data in a cache 334 * 335 * @param mixed $data Data to put in cache (can be another type than string if automatic_serialization is on) 336 * @param string $id Cache id (if not set, the last cache id will be used) 337 * @param array $tags Cache tags 338 * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) 339 * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends 340 * @throws Zend_Cache_Exception 341 * @return boolean True if no problem 342 */ 343 public function save($data, $id = null, $tags = array(), $specificLifetime = false, $priority = 8) 344 { 345 if (!$this->_options['caching']) { 346 return true; 347 } 348 if ($id === null) { 349 $id = $this->_lastId; 350 } else { 351 $id = $this->_id($id); 352 } 353 self::_validateIdOrTag($id); 354 self::_validateTagsArray($tags); 355 if ($this->_options['automatic_serialization']) { 356 // we need to serialize datas before storing them 357 $data = serialize($data); 358 } else { 359 if (!is_string($data)) { 360 Zend_Cache::throwException("Datas must be string or set automatic_serialization = true"); 361 } 362 } 363 // automatic cleaning 364 if ($this->_options['automatic_cleaning_factor'] > 0) { 365 $rand = rand(1, $this->_options['automatic_cleaning_factor']); 366 if ($rand==1) { 367 if ($this->_extendedBackend) { 368 // New way 369 if ($this->_backendCapabilities['automatic_cleaning']) { 370 $this->clean(Zend_Cache::CLEANING_MODE_OLD); 371 } else { 372 $this->_log('Zend_Cache_Core::save() / automatic cleaning is not available/necessary with this backend'); 373 } 374 } else { 375 // Deprecated way (will be removed in next major version) 376 if (method_exists($this->_backend, 'isAutomaticCleaningAvailable') && ($this->_backend->isAutomaticCleaningAvailable())) { 377 $this->clean(Zend_Cache::CLEANING_MODE_OLD); 378 } else { 379 $this->_log('Zend_Cache_Core::save() / automatic cleaning is not available/necessary with this backend'); 380 } 381 } 382 } 383 } 384 if ($this->_options['ignore_user_abort']) { 385 $abort = ignore_user_abort(true); 386 } 387 if (($this->_extendedBackend) && ($this->_backendCapabilities['priority'])) { 388 $result = $this->_backend->save($data, $id, $tags, $specificLifetime, $priority); 389 } else { 390 $result = $this->_backend->save($data, $id, $tags, $specificLifetime); 391 } 392 if ($this->_options['ignore_user_abort']) { 393 ignore_user_abort($abort); 394 } 395 if (!$result) { 396 // maybe the cache is corrupted, so we remove it ! 397 if ($this->_options['logging']) { 398 $this->_log("Zend_Cache_Core::save() : impossible to save cache (id=$id)"); 399 } 400 $this->remove($id); 401 return false; 402 } 403 if ($this->_options['write_control']) { 404 $data2 = $this->_backend->load($id, true); 405 if ($data!=$data2) { 406 $this->_log('Zend_Cache_Core::save() / write_control : written and read data do not match'); 407 $this->_backend->remove($id); 408 return false; 409 } 410 } 411 return true; 412 } 413 414 /** 415 * Remove a cache 416 * 417 * @param string $id Cache id to remove 418 * @return boolean True if ok 419 */ 420 public function remove($id) 421 { 422 if (!$this->_options['caching']) { 423 return true; 424 } 425 $id = $this->_id($id); // cache id may need prefix 426 self::_validateIdOrTag($id); 427 return $this->_backend->remove($id); 428 } 429 430 /** 431 * Clean cache entries 432 * 433 * Available modes are : 434 * 'all' (default) => remove all cache entries ($tags is not used) 435 * 'old' => remove too old cache entries ($tags is not used) 436 * 'matchingTag' => remove cache entries matching all given tags 437 * ($tags can be an array of strings or a single string) 438 * 'notMatchingTag' => remove cache entries not matching one of the given tags 439 * ($tags can be an array of strings or a single string) 440 * 'matchingAnyTag' => remove cache entries matching any given tags 441 * ($tags can be an array of strings or a single string) 442 * 443 * @param string $mode 444 * @param array|string $tags 445 * @throws Zend_Cache_Exception 446 * @return boolean True if ok 447 */ 448 public function clean($mode = 'all', $tags = array()) 449 { 450 if (!$this->_options['caching']) { 451 return true; 452 } 453 if (!in_array($mode, array(Zend_Cache::CLEANING_MODE_ALL, 454 Zend_Cache::CLEANING_MODE_OLD, 455 Zend_Cache::CLEANING_MODE_MATCHING_TAG, 456 Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG, 457 Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG))) { 458 Zend_Cache::throwException('Invalid cleaning mode'); 459 } 460 self::_validateTagsArray($tags); 461 return $this->_backend->clean($mode, $tags); 462 } 463 464 /** 465 * Return an array of stored cache ids which match given tags 466 * 467 * In case of multiple tags, a logical AND is made between tags 468 * 469 * @param array $tags array of tags 470 * @return array array of matching cache ids (string) 471 */ 472 public function getIdsMatchingTags($tags = array()) 473 { 474 if (!$this->_extendedBackend) { 475 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 476 } 477 if (!($this->_backendCapabilities['tags'])) { 478 Zend_Cache::throwException(self::BACKEND_NOT_SUPPORT_TAG); 479 } 480 481 $ids = $this->_backend->getIdsMatchingTags($tags); 482 483 // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) 484 if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { 485 $prefix = & $this->_options['cache_id_prefix']; 486 $prefixLen = strlen($prefix); 487 foreach ($ids as &$id) { 488 if (strpos($id, $prefix) === 0) { 489 $id = substr($id, $prefixLen); 490 } 491 } 492 } 493 494 return $ids; 495 } 496 497 /** 498 * Return an array of stored cache ids which don't match given tags 499 * 500 * In case of multiple tags, a logical OR is made between tags 501 * 502 * @param array $tags array of tags 503 * @return array array of not matching cache ids (string) 504 */ 505 public function getIdsNotMatchingTags($tags = array()) 506 { 507 if (!$this->_extendedBackend) { 508 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 509 } 510 if (!($this->_backendCapabilities['tags'])) { 511 Zend_Cache::throwException(self::BACKEND_NOT_SUPPORT_TAG); 512 } 513 514 $ids = $this->_backend->getIdsNotMatchingTags($tags); 515 516 // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) 517 if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { 518 $prefix = & $this->_options['cache_id_prefix']; 519 $prefixLen = strlen($prefix); 520 foreach ($ids as &$id) { 521 if (strpos($id, $prefix) === 0) { 522 $id = substr($id, $prefixLen); 523 } 524 } 525 } 526 527 return $ids; 528 } 529 530 /** 531 * Return an array of stored cache ids which match any given tags 532 * 533 * In case of multiple tags, a logical OR is made between tags 534 * 535 * @param array $tags array of tags 536 * @return array array of matching any cache ids (string) 537 */ 538 public function getIdsMatchingAnyTags($tags = array()) 539 { 540 if (!$this->_extendedBackend) { 541 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 542 } 543 if (!($this->_backendCapabilities['tags'])) { 544 Zend_Cache::throwException(self::BACKEND_NOT_SUPPORT_TAG); 545 } 546 547 $ids = $this->_backend->getIdsMatchingAnyTags($tags); 548 549 // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) 550 if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { 551 $prefix = & $this->_options['cache_id_prefix']; 552 $prefixLen = strlen($prefix); 553 foreach ($ids as &$id) { 554 if (strpos($id, $prefix) === 0) { 555 $id = substr($id, $prefixLen); 556 } 557 } 558 } 559 560 return $ids; 561 } 562 563 /** 564 * Return an array of stored cache ids 565 * 566 * @return array array of stored cache ids (string) 567 */ 568 public function getIds() 569 { 570 if (!$this->_extendedBackend) { 571 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 572 } 573 574 $ids = $this->_backend->getIds(); 575 576 // we need to remove cache_id_prefix from ids (see #ZF-6178, #ZF-7600) 577 if (isset($this->_options['cache_id_prefix']) && $this->_options['cache_id_prefix'] !== '') { 578 $prefix = & $this->_options['cache_id_prefix']; 579 $prefixLen = strlen($prefix); 580 foreach ($ids as &$id) { 581 if (strpos($id, $prefix) === 0) { 582 $id = substr($id, $prefixLen); 583 } 584 } 585 } 586 587 return $ids; 588 } 589 590 /** 591 * Return an array of stored tags 592 * 593 * @return array array of stored tags (string) 594 */ 595 public function getTags() 596 { 597 if (!$this->_extendedBackend) { 598 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 599 } 600 if (!($this->_backendCapabilities['tags'])) { 601 Zend_Cache::throwException(self::BACKEND_NOT_SUPPORT_TAG); 602 } 603 return $this->_backend->getTags(); 604 } 605 606 /** 607 * Return the filling percentage of the backend storage 608 * 609 * @return int integer between 0 and 100 610 */ 611 public function getFillingPercentage() 612 { 613 if (!$this->_extendedBackend) { 614 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 615 } 616 return $this->_backend->getFillingPercentage(); 617 } 618 619 /** 620 * Return an array of metadatas for the given cache id 621 * 622 * The array will include these keys : 623 * - expire : the expire timestamp 624 * - tags : a string array of tags 625 * - mtime : timestamp of last modification time 626 * 627 * @param string $id cache id 628 * @return array array of metadatas (false if the cache id is not found) 629 */ 630 public function getMetadatas($id) 631 { 632 if (!$this->_extendedBackend) { 633 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 634 } 635 $id = $this->_id($id); // cache id may need prefix 636 return $this->_backend->getMetadatas($id); 637 } 638 639 /** 640 * Give (if possible) an extra lifetime to the given cache id 641 * 642 * @param string $id cache id 643 * @param int $extraLifetime 644 * @return boolean true if ok 645 */ 646 public function touch($id, $extraLifetime) 647 { 648 if (!$this->_extendedBackend) { 649 Zend_Cache::throwException(self::BACKEND_NOT_IMPLEMENTS_EXTENDED_IF); 650 } 651 $id = $this->_id($id); // cache id may need prefix 652 return $this->_backend->touch($id, $extraLifetime); 653 } 654 655 /** 656 * Validate a cache id or a tag (security, reliable filenames, reserved prefixes...) 657 * 658 * Throw an exception if a problem is found 659 * 660 * @param string $string Cache id or tag 661 * @throws Zend_Cache_Exception 662 * @return void 663 */ 664 protected static function _validateIdOrTag($string) 665 { 666 if (!is_string($string)) { 667 Zend_Cache::throwException('Invalid id or tag : must be a string'); 668 } 669 if (substr($string, 0, 9) == 'internal-') { 670 Zend_Cache::throwException('"internal-*" ids or tags are reserved'); 671 } 672 if (!preg_match('~^[a-zA-Z0-9_]+$~D', $string)) { 673 Zend_Cache::throwException("Invalid id or tag '$string' : must use only [a-zA-Z0-9_]"); 674 } 675 } 676 677 /** 678 * Validate a tags array (security, reliable filenames, reserved prefixes...) 679 * 680 * Throw an exception if a problem is found 681 * 682 * @param array $tags Array of tags 683 * @throws Zend_Cache_Exception 684 * @return void 685 */ 686 protected static function _validateTagsArray($tags) 687 { 688 if (!is_array($tags)) { 689 Zend_Cache::throwException('Invalid tags array : must be an array'); 690 } 691 foreach($tags as $tag) { 692 self::_validateIdOrTag($tag); 693 } 694 reset($tags); 695 } 696 697 /** 698 * Make sure if we enable logging that the Zend_Log class 699 * is available. 700 * Create a default log object if none is set. 701 * 702 * @throws Zend_Cache_Exception 703 * @return void 704 */ 705 protected function _loggerSanity() 706 { 707 if (!isset($this->_options['logging']) || !$this->_options['logging']) { 708 return; 709 } 710 711 if (isset($this->_options['logger']) && $this->_options['logger'] instanceof Zend_Log) { 712 return; 713 } 714 715 // Create a default logger to the standard output stream 716 require_once 'Zend/Log/Writer/Stream.php'; 717 $logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output')); 718 $this->_options['logger'] = $logger; 719 } 720 721 /** 722 * Log a message at the WARN (4) priority. 723 * 724 * @param string $message 725 * @throws Zend_Cache_Exception 726 * @return void 727 */ 728 protected function _log($message, $priority = 4) 729 { 730 if (!$this->_options['logging']) { 731 return; 732 } 733 if (!(isset($this->_options['logger']) || $this->_options['logger'] instanceof Zend_Log)) { 734 Zend_Cache::throwException('Logging is enabled but logger is not set'); 735 } 736 $logger = $this->_options['logger']; 737 $logger->log($message, $priority); 738 } 739 740 /** 741 * Make and return a cache id 742 * 743 * Checks 'cache_id_prefix' and returns new id with prefix or simply the id if null 744 * 745 * @param string $id Cache id 746 * @return string Cache id (with or without prefix) 747 */ 748 protected function _id($id) 749 { 750 if (($id !== null) && isset($this->_options['cache_id_prefix'])) { 751 return $this->_options['cache_id_prefix'] . $id; // return with prefix 752 } 753 return $id; // no prefix, just return the $id passed 754 } 755 756}