Make WordPress Core

source: tags/5.9/src/wp-includes/class-wp-object-cache.php

Last change on this file was 49692, checked in by johnbillion, 20 months ago

Docs: Various docblock corrections relating to parameter types.

See #51800

  • Property svn:eol-style set to native
File size: 13.2 KB
Line 
1<?php
2/**
3 * Object Cache API: WP_Object_Cache class
4 *
5 * @package WordPress
6 * @subpackage Cache
7 * @since 5.4.0
8 */
9
10/**
11 * Core class that implements an object cache.
12 *
13 * The WordPress Object Cache is used to save on trips to the database. The
14 * Object Cache stores all of the cache data to memory and makes the cache
15 * contents available by using a key, which is used to name and later retrieve
16 * the cache contents.
17 *
18 * The Object Cache can be replaced by other caching mechanisms by placing files
19 * in the wp-content folder which is looked at in wp-settings. If that file
20 * exists, then this file will not be included.
21 *
22 * @since 2.0.0
23 */
24class WP_Object_Cache {
25
26        /**
27         * Holds the cached objects.
28         *
29         * @since 2.0.0
30         * @var array
31         */
32        private $cache = array();
33
34        /**
35         * The amount of times the cache data was already stored in the cache.
36         *
37         * @since 2.5.0
38         * @var int
39         */
40        public $cache_hits = 0;
41
42        /**
43         * Amount of times the cache did not have the request in cache.
44         *
45         * @since 2.0.0
46         * @var int
47         */
48        public $cache_misses = 0;
49
50        /**
51         * List of global cache groups.
52         *
53         * @since 3.0.0
54         * @var array
55         */
56        protected $global_groups = array();
57
58        /**
59         * The blog prefix to prepend to keys in non-global groups.
60         *
61         * @since 3.5.0
62         * @var string
63         */
64        private $blog_prefix;
65
66        /**
67         * Holds the value of is_multisite().
68         *
69         * @since 3.5.0
70         * @var bool
71         */
72        private $multisite;
73
74        /**
75         * Sets up object properties; PHP 5 style constructor.
76         *
77         * @since 2.0.8
78         */
79        public function __construct() {
80                $this->multisite   = is_multisite();
81                $this->blog_prefix = $this->multisite ? get_current_blog_id() . ':' : '';
82        }
83
84        /**
85         * Makes private properties readable for backward compatibility.
86         *
87         * @since 4.0.0
88         *
89         * @param string $name Property to get.
90         * @return mixed Property.
91         */
92        public function __get( $name ) {
93                return $this->$name;
94        }
95
96        /**
97         * Makes private properties settable for backward compatibility.
98         *
99         * @since 4.0.0
100         *
101         * @param string $name  Property to set.
102         * @param mixed  $value Property value.
103         * @return mixed Newly-set property.
104         */
105        public function __set( $name, $value ) {
106                return $this->$name = $value;
107        }
108
109        /**
110         * Makes private properties checkable for backward compatibility.
111         *
112         * @since 4.0.0
113         *
114         * @param string $name Property to check if set.
115         * @return bool Whether the property is set.
116         */
117        public function __isset( $name ) {
118                return isset( $this->$name );
119        }
120
121        /**
122         * Makes private properties un-settable for backward compatibility.
123         *
124         * @since 4.0.0
125         *
126         * @param string $name Property to unset.
127         */
128        public function __unset( $name ) {
129                unset( $this->$name );
130        }
131
132        /**
133         * Adds data to the cache if it doesn't already exist.
134         *
135         * @since 2.0.0
136         *
137         * @uses WP_Object_Cache::_exists() Checks to see if the cache already has data.
138         * @uses WP_Object_Cache::set()     Sets the data after the checking the cache
139         *                                  contents existence.
140         *
141         * @param int|string $key    What to call the contents in the cache.
142         * @param mixed      $data   The contents to store in the cache.
143         * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
144         * @param int        $expire Optional. When to expire the cache contents. Default 0 (no expiration).
145         * @return bool True on success, false if cache key and group already exist.
146         */
147        public function add( $key, $data, $group = 'default', $expire = 0 ) {
148                if ( wp_suspend_cache_addition() ) {
149                        return false;
150                }
151
152                if ( empty( $group ) ) {
153                        $group = 'default';
154                }
155
156                $id = $key;
157                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
158                        $id = $this->blog_prefix . $key;
159                }
160
161                if ( $this->_exists( $id, $group ) ) {
162                        return false;
163                }
164
165                return $this->set( $key, $data, $group, (int) $expire );
166        }
167
168        /**
169         * Sets the list of global cache groups.
170         *
171         * @since 3.0.0
172         *
173         * @param string|string[] $groups List of groups that are global.
174         */
175        public function add_global_groups( $groups ) {
176                $groups = (array) $groups;
177
178                $groups              = array_fill_keys( $groups, true );
179                $this->global_groups = array_merge( $this->global_groups, $groups );
180        }
181
182        /**
183         * Decrements numeric cache item's value.
184         *
185         * @since 3.3.0
186         *
187         * @param int|string $key    The cache key to decrement.
188         * @param int        $offset Optional. The amount by which to decrement the item's value. Default 1.
189         * @param string     $group  Optional. The group the key is in. Default 'default'.
190         * @return int|false The item's new value on success, false on failure.
191         */
192        public function decr( $key, $offset = 1, $group = 'default' ) {
193                if ( empty( $group ) ) {
194                        $group = 'default';
195                }
196
197                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
198                        $key = $this->blog_prefix . $key;
199                }
200
201                if ( ! $this->_exists( $key, $group ) ) {
202                        return false;
203                }
204
205                if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
206                        $this->cache[ $group ][ $key ] = 0;
207                }
208
209                $offset = (int) $offset;
210
211                $this->cache[ $group ][ $key ] -= $offset;
212
213                if ( $this->cache[ $group ][ $key ] < 0 ) {
214                        $this->cache[ $group ][ $key ] = 0;
215                }
216
217                return $this->cache[ $group ][ $key ];
218        }
219
220        /**
221         * Removes the contents of the cache key in the group.
222         *
223         * If the cache key does not exist in the group, then nothing will happen.
224         *
225         * @since 2.0.0
226         *
227         * @param int|string $key        What the contents in the cache are called.
228         * @param string     $group      Optional. Where the cache contents are grouped. Default 'default'.
229         * @param bool       $deprecated Optional. Unused. Default false.
230         * @return bool False if the contents weren't deleted and true on success.
231         */
232        public function delete( $key, $group = 'default', $deprecated = false ) {
233                if ( empty( $group ) ) {
234                        $group = 'default';
235                }
236
237                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
238                        $key = $this->blog_prefix . $key;
239                }
240
241                if ( ! $this->_exists( $key, $group ) ) {
242                        return false;
243                }
244
245                unset( $this->cache[ $group ][ $key ] );
246                return true;
247        }
248
249        /**
250         * Clears the object cache of all data.
251         *
252         * @since 2.0.0
253         *
254         * @return true Always returns true.
255         */
256        public function flush() {
257                $this->cache = array();
258
259                return true;
260        }
261
262        /**
263         * Retrieves the cache contents, if it exists.
264         *
265         * The contents will be first attempted to be retrieved by searching by the
266         * key in the cache group. If the cache is hit (success) then the contents
267         * are returned.
268         *
269         * On failure, the number of cache misses will be incremented.
270         *
271         * @since 2.0.0
272         *
273         * @param int|string $key   The key under which the cache contents are stored.
274         * @param string     $group Optional. Where the cache contents are grouped. Default 'default'.
275         * @param bool       $force Optional. Unused. Whether to force an update of the local cache
276         *                          from the persistent cache. Default false.
277         * @param bool       $found Optional. Whether the key was found in the cache (passed by reference).
278         *                          Disambiguates a return of false, a storable value. Default null.
279         * @return mixed|false The cache contents on success, false on failure to retrieve contents.
280         */
281        public function get( $key, $group = 'default', $force = false, &$found = null ) {
282                if ( empty( $group ) ) {
283                        $group = 'default';
284                }
285
286                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
287                        $key = $this->blog_prefix . $key;
288                }
289
290                if ( $this->_exists( $key, $group ) ) {
291                        $found             = true;
292                        $this->cache_hits += 1;
293                        if ( is_object( $this->cache[ $group ][ $key ] ) ) {
294                                return clone $this->cache[ $group ][ $key ];
295                        } else {
296                                return $this->cache[ $group ][ $key ];
297                        }
298                }
299
300                $found               = false;
301                $this->cache_misses += 1;
302                return false;
303        }
304
305        /**
306         * Retrieves multiple values from the cache in one call.
307         *
308         * @since 5.5.0
309         *
310         * @param array  $keys  Array of keys under which the cache contents are stored.
311         * @param string $group Optional. Where the cache contents are grouped. Default 'default'.
312         * @param bool   $force Optional. Whether to force an update of the local cache
313         *                      from the persistent cache. Default false.
314         * @return array Array of values organized into groups.
315         */
316        public function get_multiple( $keys, $group = 'default', $force = false ) {
317                $values = array();
318
319                foreach ( $keys as $key ) {
320                        $values[ $key ] = $this->get( $key, $group, $force );
321                }
322
323                return $values;
324        }
325
326        /**
327         * Increments numeric cache item's value.
328         *
329         * @since 3.3.0
330         *
331         * @param int|string $key    The cache key to increment
332         * @param int        $offset Optional. The amount by which to increment the item's value. Default 1.
333         * @param string     $group  Optional. The group the key is in. Default 'default'.
334         * @return int|false The item's new value on success, false on failure.
335         */
336        public function incr( $key, $offset = 1, $group = 'default' ) {
337                if ( empty( $group ) ) {
338                        $group = 'default';
339                }
340
341                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
342                        $key = $this->blog_prefix . $key;
343                }
344
345                if ( ! $this->_exists( $key, $group ) ) {
346                        return false;
347                }
348
349                if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
350                        $this->cache[ $group ][ $key ] = 0;
351                }
352
353                $offset = (int) $offset;
354
355                $this->cache[ $group ][ $key ] += $offset;
356
357                if ( $this->cache[ $group ][ $key ] < 0 ) {
358                        $this->cache[ $group ][ $key ] = 0;
359                }
360
361                return $this->cache[ $group ][ $key ];
362        }
363
364        /**
365         * Replaces the contents in the cache, if contents already exist.
366         *
367         * @since 2.0.0
368         *
369         * @see WP_Object_Cache::set()
370         *
371         * @param int|string $key    What to call the contents in the cache.
372         * @param mixed      $data   The contents to store in the cache.
373         * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
374         * @param int        $expire Optional. When to expire the cache contents. Default 0 (no expiration).
375         * @return bool False if not exists, true if contents were replaced.
376         */
377        public function replace( $key, $data, $group = 'default', $expire = 0 ) {
378                if ( empty( $group ) ) {
379                        $group = 'default';
380                }
381
382                $id = $key;
383                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
384                        $id = $this->blog_prefix . $key;
385                }
386
387                if ( ! $this->_exists( $id, $group ) ) {
388                        return false;
389                }
390
391                return $this->set( $key, $data, $group, (int) $expire );
392        }
393
394        /**
395         * Resets cache keys.
396         *
397         * @since 3.0.0
398         *
399         * @deprecated 3.5.0 Use switch_to_blog()
400         * @see switch_to_blog()
401         */
402        public function reset() {
403                _deprecated_function( __FUNCTION__, '3.5.0', 'switch_to_blog()' );
404
405                // Clear out non-global caches since the blog ID has changed.
406                foreach ( array_keys( $this->cache ) as $group ) {
407                        if ( ! isset( $this->global_groups[ $group ] ) ) {
408                                unset( $this->cache[ $group ] );
409                        }
410                }
411        }
412
413        /**
414         * Sets the data contents into the cache.
415         *
416         * The cache contents are grouped by the $group parameter followed by the
417         * $key. This allows for duplicate IDs in unique groups. Therefore, naming of
418         * the group should be used with care and should follow normal function
419         * naming guidelines outside of core WordPress usage.
420         *
421         * The $expire parameter is not used, because the cache will automatically
422         * expire for each time a page is accessed and PHP finishes. The method is
423         * more for cache plugins which use files.
424         *
425         * @since 2.0.0
426         *
427         * @param int|string $key    What to call the contents in the cache.
428         * @param mixed      $data   The contents to store in the cache.
429         * @param string     $group  Optional. Where to group the cache contents. Default 'default'.
430         * @param int        $expire Not Used.
431         * @return true Always returns true.
432         */
433        public function set( $key, $data, $group = 'default', $expire = 0 ) {
434                if ( empty( $group ) ) {
435                        $group = 'default';
436                }
437
438                if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
439                        $key = $this->blog_prefix . $key;
440                }
441
442                if ( is_object( $data ) ) {
443                        $data = clone $data;
444                }
445
446                $this->cache[ $group ][ $key ] = $data;
447                return true;
448        }
449
450        /**
451         * Echoes the stats of the caching.
452         *
453         * Gives the cache hits, and cache misses. Also prints every cached group,
454         * key and the data.
455         *
456         * @since 2.0.0
457         */
458        public function stats() {
459                echo '<p>';
460                echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />";
461                echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />";
462                echo '</p>';
463                echo '<ul>';
464                foreach ( $this->cache as $group => $cache ) {
465                        echo '<li><strong>Group:</strong> ' . esc_html( $group ) . ' - ( ' . number_format( strlen( serialize( $cache ) ) / KB_IN_BYTES, 2 ) . 'k )</li>';
466                }
467                echo '</ul>';
468        }
469
470        /**
471         * Switches the internal blog ID.
472         *
473         * This changes the blog ID used to create keys in blog specific groups.
474         *
475         * @since 3.5.0
476         *
477         * @param int $blog_id Blog ID.
478         */
479        public function switch_to_blog( $blog_id ) {
480                $blog_id           = (int) $blog_id;
481                $this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
482        }
483
484        /**
485         * Serves as a utility function to determine whether a key exists in the cache.
486         *
487         * @since 3.4.0
488         *
489         * @param int|string $key   Cache key to check for existence.
490         * @param string     $group Cache group for the key existence check.
491         * @return bool Whether the key exists in the cache for the given group.
492         */
493        protected function _exists( $key, $group ) {
494                return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) );
495        }
496}
Note: See TracBrowser for help on using the repository browser.