106 * @since 2.0.0 |
109 * @since 2.0.0 |
107 * |
110 * |
108 * @see WP_Object_Cache::get() |
111 * @see WP_Object_Cache::get() |
109 * @global WP_Object_Cache $wp_object_cache Object cache global instance. |
112 * @global WP_Object_Cache $wp_object_cache Object cache global instance. |
110 * |
113 * |
111 * @param int|string $key The key under which the cache contents are stored. |
114 * @param int|string $key The key under which the cache contents are stored. |
112 * @param string $group Optional. Where the cache contents are grouped. Default empty. |
115 * @param string $group Optional. Where the cache contents are grouped. Default empty. |
113 * @param bool $force Optional. Whether to force an update of the local cache from the persistent |
116 * @param bool $force Optional. Whether to force an update of the local cache |
114 * cache. Default false. |
117 * from the persistent cache. Default false. |
115 * @param bool $found Optional. Whether the key was found in the cache (passed by reference). |
118 * @param bool $found Optional. Whether the key was found in the cache (passed by reference). |
116 * Disambiguates a return of false, a storable value. Default null. |
119 * Disambiguates a return of false, a storable value. Default null. |
117 * @return bool|mixed False on failure to retrieve contents or the cache |
120 * @return mixed|false The cache contents on success, false on failure to retrieve contents. |
118 * contents on success |
|
119 */ |
121 */ |
120 function wp_cache_get( $key, $group = '', $force = false, &$found = null ) { |
122 function wp_cache_get( $key, $group = '', $force = false, &$found = null ) { |
121 global $wp_object_cache; |
123 global $wp_object_cache; |
122 |
124 |
123 return $wp_object_cache->get( $key, $group, $force, $found ); |
125 return $wp_object_cache->get( $key, $group, $force, $found ); |
|
126 } |
|
127 |
|
128 /** |
|
129 * Retrieves multiple values from the cache in one call. |
|
130 * |
|
131 * @since 5.5.0 |
|
132 * |
|
133 * @see WP_Object_Cache::get_multiple() |
|
134 * @global WP_Object_Cache $wp_object_cache Object cache global instance. |
|
135 * |
|
136 * @param array $keys Array of keys under which the cache contents are stored. |
|
137 * @param string $group Optional. Where the cache contents are grouped. Default empty. |
|
138 * @param bool $force Optional. Whether to force an update of the local cache |
|
139 * from the persistent cache. Default false. |
|
140 * @return array Array of values organized into groups. |
|
141 */ |
|
142 function wp_cache_get_multiple( $keys, $group = '', $force = false ) { |
|
143 global $wp_object_cache; |
|
144 |
|
145 return $wp_object_cache->get_multiple( $keys, $group, $force ); |
124 } |
146 } |
125 |
147 |
126 /** |
148 /** |
127 * Increment numeric cache item's value |
149 * Increment numeric cache item's value |
128 * |
150 * |
268 |
290 |
269 global $wp_object_cache; |
291 global $wp_object_cache; |
270 |
292 |
271 $wp_object_cache->reset(); |
293 $wp_object_cache->reset(); |
272 } |
294 } |
273 |
|
274 /** |
|
275 * Core class that implements an object cache. |
|
276 * |
|
277 * The WordPress Object Cache is used to save on trips to the database. The |
|
278 * Object Cache stores all of the cache data to memory and makes the cache |
|
279 * contents available by using a key, which is used to name and later retrieve |
|
280 * the cache contents. |
|
281 * |
|
282 * The Object Cache can be replaced by other caching mechanisms by placing files |
|
283 * in the wp-content folder which is looked at in wp-settings. If that file |
|
284 * exists, then this file will not be included. |
|
285 * |
|
286 * @since 2.0.0 |
|
287 */ |
|
288 class WP_Object_Cache { |
|
289 |
|
290 /** |
|
291 * Holds the cached objects. |
|
292 * |
|
293 * @since 2.0.0 |
|
294 * @var array |
|
295 */ |
|
296 private $cache = array(); |
|
297 |
|
298 /** |
|
299 * The amount of times the cache data was already stored in the cache. |
|
300 * |
|
301 * @since 2.5.0 |
|
302 * @var int |
|
303 */ |
|
304 public $cache_hits = 0; |
|
305 |
|
306 /** |
|
307 * Amount of times the cache did not have the request in cache. |
|
308 * |
|
309 * @since 2.0.0 |
|
310 * @var int |
|
311 */ |
|
312 public $cache_misses = 0; |
|
313 |
|
314 /** |
|
315 * List of global cache groups. |
|
316 * |
|
317 * @since 3.0.0 |
|
318 * @var array |
|
319 */ |
|
320 protected $global_groups = array(); |
|
321 |
|
322 /** |
|
323 * The blog prefix to prepend to keys in non-global groups. |
|
324 * |
|
325 * @since 3.5.0 |
|
326 * @var string |
|
327 */ |
|
328 private $blog_prefix; |
|
329 |
|
330 /** |
|
331 * Holds the value of is_multisite(). |
|
332 * |
|
333 * @since 3.5.0 |
|
334 * @var bool |
|
335 */ |
|
336 private $multisite; |
|
337 |
|
338 /** |
|
339 * Makes private properties readable for backward compatibility. |
|
340 * |
|
341 * @since 4.0.0 |
|
342 * |
|
343 * @param string $name Property to get. |
|
344 * @return mixed Property. |
|
345 */ |
|
346 public function __get( $name ) { |
|
347 return $this->$name; |
|
348 } |
|
349 |
|
350 /** |
|
351 * Makes private properties settable for backward compatibility. |
|
352 * |
|
353 * @since 4.0.0 |
|
354 * |
|
355 * @param string $name Property to set. |
|
356 * @param mixed $value Property value. |
|
357 * @return mixed Newly-set property. |
|
358 */ |
|
359 public function __set( $name, $value ) { |
|
360 return $this->$name = $value; |
|
361 } |
|
362 |
|
363 /** |
|
364 * Makes private properties checkable for backward compatibility. |
|
365 * |
|
366 * @since 4.0.0 |
|
367 * |
|
368 * @param string $name Property to check if set. |
|
369 * @return bool Whether the property is set. |
|
370 */ |
|
371 public function __isset( $name ) { |
|
372 return isset( $this->$name ); |
|
373 } |
|
374 |
|
375 /** |
|
376 * Makes private properties un-settable for backward compatibility. |
|
377 * |
|
378 * @since 4.0.0 |
|
379 * |
|
380 * @param string $name Property to unset. |
|
381 */ |
|
382 public function __unset( $name ) { |
|
383 unset( $this->$name ); |
|
384 } |
|
385 |
|
386 /** |
|
387 * Adds data to the cache if it doesn't already exist. |
|
388 * |
|
389 * @since 2.0.0 |
|
390 * |
|
391 * @uses WP_Object_Cache::_exists() Checks to see if the cache already has data. |
|
392 * @uses WP_Object_Cache::set() Sets the data after the checking the cache |
|
393 * contents existence. |
|
394 * |
|
395 * @param int|string $key What to call the contents in the cache. |
|
396 * @param mixed $data The contents to store in the cache. |
|
397 * @param string $group Optional. Where to group the cache contents. Default 'default'. |
|
398 * @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration). |
|
399 * @return bool False if cache key and group already exist, true on success |
|
400 */ |
|
401 public function add( $key, $data, $group = 'default', $expire = 0 ) { |
|
402 if ( wp_suspend_cache_addition() ) { |
|
403 return false; |
|
404 } |
|
405 |
|
406 if ( empty( $group ) ) { |
|
407 $group = 'default'; |
|
408 } |
|
409 |
|
410 $id = $key; |
|
411 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { |
|
412 $id = $this->blog_prefix . $key; |
|
413 } |
|
414 |
|
415 if ( $this->_exists( $id, $group ) ) { |
|
416 return false; |
|
417 } |
|
418 |
|
419 return $this->set( $key, $data, $group, (int) $expire ); |
|
420 } |
|
421 |
|
422 /** |
|
423 * Sets the list of global cache groups. |
|
424 * |
|
425 * @since 3.0.0 |
|
426 * |
|
427 * @param array $groups List of groups that are global. |
|
428 */ |
|
429 public function add_global_groups( $groups ) { |
|
430 $groups = (array) $groups; |
|
431 |
|
432 $groups = array_fill_keys( $groups, true ); |
|
433 $this->global_groups = array_merge( $this->global_groups, $groups ); |
|
434 } |
|
435 |
|
436 /** |
|
437 * Decrements numeric cache item's value. |
|
438 * |
|
439 * @since 3.3.0 |
|
440 * |
|
441 * @param int|string $key The cache key to decrement. |
|
442 * @param int $offset Optional. The amount by which to decrement the item's value. Default 1. |
|
443 * @param string $group Optional. The group the key is in. Default 'default'. |
|
444 * @return false|int False on failure, the item's new value on success. |
|
445 */ |
|
446 public function decr( $key, $offset = 1, $group = 'default' ) { |
|
447 if ( empty( $group ) ) { |
|
448 $group = 'default'; |
|
449 } |
|
450 |
|
451 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { |
|
452 $key = $this->blog_prefix . $key; |
|
453 } |
|
454 |
|
455 if ( ! $this->_exists( $key, $group ) ) { |
|
456 return false; |
|
457 } |
|
458 |
|
459 if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) { |
|
460 $this->cache[ $group ][ $key ] = 0; |
|
461 } |
|
462 |
|
463 $offset = (int) $offset; |
|
464 |
|
465 $this->cache[ $group ][ $key ] -= $offset; |
|
466 |
|
467 if ( $this->cache[ $group ][ $key ] < 0 ) { |
|
468 $this->cache[ $group ][ $key ] = 0; |
|
469 } |
|
470 |
|
471 return $this->cache[ $group ][ $key ]; |
|
472 } |
|
473 |
|
474 /** |
|
475 * Removes the contents of the cache key in the group. |
|
476 * |
|
477 * If the cache key does not exist in the group, then nothing will happen. |
|
478 * |
|
479 * @since 2.0.0 |
|
480 * |
|
481 * @param int|string $key What the contents in the cache are called. |
|
482 * @param string $group Optional. Where the cache contents are grouped. Default 'default'. |
|
483 * @param bool $deprecated Optional. Unused. Default false. |
|
484 * @return bool False if the contents weren't deleted and true on success. |
|
485 */ |
|
486 public function delete( $key, $group = 'default', $deprecated = false ) { |
|
487 if ( empty( $group ) ) { |
|
488 $group = 'default'; |
|
489 } |
|
490 |
|
491 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { |
|
492 $key = $this->blog_prefix . $key; |
|
493 } |
|
494 |
|
495 if ( ! $this->_exists( $key, $group ) ) { |
|
496 return false; |
|
497 } |
|
498 |
|
499 unset( $this->cache[ $group ][ $key ] ); |
|
500 return true; |
|
501 } |
|
502 |
|
503 /** |
|
504 * Clears the object cache of all data. |
|
505 * |
|
506 * @since 2.0.0 |
|
507 * |
|
508 * @return true Always returns true. |
|
509 */ |
|
510 public function flush() { |
|
511 $this->cache = array(); |
|
512 |
|
513 return true; |
|
514 } |
|
515 |
|
516 /** |
|
517 * Retrieves the cache contents, if it exists. |
|
518 * |
|
519 * The contents will be first attempted to be retrieved by searching by the |
|
520 * key in the cache group. If the cache is hit (success) then the contents |
|
521 * are returned. |
|
522 * |
|
523 * On failure, the number of cache misses will be incremented. |
|
524 * |
|
525 * @since 2.0.0 |
|
526 * |
|
527 * @param int|string $key What the contents in the cache are called. |
|
528 * @param string $group Optional. Where the cache contents are grouped. Default 'default'. |
|
529 * @param bool $force Optional. Unused. Whether to force a refetch rather than relying on the local |
|
530 * cache. Default false. |
|
531 * @param bool $found Optional. Whether the key was found in the cache (passed by reference). |
|
532 * Disambiguates a return of false, a storable value. Default null. |
|
533 * @return false|mixed False on failure to retrieve contents or the cache contents on success. |
|
534 */ |
|
535 public function get( $key, $group = 'default', $force = false, &$found = null ) { |
|
536 if ( empty( $group ) ) { |
|
537 $group = 'default'; |
|
538 } |
|
539 |
|
540 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { |
|
541 $key = $this->blog_prefix . $key; |
|
542 } |
|
543 |
|
544 if ( $this->_exists( $key, $group ) ) { |
|
545 $found = true; |
|
546 $this->cache_hits += 1; |
|
547 if ( is_object( $this->cache[ $group ][ $key ] ) ) { |
|
548 return clone $this->cache[ $group ][ $key ]; |
|
549 } else { |
|
550 return $this->cache[ $group ][ $key ]; |
|
551 } |
|
552 } |
|
553 |
|
554 $found = false; |
|
555 $this->cache_misses += 1; |
|
556 return false; |
|
557 } |
|
558 |
|
559 /** |
|
560 * Increments numeric cache item's value. |
|
561 * |
|
562 * @since 3.3.0 |
|
563 * |
|
564 * @param int|string $key The cache key to increment |
|
565 * @param int $offset Optional. The amount by which to increment the item's value. Default 1. |
|
566 * @param string $group Optional. The group the key is in. Default 'default'. |
|
567 * @return false|int False on failure, the item's new value on success. |
|
568 */ |
|
569 public function incr( $key, $offset = 1, $group = 'default' ) { |
|
570 if ( empty( $group ) ) { |
|
571 $group = 'default'; |
|
572 } |
|
573 |
|
574 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { |
|
575 $key = $this->blog_prefix . $key; |
|
576 } |
|
577 |
|
578 if ( ! $this->_exists( $key, $group ) ) { |
|
579 return false; |
|
580 } |
|
581 |
|
582 if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) { |
|
583 $this->cache[ $group ][ $key ] = 0; |
|
584 } |
|
585 |
|
586 $offset = (int) $offset; |
|
587 |
|
588 $this->cache[ $group ][ $key ] += $offset; |
|
589 |
|
590 if ( $this->cache[ $group ][ $key ] < 0 ) { |
|
591 $this->cache[ $group ][ $key ] = 0; |
|
592 } |
|
593 |
|
594 return $this->cache[ $group ][ $key ]; |
|
595 } |
|
596 |
|
597 /** |
|
598 * Replaces the contents in the cache, if contents already exist. |
|
599 * |
|
600 * @since 2.0.0 |
|
601 * |
|
602 * @see WP_Object_Cache::set() |
|
603 * |
|
604 * @param int|string $key What to call the contents in the cache. |
|
605 * @param mixed $data The contents to store in the cache. |
|
606 * @param string $group Optional. Where to group the cache contents. Default 'default'. |
|
607 * @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration). |
|
608 * @return bool False if not exists, true if contents were replaced. |
|
609 */ |
|
610 public function replace( $key, $data, $group = 'default', $expire = 0 ) { |
|
611 if ( empty( $group ) ) { |
|
612 $group = 'default'; |
|
613 } |
|
614 |
|
615 $id = $key; |
|
616 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { |
|
617 $id = $this->blog_prefix . $key; |
|
618 } |
|
619 |
|
620 if ( ! $this->_exists( $id, $group ) ) { |
|
621 return false; |
|
622 } |
|
623 |
|
624 return $this->set( $key, $data, $group, (int) $expire ); |
|
625 } |
|
626 |
|
627 /** |
|
628 * Resets cache keys. |
|
629 * |
|
630 * @since 3.0.0 |
|
631 * |
|
632 * @deprecated 3.5.0 Use switch_to_blog() |
|
633 * @see switch_to_blog() |
|
634 */ |
|
635 public function reset() { |
|
636 _deprecated_function( __FUNCTION__, '3.5.0', 'switch_to_blog()' ); |
|
637 |
|
638 // Clear out non-global caches since the blog ID has changed. |
|
639 foreach ( array_keys( $this->cache ) as $group ) { |
|
640 if ( ! isset( $this->global_groups[ $group ] ) ) { |
|
641 unset( $this->cache[ $group ] ); |
|
642 } |
|
643 } |
|
644 } |
|
645 |
|
646 /** |
|
647 * Sets the data contents into the cache. |
|
648 * |
|
649 * The cache contents are grouped by the $group parameter followed by the |
|
650 * $key. This allows for duplicate ids in unique groups. Therefore, naming of |
|
651 * the group should be used with care and should follow normal function |
|
652 * naming guidelines outside of core WordPress usage. |
|
653 * |
|
654 * The $expire parameter is not used, because the cache will automatically |
|
655 * expire for each time a page is accessed and PHP finishes. The method is |
|
656 * more for cache plugins which use files. |
|
657 * |
|
658 * @since 2.0.0 |
|
659 * |
|
660 * @param int|string $key What to call the contents in the cache. |
|
661 * @param mixed $data The contents to store in the cache. |
|
662 * @param string $group Optional. Where to group the cache contents. Default 'default'. |
|
663 * @param int $expire Not Used. |
|
664 * @return true Always returns true. |
|
665 */ |
|
666 public function set( $key, $data, $group = 'default', $expire = 0 ) { |
|
667 if ( empty( $group ) ) { |
|
668 $group = 'default'; |
|
669 } |
|
670 |
|
671 if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { |
|
672 $key = $this->blog_prefix . $key; |
|
673 } |
|
674 |
|
675 if ( is_object( $data ) ) { |
|
676 $data = clone $data; |
|
677 } |
|
678 |
|
679 $this->cache[ $group ][ $key ] = $data; |
|
680 return true; |
|
681 } |
|
682 |
|
683 /** |
|
684 * Echoes the stats of the caching. |
|
685 * |
|
686 * Gives the cache hits, and cache misses. Also prints every cached group, |
|
687 * key and the data. |
|
688 * |
|
689 * @since 2.0.0 |
|
690 */ |
|
691 public function stats() { |
|
692 echo '<p>'; |
|
693 echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />"; |
|
694 echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />"; |
|
695 echo '</p>'; |
|
696 echo '<ul>'; |
|
697 foreach ( $this->cache as $group => $cache ) { |
|
698 echo "<li><strong>Group:</strong> $group - ( " . number_format( strlen( serialize( $cache ) ) / KB_IN_BYTES, 2 ) . 'k )</li>'; |
|
699 } |
|
700 echo '</ul>'; |
|
701 } |
|
702 |
|
703 /** |
|
704 * Switches the internal blog ID. |
|
705 * |
|
706 * This changes the blog ID used to create keys in blog specific groups. |
|
707 * |
|
708 * @since 3.5.0 |
|
709 * |
|
710 * @param int $blog_id Blog ID. |
|
711 */ |
|
712 public function switch_to_blog( $blog_id ) { |
|
713 $blog_id = (int) $blog_id; |
|
714 $this->blog_prefix = $this->multisite ? $blog_id . ':' : ''; |
|
715 } |
|
716 |
|
717 /** |
|
718 * Serves as a utility function to determine whether a key exists in the cache. |
|
719 * |
|
720 * @since 3.4.0 |
|
721 * |
|
722 * @param int|string $key Cache key to check for existence. |
|
723 * @param string $group Cache group for the key existence check. |
|
724 * @return bool Whether the key exists in the cache for the given group. |
|
725 */ |
|
726 protected function _exists( $key, $group ) { |
|
727 return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) ); |
|
728 } |
|
729 |
|
730 /** |
|
731 * Sets up object properties; PHP 5 style constructor. |
|
732 * |
|
733 * @since 2.0.8 |
|
734 */ |
|
735 public function __construct() { |
|
736 $this->multisite = is_multisite(); |
|
737 $this->blog_prefix = $this->multisite ? get_current_blog_id() . ':' : ''; |
|
738 |
|
739 /** |
|
740 * @todo This should be moved to the PHP4 style constructor, PHP5 |
|
741 * already calls __destruct() |
|
742 */ |
|
743 register_shutdown_function( array( $this, '__destruct' ) ); |
|
744 } |
|
745 |
|
746 /** |
|
747 * Saves the object cache before object is completely destroyed. |
|
748 * |
|
749 * Called upon object destruction, which should be when PHP ends. |
|
750 * |
|
751 * @since 2.0.8 |
|
752 * |
|
753 * @return true Always returns true. |
|
754 */ |
|
755 public function __destruct() { |
|
756 return true; |
|
757 } |
|
758 } |
|