object-cache.php 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187
  1. <?php
  2. /**
  3. * Adds a value to cache.
  4. *
  5. * If the specified key already exists, the value is not stored and the function
  6. * returns false.
  7. *
  8. * @link https://www.php.net/manual/en/memcached.add.php
  9. *
  10. * @param string $key The key under which to store the value.
  11. * @param mixed $value The value to store.
  12. * @param string $group The group value appended to the $key.
  13. * @param int $expiration The expiration time, defaults to 0.
  14. * @return bool True on success, false on failure.
  15. */
  16. function wp_cache_add( $key, $value, $group = '', $expiration = 0 ) {
  17. global $wp_object_cache;
  18. return $wp_object_cache->add( $key, $value, $group, $expiration );
  19. }
  20. /**
  21. * Adds a value to cache on a specific server.
  22. *
  23. * Using a server_key value, the object can be stored on a specified server as opposed
  24. * to a random server in the stack. Note that this method will add the key/value to the
  25. * _cache object as part of the runtime cache. It will add it to an array for the
  26. * specified server_key.
  27. *
  28. * @link https://www.php.net/manual/en/memcached.addbykey.php
  29. *
  30. * @param string $server_key The key identifying the server to store the value on.
  31. * @param string $key The key under which to store the value.
  32. * @param mixed $value The value to store.
  33. * @param string $group The group value appended to the $key.
  34. * @param int $expiration The expiration time, defaults to 0.
  35. * @return bool True on success, false on failure.
  36. */
  37. function wp_cache_add_by_key( $server_key, $key, $value, $group = '', $expiration = 0 ) {
  38. global $wp_object_cache;
  39. return $wp_object_cache->addByKey( $server_key, $key, $value, $group, $expiration );
  40. }
  41. /**
  42. * Adds a single server to the list of Memcached servers.
  43. *
  44. * @link https://www.php.net/manual/en/memcached.addserver.php
  45. *
  46. * @param string $host The hostname of the memcache server.
  47. * @param int $port The port on which memcache is running.
  48. * @param int $weight The weight of the server relative to the total weight
  49. * of all the servers in the pool.
  50. * @return bool True on success, false on failure.
  51. */
  52. function wp_cache_add_server( $host, $port, $weight = 0 ) {
  53. global $wp_object_cache;
  54. return $wp_object_cache->addServer( $host, $port, $weight );
  55. }
  56. /**
  57. * Adds an array of servers to the pool.
  58. *
  59. * Each individual server in the array must include a domain and port, with an optional
  60. * weight value: $servers = array( array( '127.0.0.1', 11211, 0 ) );
  61. *
  62. * @link https://www.php.net/manual/en/memcached.addservers.php
  63. *
  64. * @param array $servers Array of server to register.
  65. * @return bool True on success, false on failure.
  66. */
  67. function wp_cache_add_servers( $servers ) {
  68. global $wp_object_cache;
  69. return $wp_object_cache->addServers( $servers );
  70. }
  71. /**
  72. * Appends data to an existing item.
  73. *
  74. * This method should throw an error if it is used with compressed data.
  75. * This is an expected behavior. Memcached casts the value to be appended to the initial value
  76. * to the type of the initial value. Be careful as this leads to unexpected behavior at times.
  77. * Due to how memcached treats types, the behavior has been mimicked in the internal cache to produce
  78. * similar results and improve consistency. It is recommended that appends only occur with data of
  79. * the same type.
  80. *
  81. * @link https://www.php.net/manual/en/memcached.append.php
  82. *
  83. * @param string $key The key under which to store the value.
  84. * @param mixed $value Must be string as appending mixed values is not well-defined.
  85. * @param string $group The group value appended to the $key.
  86. * @return bool True on success, false on failure.
  87. */
  88. function wp_cache_append( $key, $value, $group = '' ) {
  89. global $wp_object_cache;
  90. return $wp_object_cache->append( $key, $value, $group );
  91. }
  92. /**
  93. * Appends data to an existing item by server key.
  94. *
  95. * This method should throw an error if it is used with compressed data.
  96. * This is an expected behavior. Memcached casts the value to be appended to the initial value
  97. * to the type of the initial value. Be careful as this leads to unexpected behavior at times.
  98. * Due to how memcached treats types, the behavior has been mimicked in the internal cache to produce
  99. * similar results and improve consistency. It is recommended that appends only occur with data of
  100. * the same type.
  101. *
  102. * @link https://www.php.net/manual/en/memcached.appendbykey.php
  103. *
  104. * @param string $server_key The key identifying the server to store the value on.
  105. * @param string $key The key under which to store the value.
  106. * @param mixed $value Must be string as appending mixed values is not well-defined.
  107. * @param string $group The group value appended to the $key.
  108. * @return bool True on success, false on failure.
  109. */
  110. function wp_cache_append_by_key( $server_key, $key, $value, $group = '' ) {
  111. global $wp_object_cache;
  112. return $wp_object_cache->appendByKey( $server_key, $key, $value, $group );
  113. }
  114. /**
  115. * Performs a "check and set" to store data.
  116. *
  117. * The set will be successful only if the no other request has updated the value
  118. * since it was fetched by this request.
  119. *
  120. * @link https://www.php.net/manual/en/memcached.cas.php
  121. *
  122. * @param float $cas_token Unique value associated with the existing item. Generated by memcached.
  123. * @param string $key The key under which to store the value.
  124. * @param mixed $value The value to store.
  125. * @param string $group The group value appended to the $key.
  126. * @param int $expiration The expiration time, defaults to 0.
  127. * @return bool True on success, false on failure.
  128. */
  129. function wp_cache_cas( $cas_token, $key, $value, $group = '', $expiration = 0 ) {
  130. global $wp_object_cache;
  131. return $wp_object_cache->cas( $cas_token, $key, $value, $group, $expiration );
  132. }
  133. /**
  134. * Performs a "check and set" to store data with a server key.
  135. *
  136. * The set will be successful only if the no other request has updated the value
  137. * since it was fetched by this request.
  138. *
  139. * @link https://www.php.net/manual/en/memcached.casbykey.php
  140. *
  141. * @param string $server_key The key identifying the server to store the value on.
  142. * @param float $cas_token Unique value associated with the existing item. Generated by memcached.
  143. * @param string $key The key under which to store the value.
  144. * @param mixed $value The value to store.
  145. * @param string $group The group value appended to the $key.
  146. * @param int $expiration The expiration time, defaults to 0.
  147. * @return bool True on success, false on failure.
  148. */
  149. function wp_cache_cas_by_key( $cas_token, $server_key, $key, $value, $group = '', $expiration = 0 ) {
  150. global $wp_object_cache;
  151. return $wp_object_cache->casByKey( $cas_token, $server_key, $key, $value, $group, $expiration );
  152. }
  153. /**
  154. * Closes the cache.
  155. *
  156. * This function has ceased to do anything since WordPress 2.5.
  157. * The functionality was removed along with the rest of the persistent cache.
  158. * This does not mean that plugins can't implement this function when they need
  159. * to make sure that the cache is cleaned up after WordPress no longer needs it.
  160. *
  161. * @since 2.0.0
  162. *
  163. * @return bool Always returns true.
  164. */
  165. function wp_cache_close() {
  166. return true;
  167. }
  168. /**
  169. * Decrements a numeric item's value.
  170. *
  171. * @link https://www.php.net/manual/en/memcached.decrement.php
  172. *
  173. * @param string $key The key under which to store the value.
  174. * @param int $offset The amount by which to decrement the item's value.
  175. * @param string $group The group value appended to the $key.
  176. * @return int|bool Item's new value on success, false on failure.
  177. */
  178. function wp_cache_decrement( $key, $offset = 1, $group = '' ) {
  179. global $wp_object_cache;
  180. return $wp_object_cache->decrement( $key, $offset, $group );
  181. }
  182. /**
  183. * Decrements a numeric item's value.
  184. *
  185. * This is the same as wp_cache_decrement(), but kept for backward compatibility.
  186. * The original WordPress caching backends use wp_cache_decr().
  187. *
  188. * @link https://www.php.net/manual/en/memcached.decrement.php
  189. *
  190. * @param string $key The key under which to store the value.
  191. * @param int $offset The amount by which to decrement the item's value.
  192. * @param string $group The group value appended to the $key.
  193. * @return int|bool Item's new value on success, false on failure.
  194. */
  195. function wp_cache_decr( $key, $offset = 1, $group = '' ) {
  196. return wp_cache_decrement( $key, $offset, $group );
  197. }
  198. /**
  199. * Removes the item from the cache.
  200. *
  201. * Removes an item from memcached with identified by $key after $time seconds.
  202. * The $time parameter allows an object to be queued for deletion without
  203. * immediately deleting. Between the time that it is queued and the time it's deleted,
  204. * add, replace, and get will fail, but set will succeed.
  205. *
  206. * @link https://www.php.net/manual/en/memcached.delete.php
  207. *
  208. * @param string $key The key under which to store the value.
  209. * @param string $group The group value appended to the $key.
  210. * @param int $time The amount of time the server will wait to delete the item in seconds.
  211. * @return bool True on success, false on failure.
  212. */
  213. function wp_cache_delete( $key, $group = '', $time = 0 ) {
  214. global $wp_object_cache;
  215. return $wp_object_cache->delete( $key, $group, $time );
  216. }
  217. /**
  218. * Removes the item from the cache by server key.
  219. *
  220. * Removes an item from memcached with identified by $key after $time seconds.
  221. * The $time parameter allows an object to be queued for deletion without
  222. * immediately deleting. Between the time that it is queued and the time it's deleted,
  223. * add, replace, and get will fail, but set will succeed.
  224. *
  225. * @link https://www.php.net/manual/en/memcached.deletebykey.php
  226. *
  227. * @param string $server_key The key identifying the server to store the value on.
  228. * @param string $key The key under which to store the value.
  229. * @param string $group The group value appended to the $key.
  230. * @param int $time The amount of time the server will wait to delete the item in seconds.
  231. * @return bool True on success, false on failure.
  232. */
  233. function wp_cache_delete_by_key( $server_key, $key, $group = '', $time = 0 ) {
  234. global $wp_object_cache;
  235. return $wp_object_cache->deleteByKey( $server_key, $key, $group, $time );
  236. }
  237. /**
  238. * Fetches the next result.
  239. *
  240. * @link https://www.php.net/manual/en/memcached.fetch.php
  241. *
  242. * @return array|false The next result on success, false on failure.
  243. */
  244. function wp_cache_fetch() {
  245. global $wp_object_cache;
  246. return $wp_object_cache->fetch();
  247. }
  248. /**
  249. * Fetches all remaining results from the last request.
  250. *
  251. * @link https://www.php.net/manual/en/memcached.fetchall.php
  252. *
  253. * @return array|false The results on success, false on failure.
  254. */
  255. function wp_cache_fetch_all() {
  256. global $wp_object_cache;
  257. return $wp_object_cache->fetchAll();
  258. }
  259. /**
  260. * Invalidates all items in the cache.
  261. *
  262. * @link https://www.php.net/manual/en/memcached.flush.php
  263. *
  264. * @param int $delay Number of seconds to wait before invalidating the items.
  265. * @return bool True on success, false on failure.
  266. */
  267. function wp_cache_flush( $delay = 0 ) {
  268. global $wp_object_cache;
  269. return $wp_object_cache->flush( $delay );
  270. }
  271. /**
  272. * Retrieves object from cache.
  273. *
  274. * Gets an object from cache based on $key and $group. In order to fully support
  275. * the $cache_cb and $cas_token parameters, the runtime cache is ignored by this function
  276. * if either of those values are set. In that case, the request is made directly
  277. * to the memcached server for proper handling of the callback and/or token.
  278. *
  279. * Note that the $deprecated and $found args are only here for compatibility
  280. * with the native wp_cache_get() function.
  281. *
  282. * @link https://www.php.net/manual/en/memcached.get.php
  283. *
  284. * @param string $key The key under which to store the value.
  285. * @param string $group The group value appended to the $key.
  286. * @param bool $force Whether or not to force a cache invalidation.
  287. * @param null|bool $found Variable passed by reference to determine if the value was found or not.
  288. * @param null|string $cache_cb Read-through caching callback.
  289. * @param null|float $cas_token The variable to store the CAS token in.
  290. * @return bool|mixed Cached object value.
  291. */
  292. function wp_cache_get( $key, $group = '', $force = false, &$found = null, $cache_cb = null, &$cas_token = null ) {
  293. global $wp_object_cache;
  294. if ( func_num_args() > 4 ) {
  295. return $wp_object_cache->get( $key, $group, $force, $found, '', false, $cache_cb, $cas_token );
  296. } else {
  297. return $wp_object_cache->get( $key, $group, $force, $found );
  298. }
  299. }
  300. /**
  301. * Retrieves object from cache from specified server.
  302. *
  303. * Gets an object from cache based on $key, $group, and $server_key. In order to fully support
  304. * the $cache_cb and $cas_token parameters, the runtime cache is ignored by this function
  305. * if either of those values are set. In that case, the request is made directly
  306. * to the memcached server for proper handling of the callback and/or token.
  307. *
  308. * @link https://www.php.net/manual/en/memcached.getbykey.php
  309. *
  310. * @param string $server_key The key identifying the server to store the value on.
  311. * @param string $key The key under which to store the value.
  312. * @param string $group The group value appended to the $key.
  313. * @param bool $force Whether or not to force a cache invalidation.
  314. * @param null|bool $found Variable passed by reference to determine if the value was found or not.
  315. * @param null|string $cache_cb Read-through caching callback.
  316. * @param null|float $cas_token The variable to store the CAS token in.
  317. * @return bool|mixed Cached object value.
  318. */
  319. function wp_cache_get_by_key( $server_key, $key, $group = '', $force = false, &$found = null, $cache_cb = null, &$cas_token = null ) {
  320. global $wp_object_cache;
  321. if ( func_num_args() > 5 ) {
  322. return $wp_object_cache->getByKey( $server_key, $key, $group, $force, $found, $cache_cb, $cas_token );
  323. } else {
  324. return $wp_object_cache->getByKey( $server_key, $key, $group, $force, $found );
  325. }
  326. }
  327. /**
  328. * Requests multiple keys without blocking.
  329. *
  330. * @link https://www.php.net/manual/en/memcached.getdelayed.php
  331. *
  332. * @param string|array $keys Array or string of key(s) to request.
  333. * @param string|array $groups Array or string of group(s) for the key(s).
  334. * See buildKeys for more on how these are handled.
  335. * @param bool $with_cas Whether to request CAS token values also.
  336. * @param null $value_cb The result callback or null.
  337. * @return bool True on success, false on failure.
  338. */
  339. function wp_cache_get_delayed( $keys, $groups = '', $with_cas = false, $value_cb = null ) {
  340. global $wp_object_cache;
  341. return $wp_object_cache->getDelayed( $keys, $groups, $with_cas, $value_cb );
  342. }
  343. /**
  344. * Requests multiple keys without blocking from a specified server.
  345. *
  346. * @link https://www.php.net/manual/en/memcached.getdelayed.php
  347. *
  348. * @param string $server_key The key identifying the server to store the value on.
  349. * @param string|array $keys Array or string of key(s) to request.
  350. * @param string|array $groups Array or string of group(s) for the key(s).
  351. * See buildKeys for more on how these are handled.
  352. * @param bool $with_cas Whether to request CAS token values also.
  353. * @param null $value_cb The result callback or null.
  354. * @return bool True on success, false on failure.
  355. */
  356. function wp_cache_get_delayed_by_key( $server_key, $keys, $groups = '', $with_cas = false, $value_cb = null ) {
  357. global $wp_object_cache;
  358. return $wp_object_cache->getDelayedByKey( $server_key, $keys, $groups, $with_cas, $value_cb );
  359. }
  360. /**
  361. * Gets multiple values from memcached in one request.
  362. *
  363. * See the buildKeys method definition to understand the $keys/$groups parameters.
  364. *
  365. * @link https://www.php.net/manual/en/memcached.getmulti.php
  366. *
  367. * @param array $keys Array of keys to retrieve.
  368. * @param string|array $groups If string, used for all keys.
  369. * If arrays, corresponds with the $keys array.
  370. * @param null|array $cas_tokens The variable to store the CAS tokens for the found items.
  371. * @param int $flags The flags for the get operation.
  372. * @return bool|array The array of found items on success, false on failure.
  373. */
  374. function wp_cache_get_multi( $keys, $groups = '', &$cas_tokens = null, $flags = null ) {
  375. global $wp_object_cache;
  376. if ( func_num_args() > 2 ) {
  377. return $wp_object_cache->getMulti( $keys, $groups, '', $cas_tokens, $flags );
  378. } else {
  379. return $wp_object_cache->getMulti( $keys, $groups );
  380. }
  381. }
  382. /**
  383. * Gets multiple values from memcached in one request by specified server key.
  384. *
  385. * See the buildKeys method definition to understand the $keys/$groups parameters.
  386. *
  387. * @link https://www.php.net/manual/en/memcached.getmultibykey.php
  388. *
  389. * @param string $server_key The key identifying the server to store the value on.
  390. * @param array $keys Array of keys to retrieve.
  391. * @param string|array $groups If string, used for all keys.
  392. * If arrays, corresponds with the $keys array.
  393. * @param null|array $cas_tokens The variable to store the CAS tokens for the found items.
  394. * @param int $flags The flags for the get operation.
  395. * @return bool|array The array of found items on success, false on failure.
  396. */
  397. function wp_cache_get_multi_by_key( $server_key, $keys, $groups = '', &$cas_tokens = null, $flags = null ) {
  398. global $wp_object_cache;
  399. if ( func_num_args() > 3 ) {
  400. return $wp_object_cache->getMultiByKey( $server_key, $keys, $groups, $cas_tokens, $flags );
  401. } else {
  402. return $wp_object_cache->getMultiByKey( $server_key, $keys, $groups );
  403. }
  404. }
  405. /**
  406. * Retrieves a Memcached option value.
  407. *
  408. * @link https://www.php.net/manual/en/memcached.getoption.php
  409. *
  410. * @param int $option One of the Memcached::OPT_* constants.
  411. * @return mixed The value of the requested option on success, false on failure.
  412. */
  413. function wp_cache_get_option( $option ) {
  414. global $wp_object_cache;
  415. return $wp_object_cache->getOption( $option );
  416. }
  417. /**
  418. * Returns the result code of the last option.
  419. *
  420. * @link https://www.php.net/manual/en/memcached.getresultcode.php
  421. *
  422. * @return int Result code of the last Memcached operation.
  423. */
  424. function wp_cache_get_result_code() {
  425. global $wp_object_cache;
  426. return $wp_object_cache->getResultCode();
  427. }
  428. /**
  429. * Return the message describing the result of the last operation.
  430. *
  431. * @link https://www.php.net/manual/en/memcached.getresultmessage.php
  432. *
  433. * @return string Message describing the result of the last Memcached operation.
  434. */
  435. function wp_cache_get_result_message() {
  436. global $wp_object_cache;
  437. return $wp_object_cache->getResultMessage();
  438. }
  439. /**
  440. * Gets server information by key.
  441. *
  442. * @link https://www.php.net/manual/en/memcached.getserverbykey.php
  443. *
  444. * @param string $server_key The key identifying the server to store the value on.
  445. * @return array Array with host, post, and weight on success, fales on failure.
  446. */
  447. function wp_cache_get_server_by_key( $server_key ) {
  448. global $wp_object_cache;
  449. return $wp_object_cache->getServerByKey( $server_key );
  450. }
  451. /**
  452. * Gets the list of servers in the pool.
  453. *
  454. * @link https://www.php.net/manual/en/memcached.getserverlist.php
  455. *
  456. * @return array The list of all servers in the server pool.
  457. */
  458. function wp_cache_get_server_list() {
  459. global $wp_object_cache;
  460. return $wp_object_cache->getServerList();
  461. }
  462. /**
  463. * Gets server pool statistics.
  464. *
  465. * @link https://www.php.net/manual/en/memcached.getstats.php
  466. *
  467. * @return array Array of server statistics, one entry per server.
  468. */
  469. function wp_cache_get_stats() {
  470. global $wp_object_cache;
  471. return $wp_object_cache->getStats();
  472. }
  473. /**
  474. * Gets server pool memcached version information.
  475. *
  476. * @link https://www.php.net/manual/en/memcached.getversion.php
  477. *
  478. * @return array Array of server versions, one entry per server.
  479. */
  480. function wp_cache_get_version() {
  481. global $wp_object_cache;
  482. return $wp_object_cache->getVersion();
  483. }
  484. /**
  485. * Increments a numeric item's value.
  486. *
  487. * @link https://www.php.net/manual/en/memcached.increment.php
  488. *
  489. * @param string $key The key under which to store the value.
  490. * @param int $offset The amount by which to increment the item's value.
  491. * @param string $group The group value appended to the $key.
  492. * @return int|bool Item's new value on success, false on failure.
  493. */
  494. function wp_cache_increment( $key, $offset = 1, $group = '' ) {
  495. global $wp_object_cache;
  496. return $wp_object_cache->increment( $key, $offset, $group );
  497. }
  498. /**
  499. * Increments a numeric item's value.
  500. *
  501. * This is the same as wp_cache_increment(), but kept for backward compatibility.
  502. * The original WordPress caching backends use wp_cache_incr().
  503. *
  504. * @link https://www.php.net/manual/en/memcached.increment.php
  505. *
  506. * @param string $key The key under which to store the value.
  507. * @param int $offset The amount by which to increment the item's value.
  508. * @param string $group The group value appended to the $key.
  509. * @return int|bool Item's new value on success, false on failure.
  510. */
  511. function wp_cache_incr( $key, $offset = 1, $group = '' ) {
  512. return wp_cache_increment( $key, $offset, $group );
  513. }
  514. /**
  515. * Prepends data to an existing item.
  516. *
  517. * This method should throw an error if it is used with compressed data. This is an expected behavior.
  518. * Memcached casts the value to be prepended to the initial value to the type of the initial value.
  519. * Be careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23
  520. * to (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer"
  521. * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been
  522. * mimicked in the internal cache to produce similar results and improve consistency. It is recommended
  523. * that prepends only occur with data of the same type.
  524. *
  525. * @link https://www.php.net/manual/en/memcached.prepend.php
  526. *
  527. * @param string $key The key under which to store the value.
  528. * @param string $value Must be string as prepending mixed values is not well-defined.
  529. * @param string $group The group value prepended to the $key.
  530. * @return bool True on success, false on failure.
  531. */
  532. function wp_cache_prepend( $key, $value, $group = '' ) {
  533. global $wp_object_cache;
  534. return $wp_object_cache->prepend( $key, $value, $group );
  535. }
  536. /**
  537. * Appends data to an existing item by server key.
  538. *
  539. * This method should throw an error if it is used with compressed data. This is an expected behavior.
  540. * Memcached casts the value to be prepended to the initial value to the type of the initial value.
  541. * Be careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23
  542. * to (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer"
  543. * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been
  544. * mimicked in the internal cache to produce similar results and improve consistency. It is recommended
  545. * that prepends only occur with data of the same type.
  546. *
  547. * @link https://www.php.net/manual/en/memcached.prependbykey.php
  548. *
  549. * @param string $server_key The key identifying the server to store the value on.
  550. * @param string $key The key under which to store the value.
  551. * @param string $value Must be string as prepending mixed values is not well-defined.
  552. * @param string $group The group value prepended to the $key.
  553. * @return bool True on success, false on failure.
  554. */
  555. function wp_cache_prepend_by_key( $server_key, $key, $value, $group = '' ) {
  556. global $wp_object_cache;
  557. return $wp_object_cache->prependByKey( $server_key, $key, $value, $group );
  558. }
  559. /**
  560. * Replaces a value in cache.
  561. *
  562. * This method is similar to "add"; however, is does not successfully set a value
  563. * if the object's key is not already set in cache.
  564. *
  565. * @link https://www.php.net/manual/en/memcached.replace.php
  566. *
  567. * @param string $key The key under which to store the value.
  568. * @param mixed $value The value to store.
  569. * @param string $group The group value appended to the $key.
  570. * @param int $expiration The expiration time, defaults to 0.
  571. * @return bool True on success, false on failure.
  572. */
  573. function wp_cache_replace( $key, $value, $group = '', $expiration = 0 ) {
  574. global $wp_object_cache;
  575. return $wp_object_cache->replace( $key, $value, $group, $expiration );
  576. }
  577. /**
  578. * Replaces a value in cache on a specific server.
  579. *
  580. * This method is similar to "addByKey"; however, is does not successfully set a value
  581. * if the object's key is not already set in cache.
  582. *
  583. * @link https://www.php.net/manual/en/memcached.addbykey.php
  584. *
  585. * @param string $server_key The key identifying the server to store the value on.
  586. * @param string $key The key under which to store the value.
  587. * @param mixed $value The value to store.
  588. * @param string $group The group value appended to the $key.
  589. * @param int $expiration The expiration time, defaults to 0.
  590. * @return bool True on success, false on failure.
  591. */
  592. function wp_cache_replace_by_key( $server_key, $key, $value, $group = '', $expiration = 0 ) {
  593. global $wp_object_cache;
  594. return $wp_object_cache->replaceByKey( $server_key, $key, $value, $group, $expiration );
  595. }
  596. /**
  597. * Sets a value in cache.
  598. *
  599. * The value is set whether or not this key already exists in memcached.
  600. *
  601. * @link https://www.php.net/manual/en/memcached.set.php
  602. *
  603. * @param string $key The key under which to store the value.
  604. * @param mixed $value The value to store.
  605. * @param string $group The group value appended to the $key.
  606. * @param int $expiration The expiration time, defaults to 0.
  607. * @return bool True on success, false on failure.
  608. */
  609. function wp_cache_set( $key, $value, $group = '', $expiration = 0 ) {
  610. global $wp_object_cache;
  611. return $wp_object_cache->set( $key, $value, $group, $expiration );
  612. }
  613. /**
  614. * Sets a value in cache.
  615. *
  616. * The value is set whether or not this key already exists in memcached.
  617. *
  618. * @link https://www.php.net/manual/en/memcached.set.php
  619. *
  620. * @param string $server_key The key identifying the server to store the value on.
  621. * @param string $key The key under which to store the value.
  622. * @param mixed $value The value to store.
  623. * @param string $group The group value appended to the $key.
  624. * @param int $expiration The expiration time, defaults to 0.
  625. * @return bool True on success, false on failure.
  626. */
  627. function wp_cache_set_by_key( $server_key, $key, $value, $group = '', $expiration = 0 ) {
  628. global $wp_object_cache;
  629. return $wp_object_cache->setByKey( $server_key, $key, $value, $group, $expiration );
  630. }
  631. /**
  632. * Sets multiple values to cache at once.
  633. *
  634. * By sending an array of $items to this function, all values are saved at once to
  635. * memcached, reducing the need for multiple requests to memcached. The $items array
  636. * keys and values are what are stored to memcached. The keys in the $items array
  637. * are merged with the $groups array/string value via buildKeys to determine the
  638. * final key for the object.
  639. *
  640. * @param array $items An array of key/value pairs to store on the server.
  641. * @param string|array $groups Group(s) to merge with key(s) in $items.
  642. * @param int $expiration The expiration time, defaults to 0.
  643. * @return bool True on success, false on failure.
  644. */
  645. function wp_cache_set_multi( $items, $groups = '', $expiration = 0 ) {
  646. global $wp_object_cache;
  647. return $wp_object_cache->setMulti( $items, $groups, $expiration );
  648. }
  649. /**
  650. * Sets multiple values to cache at once on specified server.
  651. *
  652. * By sending an array of $items to this function, all values are saved at once to
  653. * memcached, reducing the need for multiple requests to memcached. The $items array
  654. * keys and values are what are stored to memcached. The keys in the $items array
  655. * are merged with the $groups array/string value via buildKeys to determine the
  656. * final key for the object.
  657. *
  658. * @param string $server_key The key identifying the server to store the value on.
  659. * @param array $items An array of key/value pairs to store on the server.
  660. * @param string|array $groups Group(s) to merge with key(s) in $items.
  661. * @param int $expiration The expiration time, defaults to 0.
  662. * @return bool True on success, false on failure.
  663. */
  664. function wp_cache_set_multi_by_key( $server_key, $items, $groups = 'default', $expiration = 0 ) {
  665. global $wp_object_cache;
  666. return $wp_object_cache->setMultiByKey( $server_key, $items, $groups, $expiration );
  667. }
  668. /**
  669. * Sets a Memcached option.
  670. *
  671. * @link https://www.php.net/manual/en/memcached.setoption.php
  672. *
  673. * @param int $option Option name.
  674. * @param mixed $value Option value.
  675. * @return bool True on success, false on failure.
  676. */
  677. function wp_cache_set_option( $option, $value ) {
  678. global $wp_object_cache;
  679. return $wp_object_cache->setOption( $option, $value );
  680. }
  681. /**
  682. * Switches blog prefix, which changes the cache that is accessed.
  683. *
  684. * @param int $blog_id Blog to switch to.
  685. * @return void
  686. */
  687. function wp_cache_switch_to_blog( $blog_id ) {
  688. global $wp_object_cache;
  689. return $wp_object_cache->switch_to_blog( $blog_id );
  690. }
  691. /**
  692. * Sets up Object Cache Global and assigns it.
  693. *
  694. * @global WP_Object_Cache $wp_object_cache WordPress Object Cache
  695. * @return void
  696. */
  697. function wp_cache_init() {
  698. global $wp_object_cache;
  699. $wp_object_cache = new WP_Object_Cache();
  700. }
  701. /**
  702. * Adds a group or set of groups to the list of non-persistent groups.
  703. *
  704. * @param string|array $groups A group or an array of groups to add.
  705. * @return void
  706. */
  707. function wp_cache_add_global_groups( $groups ) {
  708. global $wp_object_cache;
  709. $wp_object_cache->add_global_groups( $groups );
  710. }
  711. /**
  712. * Adds a group or set of groups to the list of non-Memcached groups.
  713. *
  714. * @param string|array $groups A group or an array of groups to add.
  715. * @return void
  716. */
  717. function wp_cache_add_non_persistent_groups( $groups ) {
  718. global $wp_object_cache;
  719. $wp_object_cache->add_non_persistent_groups( $groups );
  720. }
  721. // phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
  722. class WP_Object_Cache {
  723. /**
  724. * Holds the Memcached object.
  725. *
  726. * @var Memcached
  727. */
  728. public $m;
  729. /**
  730. * Hold the Memcached server details.
  731. *
  732. * @var array
  733. */
  734. public $servers;
  735. /**
  736. * Holds the non-Memcached objects.
  737. *
  738. * @var array
  739. */
  740. public $cache = array();
  741. /**
  742. * List of global groups.
  743. *
  744. * @var array
  745. */
  746. public $global_groups = array( 'users', 'userlogins', 'usermeta', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss' );
  747. /**
  748. * List of groups not saved to Memcached.
  749. *
  750. * @var array
  751. */
  752. public $no_mc_groups = array( 'comment', 'counts' );
  753. /**
  754. * Prefix used for global groups.
  755. *
  756. * @var string
  757. */
  758. public $global_prefix = '';
  759. /**
  760. * Prefix used for non-global groups.
  761. *
  762. * @var string
  763. */
  764. public $blog_prefix = '';
  765. /**
  766. * Instantiates the Memcached class.
  767. *
  768. * Instantiates the Memcached class and returns adds the servers specified
  769. * in the $memcached_servers global array.
  770. *
  771. * @link https://www.php.net/manual/en/memcached.construct.php
  772. *
  773. * @param null $persistent_id To create an instance that persists between requests,
  774. * use persistent_id to specify a unique ID for the instance.
  775. */
  776. public function __construct( $persistent_id = null ) {
  777. global $memcached_servers, $blog_id, $table_prefix;
  778. if ( is_null( $persistent_id ) || ! is_string( $persistent_id ) ) {
  779. $this->m = new Memcached();
  780. } else {
  781. $this->m = new Memcached( $persistent_id );
  782. }
  783. if ( isset( $memcached_servers ) ) {
  784. $this->servers = $memcached_servers;
  785. } else {
  786. $this->servers = array( array( 'memcached', 11211 ) );
  787. }
  788. $this->addServers( $this->servers );
  789. /**
  790. * This approach is borrowed from Sivel and Boren. Use the salt for easy cache invalidation
  791. * and for multi single WP installations on the same server.
  792. */
  793. if ( ! defined( 'WP_CACHE_KEY_SALT' ) ) {
  794. define( 'WP_CACHE_KEY_SALT', '' );
  795. }
  796. // Assign global and blog prefixes for use with keys.
  797. if ( function_exists( 'is_multisite' ) ) {
  798. $this->global_prefix = ( is_multisite() || defined( 'CUSTOM_USER_TABLE' ) && defined( 'CUSTOM_USER_META_TABLE' ) ) ? '' : $table_prefix;
  799. $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ) . ':';
  800. }
  801. // Setup cacheable values for handling expiration times.
  802. $this->thirty_days = 60 * 60 * 24 * 30;
  803. $this->now = time();
  804. }
  805. /**
  806. * Adds a value to cache.
  807. *
  808. * If the specified key already exists, the value is not stored and the function
  809. * returns false.
  810. *
  811. * @link https://www.php.net/manual/en/memcached.add.php
  812. *
  813. * @param string $key The key under which to store the value.
  814. * @param mixed $value The value to store.
  815. * @param string $group The group value appended to the $key.
  816. * @param int $expiration The expiration time, defaults to 0.
  817. * @param string $server_key The key identifying the server to store the value on.
  818. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  819. * @return bool True on success, false on failure.
  820. */
  821. public function add( $key, $value, $group = 'default', $expiration = 0, $server_key = '', $by_key = false ) {
  822. /*
  823. * Ensuring that wp_suspend_cache_addition is defined before calling, because sometimes an advanced-cache.php
  824. * file will load object-cache.php before wp-includes/functions.php is loaded. In those cases, if wp_cache_add
  825. * is called in advanced-cache.php before any more of WordPress is loaded, we get a fatal error because
  826. * wp_suspend_cache_addition will not be defined until wp-includes/functions.php is loaded.
  827. */
  828. if ( function_exists( 'wp_suspend_cache_addition' ) && wp_suspend_cache_addition() ) {
  829. return false;
  830. }
  831. $derived_key = $this->buildKey( $key, $group );
  832. $expiration = $this->sanitize_expiration( $expiration );
  833. // If group is a non-Memcached group, save to runtime cache, not Memcached.
  834. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  835. // Add does not set the value if the key exists; mimic that here.
  836. if ( isset( $this->cache[ $derived_key ] ) ) {
  837. return false;
  838. }
  839. $this->add_to_internal_cache( $derived_key, $value );
  840. return true;
  841. }
  842. // Save to Memcached.
  843. if ( $by_key ) {
  844. $result = $this->m->addByKey( $server_key, $derived_key, $value, $expiration );
  845. } else {
  846. $result = $this->m->add( $derived_key, $value, $expiration );
  847. }
  848. // Store in runtime cache if add was successful.
  849. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  850. $this->add_to_internal_cache( $derived_key, $value );
  851. }
  852. return $result;
  853. }
  854. /**
  855. * Adds a value to cache on a specific server.
  856. *
  857. * Using a server_key value, the object can be stored on a specified server as opposed
  858. * to a random server in the stack. Note that this method will add the key/value to the
  859. * _cache object as part of the runtime cache. It will add it to an array for the
  860. * specified server_key.
  861. *
  862. * @link https://www.php.net/manual/en/memcached.addbykey.php
  863. *
  864. * @param string $server_key The key identifying the server to store the value on.
  865. * @param string $key The key under which to store the value.
  866. * @param mixed $value The value to store.
  867. * @param string $group The group value appended to the $key.
  868. * @param int $expiration The expiration time, defaults to 0.
  869. * @return bool True on success, false on failure.
  870. */
  871. public function addByKey( $server_key, $key, $value, $group = 'default', $expiration = 0 ) {
  872. return $this->add( $key, $value, $group, $expiration, $server_key, true );
  873. }
  874. /**
  875. * Adds a single server to the list of Memcached servers.
  876. *
  877. * @link https://www.php.net/manual/en/memcached.addserver.php
  878. *
  879. * @param string $host The hostname of the memcache server.
  880. * @param int $port The port on which memcache is running.
  881. * @param int $weight The weight of the server relative to the total weight
  882. * of all the servers in the pool.
  883. * @return bool True on success, false on failure.
  884. */
  885. public function addServer( $host, $port, $weight = 0 ) {
  886. $host = is_string( $host ) ? $host : '127.0.0.1';
  887. $port = is_numeric( $port ) && $port > 0 ? $port : 11211;
  888. $weight = is_numeric( $weight ) && $weight > 0 ? $weight : 1;
  889. return $this->m->addServer( $host, $port, $weight );
  890. }
  891. /**
  892. * Adds an array of servers to the pool.
  893. *
  894. * Each individual server in the array must include a domain and port, with an optional
  895. * weight value: $servers = array( array( '127.0.0.1', 11211, 0 ) );
  896. *
  897. * @link https://www.php.net/manual/en/memcached.addservers.php
  898. *
  899. * @param array $servers Array of server to register.
  900. * @return bool True on success, false on failure.
  901. */
  902. public function addServers( $servers ) {
  903. if ( ! is_object( $this->m ) ) {
  904. return false;
  905. }
  906. return $this->m->addServers( $servers );
  907. }
  908. /**
  909. * Appends data to an existing item.
  910. *
  911. * This method should throw an error if it is used with compressed data.
  912. * This is an expected behavior. Memcached casts the value to be appended to the initial value
  913. * to the type of the initial value. Be careful as this leads to unexpected behavior at times.
  914. * Due to how memcached treats types, the behavior has been mimicked in the internal cache to produce
  915. * similar results and improve consistency. It is recommended that appends only occur with data of
  916. * the same type.
  917. *
  918. * @link https://www.php.net/manual/en/memcached.append.php
  919. *
  920. * @param string $key The key under which to store the value.
  921. * @param mixed $value Must be string as appending mixed values is not well-defined.
  922. * @param string $group The group value appended to the $key.
  923. * @param string $server_key The key identifying the server to store the value on.
  924. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  925. * @return bool True on success, false on failure.
  926. */
  927. public function append( $key, $value, $group = 'default', $server_key = '', $by_key = false ) {
  928. if ( ! is_string( $value ) && ! is_int( $value ) && ! is_float( $value ) ) {
  929. return false;
  930. }
  931. $derived_key = $this->buildKey( $key, $group );
  932. // If group is a non-Memcached group, append to runtime cache value, not Memcached.
  933. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  934. if ( ! isset( $this->cache[ $derived_key ] ) ) {
  935. return false;
  936. }
  937. $combined = $this->combine_values( $this->cache[ $derived_key ], $value, 'app' );
  938. $this->add_to_internal_cache( $derived_key, $combined );
  939. return true;
  940. }
  941. // Append to Memcached value.
  942. if ( $by_key ) {
  943. $result = $this->m->appendByKey( $server_key, $derived_key, $value );
  944. } else {
  945. $result = $this->m->append( $derived_key, $value );
  946. }
  947. // Store in runtime cache if add was successful.
  948. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  949. $combined = $this->combine_values( $this->cache[ $derived_key ], $value, 'app' );
  950. $this->add_to_internal_cache( $derived_key, $combined );
  951. }
  952. return $result;
  953. }
  954. /**
  955. * Appends data to an existing item by server key.
  956. *
  957. * This method should throw an error if it is used with compressed data.
  958. * This is an expected behavior. Memcached casts the value to be appended to the initial value
  959. * to the type of the initial value. Be careful as this leads to unexpected behavior at times.
  960. * Due to how memcached treats types, the behavior has been mimicked in the internal cache to produce
  961. * similar results and improve consistency. It is recommended that appends only occur with data of
  962. * the same type.
  963. *
  964. * @link https://www.php.net/manual/en/memcached.appendbykey.php
  965. *
  966. * @param string $server_key The key identifying the server to store the value on.
  967. * @param string $key The key under which to store the value.
  968. * @param mixed $value Must be string as appending mixed values is not well-defined.
  969. * @param string $group The group value appended to the $key.
  970. * @return bool True on success, false on failure.
  971. */
  972. public function appendByKey( $server_key, $key, $value, $group = 'default' ) {
  973. return $this->append( $key, $value, $group, $server_key, true );
  974. }
  975. /**
  976. * Performs a "check and set" to store data.
  977. *
  978. * The set will be successful only if the no other request has updated the value
  979. * since it was fetched by this request.
  980. *
  981. * @link https://www.php.net/manual/en/memcached.cas.php
  982. *
  983. * @param float $cas_token Unique value associated with the existing item. Generated by memcached.
  984. * @param string $key The key under which to store the value.
  985. * @param mixed $value The value to store.
  986. * @param string $group The group value appended to the $key.
  987. * @param int $expiration The expiration time, defaults to 0.
  988. * @param string $server_key The key identifying the server to store the value on.
  989. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  990. * @return bool True on success, false on failure.
  991. */
  992. public function cas( $cas_token, $key, $value, $group = 'default', $expiration = 0, $server_key = '', $by_key = false ) {
  993. $derived_key = $this->buildKey( $key, $group );
  994. $expiration = $this->sanitize_expiration( $expiration );
  995. /**
  996. * If group is a non-Memcached group, save to runtime cache, not Memcached. Note
  997. * that since check and set cannot be emulated in the run time cache, this value
  998. * operation is treated as a normal "add" for no_mc_groups.
  999. */
  1000. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1001. $this->add_to_internal_cache( $derived_key, $value );
  1002. return true;
  1003. }
  1004. // Save to Memcached.
  1005. if ( $by_key ) {
  1006. $result = $this->m->casByKey( $cas_token, $server_key, $derived_key, $value, $expiration );
  1007. } else {
  1008. $result = $this->m->cas( $cas_token, $derived_key, $value, $expiration );
  1009. }
  1010. // Store in runtime cache if cas was successful.
  1011. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1012. $this->add_to_internal_cache( $derived_key, $value );
  1013. }
  1014. return $result;
  1015. }
  1016. /**
  1017. * Performs a "check and set" to store data with a server key.
  1018. *
  1019. * The set will be successful only if the no other request has updated the value
  1020. * since it was fetched by this request.
  1021. *
  1022. * @link https://www.php.net/manual/en/memcached.casbykey.php
  1023. *
  1024. * @param string $server_key The key identifying the server to store the value on.
  1025. * @param float $cas_token Unique value associated with the existing item. Generated by memcached.
  1026. * @param string $key The key under which to store the value.
  1027. * @param mixed $value The value to store.
  1028. * @param string $group The group value appended to the $key.
  1029. * @param int $expiration The expiration time, defaults to 0.
  1030. * @return bool True on success, false on failure.
  1031. */
  1032. public function casByKey( $cas_token, $server_key, $key, $value, $group = 'default', $expiration = 0 ) {
  1033. return $this->cas( $cas_token, $key, $value, $group, $expiration, $server_key, true );
  1034. }
  1035. /**
  1036. * Decrements a numeric item's value.
  1037. *
  1038. * @link https://www.php.net/manual/en/memcached.decrement.php
  1039. *
  1040. * @param string $key The key under which to store the value.
  1041. * @param int $offset The amount by which to decrement the item's value.
  1042. * @param string $group The group value appended to the $key.
  1043. * @return int|bool Item's new value on success, false on failure.
  1044. */
  1045. public function decrement( $key, $offset = 1, $group = 'default' ) {
  1046. $derived_key = $this->buildKey( $key, $group );
  1047. // Decrement values in no_mc_groups.
  1048. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1049. // Only decrement if the key already exists and value is 0 or greater (mimics memcached behavior).
  1050. if ( isset( $this->cache[ $derived_key ] ) && $this->cache[ $derived_key ] >= 0 ) {
  1051. // If numeric, subtract; otherwise, consider it 0 and do nothing.
  1052. if ( is_numeric( $this->cache[ $derived_key ] ) ) {
  1053. $this->cache[ $derived_key ] -= (int) $offset;
  1054. } else {
  1055. $this->cache[ $derived_key ] = 0;
  1056. }
  1057. // Returned value cannot be less than 0.
  1058. if ( $this->cache[ $derived_key ] < 0 ) {
  1059. $this->cache[ $derived_key ] = 0;
  1060. }
  1061. return $this->cache[ $derived_key ];
  1062. } else {
  1063. return false;
  1064. }
  1065. }
  1066. $result = $this->m->decrement( $derived_key, $offset );
  1067. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1068. $this->add_to_internal_cache( $derived_key, $result );
  1069. }
  1070. return $result;
  1071. }
  1072. /**
  1073. * Decrements a numeric item's value.
  1074. *
  1075. * Alias for $this->decrement(). Other caching backends use this abbreviated form
  1076. * of the function. It *may* cause breakage somewhere, so it is nice to have.
  1077. * This function will also allow the core unit tests to pass.
  1078. *
  1079. * @param string $key The key under which to store the value.
  1080. * @param int $offset The amount by which to decrement the item's value.
  1081. * @param string $group The group value appended to the $key.
  1082. * @return int|bool Item's new value on success, false on failure.
  1083. */
  1084. public function decr( $key, $offset = 1, $group = 'default' ) {
  1085. return $this->decrement( $key, $offset, $group );
  1086. }
  1087. /**
  1088. * Removes the item from the cache.
  1089. *
  1090. * Removes an item from memcached with identified by $key after $time seconds.
  1091. * The $time parameter allows an object to be queued for deletion without
  1092. * immediately deleting. Between the time that it is queued and the time it's deleted,
  1093. * add, replace, and get will fail, but set will succeed.
  1094. *
  1095. * @link https://www.php.net/manual/en/memcached.delete.php
  1096. *
  1097. * @param string $key The key under which to store the value.
  1098. * @param string $group The group value appended to the $key.
  1099. * @param int $time The amount of time the server will wait to delete the item in seconds.
  1100. * @param string $server_key The key identifying the server to store the value on.
  1101. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  1102. * @return bool True on success, false on failure.
  1103. */
  1104. public function delete( $key, $group = 'default', $time = 0, $server_key = '', $by_key = false ) {
  1105. $derived_key = $this->buildKey( $key, $group );
  1106. // Remove from no_mc_groups array.
  1107. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1108. if ( isset( $this->cache[ $derived_key ] ) ) {
  1109. unset( $this->cache[ $derived_key ] );
  1110. }
  1111. return true;
  1112. }
  1113. if ( $by_key ) {
  1114. $result = $this->m->deleteByKey( $server_key, $derived_key, $time );
  1115. } else {
  1116. $result = $this->m->delete( $derived_key, $time );
  1117. }
  1118. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1119. unset( $this->cache[ $derived_key ] );
  1120. }
  1121. return $result;
  1122. }
  1123. /**
  1124. * Removes the item from the cache by server key.
  1125. *
  1126. * Removes an item from memcached with identified by $key after $time seconds.
  1127. * The $time parameter allows an object to be queued for deletion without
  1128. * immediately deleting. Between the time that it is queued and the time it's deleted,
  1129. * add, replace, and get will fail, but set will succeed.
  1130. *
  1131. * @link https://www.php.net/manual/en/memcached.deletebykey.php
  1132. *
  1133. * @param string $server_key The key identifying the server to store the value on.
  1134. * @param string $key The key under which to store the value.
  1135. * @param string $group The group value appended to the $key.
  1136. * @param int $time The amount of time the server will wait to delete the item in seconds.
  1137. * @return bool True on success, false on failure.
  1138. */
  1139. public function deleteByKey( $server_key, $key, $group = 'default', $time = 0 ) {
  1140. return $this->delete( $key, $group, $time, $server_key, true );
  1141. }
  1142. /**
  1143. * Fetches the next result.
  1144. *
  1145. * @link https://www.php.net/manual/en/memcached.fetch.php
  1146. *
  1147. * @return array|false The next result on success, false on failure.
  1148. */
  1149. public function fetch() {
  1150. return $this->m->fetch();
  1151. }
  1152. /**
  1153. * Fetches all remaining results from the last request.
  1154. *
  1155. * @link https://www.php.net/manual/en/memcached.fetchall.php
  1156. *
  1157. * @return array|false The results on success, false on failure.
  1158. */
  1159. public function fetchAll() {
  1160. return $this->m->fetchAll();
  1161. }
  1162. /**
  1163. * Invalidates all items in the cache.
  1164. *
  1165. * @link https://www.php.net/manual/en/memcached.flush.php
  1166. *
  1167. * @param int $delay Number of seconds to wait before invalidating the items.
  1168. * @return bool True on success, false on failure.
  1169. */
  1170. public function flush( $delay = 0 ) {
  1171. $result = $this->m->flush( $delay );
  1172. // Only reset the runtime cache if memcached was properly flushed.
  1173. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1174. $this->cache = array();
  1175. }
  1176. return $result;
  1177. }
  1178. /**
  1179. * Retrieves object from cache.
  1180. *
  1181. * Gets an object from cache based on $key and $group. In order to fully support
  1182. * the $cache_cb and $cas_token parameters, the runtime cache is ignored by this function
  1183. * if either of those values are set. In that case, the request is made directly
  1184. * to the memcached server for proper handling of the callback and/or token.
  1185. * Note that the $cas_token variable cannot be directly passed to the function.
  1186. * The variable needs to be first defined with a non-null value.
  1187. *
  1188. * If using the $cache_cb argument, the new value will always have an expiration
  1189. * of time of 0 (forever). This is a limitation of the Memcached PECL extension.
  1190. *
  1191. * @link https://www.php.net/manual/en/memcached.get.php
  1192. *
  1193. * @param string $key The key under which to store the value.
  1194. * @param string $group The group value appended to the $key.
  1195. * @param bool $force Whether or not to force a cache invalidation.
  1196. * @param null|bool $found Variable passed by reference to determine if the value was found or not.
  1197. * @param string $server_key The key identifying the server to store the value on.
  1198. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  1199. * @param null|callable $cache_cb Read-through caching callback.
  1200. * @param null|float $cas_token The variable to store the CAS token in.
  1201. * @return bool|mixed Cached object value.
  1202. */
  1203. public function get( $key, $group = 'default', $force = false, &$found = null, $server_key = '', $by_key = false, $cache_cb = null, &$cas_token = null ) {
  1204. $derived_key = $this->buildKey( $key, $group );
  1205. // Assume object is not found.
  1206. $found = false;
  1207. // If either $cache_db, or $cas_token is set, must hit Memcached and bypass runtime cache.
  1208. if ( func_num_args() > 6 && ! in_array( $group, $this->no_mc_groups, true ) ) {
  1209. if ( $by_key ) {
  1210. $value = $this->m->getByKey( $server_key, $derived_key, $cache_cb, $cas_token );
  1211. } else {
  1212. $value = $this->m->get( $derived_key, $cache_cb, $cas_token );
  1213. }
  1214. } else {
  1215. if ( isset( $this->cache[ $derived_key ] ) ) {
  1216. $found = true;
  1217. return is_object( $this->cache[ $derived_key ] ) ? clone $this->cache[ $derived_key ] : $this->cache[ $derived_key ];
  1218. } elseif ( in_array( $group, $this->no_mc_groups, true ) ) {
  1219. return false;
  1220. } else {
  1221. if ( $by_key ) {
  1222. $value = $this->m->getByKey( $server_key, $derived_key );
  1223. } else {
  1224. $value = $this->m->get( $derived_key );
  1225. }
  1226. }
  1227. }
  1228. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1229. $this->add_to_internal_cache( $derived_key, $value );
  1230. $found = true;
  1231. }
  1232. return is_object( $value ) ? clone $value : $value;
  1233. }
  1234. /**
  1235. * Retrieves object from cache from specified server.
  1236. *
  1237. * Gets an object from cache based on $key and $group, and $server_key. In order to fully support
  1238. * the $cache_cb and $cas_token parameters, the runtime cache is ignored by this function
  1239. * if either of those values are set. In that case, the request is made directly
  1240. * to the memcached server for proper handling of the callback and/or token.
  1241. * Note that the $cas_token variable cannot be directly passed to the function.
  1242. * The variable needs to be first defined with a non-null value.
  1243. *
  1244. * If using the $cache_cb argument, the new value will always have an expiration
  1245. * of time of 0 (forever). This is a limitation of the Memcached PECL extension.
  1246. *
  1247. * @link https://www.php.net/manual/en/memcached.getbykey.php
  1248. *
  1249. * @param string $server_key The key identifying the server to store the value on.
  1250. * @param string $key The key under which to store the value.
  1251. * @param string $group The group value appended to the $key.
  1252. * @param bool $force Whether or not to force a cache invalidation.
  1253. * @param null|bool $found Variable passed by reference to determine if the value was found or not.
  1254. * @param null|string $cache_cb Read-through caching callback.
  1255. * @param null|float $cas_token The variable to store the CAS token in.
  1256. * @return bool|mixed Cached object value.
  1257. */
  1258. public function getByKey( $server_key, $key, $group = 'default', $force = false, &$found = null, $cache_cb = null, &$cas_token = null ) {
  1259. /**
  1260. * Need to be careful how "get" is called. If you send $cache_cb, and $cas_token, it will hit memcached.
  1261. * Only send those args if they were sent to this function.
  1262. */
  1263. if ( func_num_args() > 5 ) {
  1264. return $this->get( $key, $group, $force, $found, $server_key, true, $cache_cb, $cas_token );
  1265. } else {
  1266. return $this->get( $key, $group, $force, $found, $server_key, true );
  1267. }
  1268. }
  1269. /**
  1270. * Requests multiple keys without blocking.
  1271. *
  1272. * @link https://www.php.net/manual/en/memcached.getdelayed.php
  1273. *
  1274. * @param string|array $keys Array or string of key(s) to request.
  1275. * @param string|array $groups Array or string of group(s) for the key(s).
  1276. * See buildKeys for more on how these are handled.
  1277. * @param bool $with_cas Whether to request CAS token values also.
  1278. * @param null $value_cb The result callback or null.
  1279. * @return bool True on success, false on failure.
  1280. */
  1281. public function getDelayed( $keys, $groups = 'default', $with_cas = false, $value_cb = null ) {
  1282. $derived_keys = $this->buildKeys( $keys, $groups );
  1283. return $this->m->getDelayed( $derived_keys, $with_cas, $value_cb );
  1284. }
  1285. /**
  1286. * Requests multiple keys without blocking from a specified server.
  1287. *
  1288. * @link https://www.php.net/manual/en/memcached.getdelayed.php
  1289. *
  1290. * @param string $server_key The key identifying the server to store the value on.
  1291. * @param string|array $keys Array or string of key(s) to request.
  1292. * @param string|array $groups Array or string of group(s) for the key(s).
  1293. * See buildKeys for more on how these are handled.
  1294. * @param bool $with_cas Whether to request CAS token values also.
  1295. * @param null $value_cb The result callback or null.
  1296. * @return bool True on success, false on failure.
  1297. */
  1298. public function getDelayedByKey( $server_key, $keys, $groups = 'default', $with_cas = false, $value_cb = null ) {
  1299. $derived_keys = $this->buildKeys( $keys, $groups );
  1300. return $this->m->getDelayedByKey( $server_key, $derived_keys, $with_cas, $value_cb );
  1301. }
  1302. /**
  1303. * Gets multiple values from memcached in one request.
  1304. *
  1305. * See the buildKeys method definition to understand the $keys/$groups parameters.
  1306. *
  1307. * @link https://www.php.net/manual/en/memcached.getmulti.php
  1308. *
  1309. * @param array $keys Array of keys to retrieve.
  1310. * @param string|array $groups If string, used for all keys.
  1311. * If arrays, corresponds with the $keys array.
  1312. * @param string $server_key The key identifying the server to store the value on.
  1313. * @param null|array $cas_tokens The variable to store the CAS tokens for the found items.
  1314. * @param int $flags The flags for the get operation.
  1315. * @return bool|array The array of found items on success, false on failure.
  1316. */
  1317. public function getMulti( $keys, $groups = 'default', $server_key = '', &$cas_tokens = null, $flags = null ) {
  1318. $derived_keys = $this->buildKeys( $keys, $groups );
  1319. /**
  1320. * If either $cas_tokens, or $flags is set, must hit Memcached and bypass runtime cache.
  1321. * Note that this will purposely ignore no_mc_groups values as they cannot handle CAS tokens
  1322. * or the special flags; however, if the groups of groups contains a no_mc_group, this is bypassed.
  1323. */
  1324. if ( func_num_args() > 3 && ! $this->contains_no_mc_group( $groups ) ) {
  1325. if ( ! empty( $server_key ) ) {
  1326. $values = $this->m->getMultiByKey( $server_key, $derived_keys, $cas_tokens, $flags );
  1327. } else {
  1328. $values = $this->m->getMulti( $derived_keys, $cas_tokens, $flags );
  1329. }
  1330. } else {
  1331. $values = array();
  1332. $need_to_get = array();
  1333. // Pull out values from runtime cache, or mark for retrieval.
  1334. foreach ( $derived_keys as $key ) {
  1335. if ( isset( $this->cache[ $key ] ) ) {
  1336. $values[ $key ] = $this->cache[ $key ];
  1337. } else {
  1338. $need_to_get[ $key ] = $key;
  1339. }
  1340. }
  1341. // Get those keys not found in the runtime cache.
  1342. if ( ! empty( $need_to_get ) ) {
  1343. if ( ! empty( $server_key ) ) {
  1344. $result = $this->m->getMultiByKey( $server_key, array_keys( $need_to_get ) );
  1345. } else {
  1346. $result = $this->m->getMulti( array_keys( $need_to_get ) );
  1347. }
  1348. }
  1349. // Merge with values found in runtime cache.
  1350. if ( isset( $result ) && Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1351. $values = array_merge( $values, $result );
  1352. }
  1353. // If order should be preserved, reorder now.
  1354. if ( ! empty( $need_to_get ) && Memcached::GET_PRESERVE_ORDER === $flags ) {
  1355. $ordered_values = array();
  1356. foreach ( $derived_keys as $key ) {
  1357. if ( isset( $values[ $key ] ) ) {
  1358. $ordered_values[ $key ] = $values[ $key ];
  1359. }
  1360. }
  1361. $values = $ordered_values;
  1362. unset( $ordered_values );
  1363. }
  1364. }
  1365. // Add the values to the runtime cache.
  1366. $this->cache = array_merge( $this->cache, $values );
  1367. return $values;
  1368. }
  1369. /**
  1370. * Gets multiple values from memcached in one request by specified server key.
  1371. *
  1372. * See the buildKeys method definition to understand the $keys/$groups parameters.
  1373. *
  1374. * @link https://www.php.net/manual/en/memcached.getmultibykey.php
  1375. *
  1376. * @param string $server_key The key identifying the server to store the value on.
  1377. * @param array $keys Array of keys to retrieve.
  1378. * @param string|array $groups If string, used for all keys.
  1379. * If arrays, corresponds with the $keys array.
  1380. * @param null|array $cas_tokens The variable to store the CAS tokens for the found items.
  1381. * @param int $flags The flags for the get operation.
  1382. * @return bool|array The array of found items on success, false on failure.
  1383. */
  1384. public function getMultiByKey( $server_key, $keys, $groups = 'default', &$cas_tokens = null, $flags = null ) {
  1385. /**
  1386. * Need to be careful how "getMulti" is called. If you send $cache_cb, and $cas_token, it will hit memcached.
  1387. * Only send those args if they were sent to this function.
  1388. */
  1389. if ( func_num_args() > 3 ) {
  1390. return $this->getMulti( $keys, $groups, $server_key, $cas_tokens, $flags );
  1391. } else {
  1392. return $this->getMulti( $keys, $groups, $server_key );
  1393. }
  1394. }
  1395. /**
  1396. * Retrieves a Memcached option value.
  1397. *
  1398. * @link https://www.php.net/manual/en/memcached.getoption.php
  1399. *
  1400. * @param int $option One of the Memcached::OPT_* constants.
  1401. * @return mixed The value of the requested option on success, false on failure.
  1402. */
  1403. public function getOption( $option ) {
  1404. return $this->m->getOption( $option );
  1405. }
  1406. /**
  1407. * Returns the result code of the last option.
  1408. *
  1409. * @link https://www.php.net/manual/en/memcached.getresultcode.php
  1410. *
  1411. * @return int Result code of the last Memcached operation.
  1412. */
  1413. public function getResultCode() {
  1414. return $this->m->getResultCode();
  1415. }
  1416. /**
  1417. * Return the message describing the result of the last operation.
  1418. *
  1419. * @link https://www.php.net/manual/en/memcached.getresultmessage.php
  1420. *
  1421. * @return string Message describing the result of the last Memcached operation.
  1422. */
  1423. public function getResultMessage() {
  1424. return $this->m->getResultMessage();
  1425. }
  1426. /**
  1427. * Gets server information by key.
  1428. *
  1429. * @link https://www.php.net/manual/en/memcached.getserverbykey.php
  1430. *
  1431. * @param string $server_key The key identifying the server to store the value on.
  1432. * @return array Array with host, post, and weight on success, false on failure.
  1433. */
  1434. public function getServerByKey( $server_key ) {
  1435. return $this->m->getServerByKey( $server_key );
  1436. }
  1437. /**
  1438. * Gets the list of servers in the pool.
  1439. *
  1440. * @link https://www.php.net/manual/en/memcached.getserverlist.php
  1441. *
  1442. * @return array The list of all servers in the server pool.
  1443. */
  1444. public function getServerList() {
  1445. return $this->m->getServerList();
  1446. }
  1447. /**
  1448. * Gets server pool statistics.
  1449. *
  1450. * @link https://www.php.net/manual/en/memcached.getstats.php
  1451. *
  1452. * @return array Array of server statistics, one entry per server.
  1453. */
  1454. public function getStats() {
  1455. return $this->m->getStats();
  1456. }
  1457. /**
  1458. * Gets server pool memcached version information.
  1459. *
  1460. * @link https://www.php.net/manual/en/memcached.getversion.php
  1461. *
  1462. * @return array Array of server versions, one entry per server.
  1463. */
  1464. public function getVersion() {
  1465. return $this->m->getVersion();
  1466. }
  1467. /**
  1468. * Increments a numeric item's value.
  1469. *
  1470. * @link https://www.php.net/manual/en/memcached.increment.php
  1471. *
  1472. * @param string $key The key under which to store the value.
  1473. * @param int $offset The amount by which to increment the item's value.
  1474. * @param string $group The group value appended to the $key.
  1475. * @return int|bool Item's new value on success, false on failure.
  1476. */
  1477. public function increment( $key, $offset = 1, $group = 'default' ) {
  1478. $derived_key = $this->buildKey( $key, $group );
  1479. // Increment values in no_mc_groups.
  1480. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1481. // Only increment if the key already exists and the number is currently 0 or greater (mimics memcached behavior).
  1482. if ( isset( $this->cache[ $derived_key ] ) && $this->cache[ $derived_key ] >= 0 ) {
  1483. // If numeric, add; otherwise, consider it 0 and do nothing.
  1484. if ( is_numeric( $this->cache[ $derived_key ] ) ) {
  1485. $this->cache[ $derived_key ] += (int) $offset;
  1486. } else {
  1487. $this->cache[ $derived_key ] = 0;
  1488. }
  1489. // Returned value cannot be less than 0.
  1490. if ( $this->cache[ $derived_key ] < 0 ) {
  1491. $this->cache[ $derived_key ] = 0;
  1492. }
  1493. return $this->cache[ $derived_key ];
  1494. } else {
  1495. return false;
  1496. }
  1497. }
  1498. $result = $this->m->increment( $derived_key, $offset );
  1499. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1500. $this->add_to_internal_cache( $derived_key, $result );
  1501. }
  1502. return $result;
  1503. }
  1504. /**
  1505. * Alias for $this->incr().
  1506. *
  1507. * Certain plugins expect an "incr" method on the $wp_object_cache object (e.g., Batcache).
  1508. * Since the original version of this library matched names to the memcached methods,
  1509. * the "incr" method was missing. Adding this method restores compatibility with plugins
  1510. * expecting an "incr" method.
  1511. *
  1512. * @param string $key The key under which to store the value.
  1513. * @param int $offset The amount by which to increment the item's value.
  1514. * @param string $group The group value appended to the $key.
  1515. * @return int|bool Item's new value on success, false on failure.
  1516. */
  1517. public function incr( $key, $offset = 1, $group = 'default' ) {
  1518. return $this->increment( $key, $offset, $group );
  1519. }
  1520. /**
  1521. * Prepends data to an existing item.
  1522. *
  1523. * This method should throw an error if it is used with compressed data. This is an expected behavior.
  1524. * Memcached casts the value to be prepended to the initial value to the type of the initial value.
  1525. * Be careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23
  1526. * to (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer"
  1527. * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been
  1528. * mimicked in the internal cache to produce similar results and improve consistency. It is recommended
  1529. * that prepends only occur with data of the same type.
  1530. *
  1531. * @link https://www.php.net/manual/en/memcached.prepend.php
  1532. *
  1533. * @param string $key The key under which to store the value.
  1534. * @param string $value Must be string as prepending mixed values is not well-defined.
  1535. * @param string $group The group value prepended to the $key.
  1536. * @param string $server_key The key identifying the server to store the value on.
  1537. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  1538. * @return bool True on success, false on failure.
  1539. */
  1540. public function prepend( $key, $value, $group = 'default', $server_key = '', $by_key = false ) {
  1541. if ( ! is_string( $value ) && ! is_int( $value ) && ! is_float( $value ) ) {
  1542. return false;
  1543. }
  1544. $derived_key = $this->buildKey( $key, $group );
  1545. // If group is a non-Memcached group, prepend to runtime cache value, not Memcached.
  1546. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1547. if ( ! isset( $this->cache[ $derived_key ] ) ) {
  1548. return false;
  1549. }
  1550. $combined = $this->combine_values( $this->cache[ $derived_key ], $value, 'pre' );
  1551. $this->add_to_internal_cache( $derived_key, $combined );
  1552. return true;
  1553. }
  1554. // Append to Memcached value.
  1555. if ( $by_key ) {
  1556. $result = $this->m->prependByKey( $server_key, $derived_key, $value );
  1557. } else {
  1558. $result = $this->m->prepend( $derived_key, $value );
  1559. }
  1560. // Store in runtime cache if add was successful.
  1561. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1562. $combined = $this->combine_values( $this->cache[ $derived_key ], $value, 'pre' );
  1563. $this->add_to_internal_cache( $derived_key, $combined );
  1564. }
  1565. return $result;
  1566. }
  1567. /**
  1568. * Appends data to an existing item by server key.
  1569. *
  1570. * This method should throw an error if it is used with compressed data. This is an expected behavior.
  1571. * Memcached casts the value to be prepended to the initial value to the type of the initial value.
  1572. * Be careful as this leads to unexpected behavior at times. For instance, prepending (float) 45.23
  1573. * to (int) 23 will result in 45, because the value is first combined (45.2323) then cast to "integer"
  1574. * (the original value), which will be (int) 45. Due to how memcached treats types, the behavior has been
  1575. * mimicked in the internal cache to produce similar results and improve consistency. It is recommended
  1576. * that prepends only occur with data of the same type.
  1577. *
  1578. * @link https://www.php.net/manual/en/memcached.prependbykey.php
  1579. *
  1580. * @param string $server_key The key identifying the server to store the value on.
  1581. * @param string $key The key under which to store the value.
  1582. * @param string $value Must be string as prepending mixed values is not well-defined.
  1583. * @param string $group The group value prepended to the $key.
  1584. * @return bool True on success, false on failure.
  1585. */
  1586. public function prependByKey( $server_key, $key, $value, $group = 'default' ) {
  1587. return $this->prepend( $key, $value, $group, $server_key, true );
  1588. }
  1589. /**
  1590. * Replaces a value in cache.
  1591. *
  1592. * This method is similar to "add"; however, is does not successfully set a value
  1593. * if the object's key is not already set in cache.
  1594. *
  1595. * @link https://www.php.net/manual/en/memcached.replace.php
  1596. *
  1597. * @param string $server_key The key identifying the server to store the value on.
  1598. * @param string $key The key under which to store the value.
  1599. * @param mixed $value The value to store.
  1600. * @param string $group The group value appended to the $key.
  1601. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  1602. * @param int $expiration The expiration time, defaults to 0.
  1603. * @return bool True on success, false on failure.
  1604. */
  1605. public function replace( $key, $value, $group = 'default', $expiration = 0, $server_key = '', $by_key = false ) {
  1606. $derived_key = $this->buildKey( $key, $group );
  1607. $expiration = $this->sanitize_expiration( $expiration );
  1608. // If group is a non-Memcached group, save to runtime cache, not Memcached.
  1609. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1610. // Replace won't save unless the key already exists; mimic this behavior here.
  1611. if ( ! isset( $this->cache[ $derived_key ] ) ) {
  1612. return false;
  1613. }
  1614. $this->cache[ $derived_key ] = $value;
  1615. return true;
  1616. }
  1617. // Save to Memcached.
  1618. if ( $by_key ) {
  1619. $result = $this->m->replaceByKey( $server_key, $derived_key, $value, $expiration );
  1620. } else {
  1621. $result = $this->m->replace( $derived_key, $value, $expiration );
  1622. }
  1623. // Store in runtime cache if add was successful.
  1624. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1625. $this->add_to_internal_cache( $derived_key, $value );
  1626. }
  1627. return $result;
  1628. }
  1629. /**
  1630. * Replaces a value in cache on a specific server.
  1631. *
  1632. * This method is similar to "addByKey"; however, is does not successfully set a value
  1633. * if the object's key is not already set in cache.
  1634. *
  1635. * @link https://www.php.net/manual/en/memcached.addbykey.php
  1636. *
  1637. * @param string $server_key The key identifying the server to store the value on.
  1638. * @param string $key The key under which to store the value.
  1639. * @param mixed $value The value to store.
  1640. * @param string $group The group value appended to the $key.
  1641. * @param int $expiration The expiration time, defaults to 0.
  1642. * @return bool True on success, false on failure.
  1643. */
  1644. public function replaceByKey( $server_key, $key, $value, $group = 'default', $expiration = 0 ) {
  1645. return $this->replace( $key, $value, $group, $expiration, $server_key, true );
  1646. }
  1647. /**
  1648. * Sets a value in cache.
  1649. *
  1650. * The value is set whether or not this key already exists in memcached.
  1651. *
  1652. * @link https://www.php.net/manual/en/memcached.set.php
  1653. *
  1654. * @param string $key The key under which to store the value.
  1655. * @param mixed $value The value to store.
  1656. * @param string $group The group value appended to the $key.
  1657. * @param int $expiration The expiration time, defaults to 0.
  1658. * @param string $server_key The key identifying the server to store the value on.
  1659. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  1660. * @return bool True on success, false on failure.
  1661. */
  1662. public function set( $key, $value, $group = 'default', $expiration = 0, $server_key = '', $by_key = false ) {
  1663. $derived_key = $this->buildKey( $key, $group );
  1664. $expiration = $this->sanitize_expiration( $expiration );
  1665. // If group is a non-Memcached group, save to runtime cache, not Memcached.
  1666. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1667. $this->add_to_internal_cache( $derived_key, $value );
  1668. return true;
  1669. }
  1670. // Save to Memcached.
  1671. if ( $by_key ) {
  1672. $result = $this->m->setByKey( $server_key, $derived_key, $value, $expiration );
  1673. } else {
  1674. $result = $this->m->set( $derived_key, $value, $expiration );
  1675. }
  1676. // Store in runtime cache if add was successful.
  1677. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1678. $this->add_to_internal_cache( $derived_key, $value );
  1679. }
  1680. return $result;
  1681. }
  1682. /**
  1683. * Sets a value in cache on a specific server.
  1684. *
  1685. * The value is set whether or not this key already exists in memcached.
  1686. *
  1687. * @link https://www.php.net/manual/en/memcached.setbykey.php
  1688. *
  1689. * @param string $server_key The key identifying the server to store the value on.
  1690. * @param string $key The key under which to store the value.
  1691. * @param mixed $value The value to store.
  1692. * @param string $group The group value appended to the $key.
  1693. * @param int $expiration The expiration time, defaults to 0.
  1694. * @return bool True on success, false on failure.
  1695. */
  1696. public function setByKey( $server_key, $key, $value, $group = 'default', $expiration = 0 ) {
  1697. return $this->set( $key, $value, $group, $expiration, $server_key, true );
  1698. }
  1699. /**
  1700. * Sets multiple values to cache at once.
  1701. *
  1702. * By sending an array of $items to this function, all values are saved at once to
  1703. * memcached, reducing the need for multiple requests to memcached. The $items array
  1704. * keys and values are what are stored to memcached. The keys in the $items array
  1705. * are merged with the $groups array/string value via buildKeys to determine the
  1706. * final key for the object.
  1707. *
  1708. * @link https://www.php.net/manual/en/memcached.setmulti.php
  1709. *
  1710. * @param array $items An array of key/value pairs to store on the server.
  1711. * @param string|array $groups Group(s) to merge with key(s) in $items.
  1712. * @param int $expiration The expiration time, defaults to 0.
  1713. * @param string $server_key The key identifying the server to store the value on.
  1714. * @param bool $by_key True to store in internal cache by key; false to not store by key.
  1715. * @return bool True on success, false on failure.
  1716. */
  1717. public function setMulti( $items, $groups = 'default', $expiration = 0, $server_key = '', $by_key = false ) {
  1718. // Build final keys and replace $items keys with the new keys.
  1719. $derived_keys = $this->buildKeys( array_keys( $items ), $groups );
  1720. $expiration = $this->sanitize_expiration( $expiration );
  1721. $derived_items = array_combine( $derived_keys, $items );
  1722. // Do not add to memcached if in no_mc_groups.
  1723. foreach ( $derived_items as $derived_key => $value ) {
  1724. // Get the individual item's group.
  1725. $key_pieces = explode( ':', $derived_key );
  1726. // If group is a non-Memcached group, save to runtime cache, not Memcached.
  1727. if ( in_array( $key_pieces[1], $this->no_mc_groups, true ) ) {
  1728. $this->add_to_internal_cache( $derived_key, $value );
  1729. unset( $derived_items[ $derived_key ] );
  1730. }
  1731. }
  1732. // Save to memcached.
  1733. if ( $by_key ) {
  1734. $result = $this->m->setMultiByKey( $server_key, $derived_items, $expiration );
  1735. } else {
  1736. $result = $this->m->setMulti( $derived_items, $expiration );
  1737. }
  1738. // Store in runtime cache if add was successful.
  1739. if ( Memcached::RES_SUCCESS === $this->getResultCode() ) {
  1740. $this->cache = array_merge( $this->cache, $derived_items );
  1741. }
  1742. return $result;
  1743. }
  1744. /**
  1745. * Sets multiple values to cache at once on specified server.
  1746. *
  1747. * By sending an array of $items to this function, all values are saved at once to
  1748. * memcached, reducing the need for multiple requests to memcached. The $items array
  1749. * keys and values are what are stored to memcached. The keys in the $items array
  1750. * are merged with the $groups array/string value via buildKeys to determine the
  1751. * final key for the object.
  1752. *
  1753. * @link https://www.php.net/manual/en/memcached.setmultibykey.php
  1754. *
  1755. * @param string $server_key The key identifying the server to store the value on.
  1756. * @param array $items An array of key/value pairs to store on the server.
  1757. * @param string|array $groups Group(s) to merge with key(s) in $items.
  1758. * @param int $expiration The expiration time, defaults to 0.
  1759. * @return bool True on success, false on failure.
  1760. */
  1761. public function setMultiByKey( $server_key, $items, $groups = 'default', $expiration = 0 ) {
  1762. return $this->setMulti( $items, $groups, $expiration, $server_key, true );
  1763. }
  1764. /**
  1765. * Sets a Memcached option.
  1766. *
  1767. * @link https://www.php.net/manual/en/memcached.setoption.php
  1768. *
  1769. * @param int $option Option name.
  1770. * @param mixed $value Option value.
  1771. * @return bool True on success, false on failure.
  1772. */
  1773. public function setOption( $option, $value ) {
  1774. return $this->m->setOption( $option, $value );
  1775. }
  1776. /**
  1777. * Builds a key for the cached object using the blog_id, key, and group values.
  1778. *
  1779. * This function is inspired by the original WP Memcached Object cache.
  1780. *
  1781. * @author Ryan Boren
  1782. * @link http://wordpress.org/extend/plugins/memcached/
  1783. *
  1784. * @param string $key The key under which to store the value.
  1785. * @param string $group The group value appended to the $key.
  1786. * @return string
  1787. */
  1788. public function buildKey( $key, $group = 'default' ) {
  1789. if ( empty( $group ) ) {
  1790. $group = 'default';
  1791. }
  1792. if ( false !== array_search( $group, $this->global_groups, true ) ) {
  1793. $prefix = $this->global_prefix;
  1794. } else {
  1795. $prefix = $this->blog_prefix;
  1796. }
  1797. return preg_replace( '/\s+/', '', WP_CACHE_KEY_SALT . "$prefix$group:$key" );
  1798. }
  1799. /**
  1800. * Creates an array of keys from passed key(s) and group(s).
  1801. *
  1802. * This function takes a string or array of key(s) and group(s) and combines them into a single dimensional
  1803. * array that merges the keys and groups. If the same number of keys and groups exist, the final keys will
  1804. * append $groups[n] to $keys[n]. If there are more keys than groups and the $groups parameter is an array,
  1805. * $keys[n] will be combined with $groups[n] until $groups runs out of values. 'default' will be used for remaining
  1806. * values. If $keys is an array and $groups is a string, all final values will append $groups to $keys[n].
  1807. * If both values are strings, they will be combined into a single string. Note that if more $groups are received
  1808. * than $keys, the method will return an empty array. This method is primarily a helper method for methods
  1809. * that call memcached with an array of keys.
  1810. *
  1811. * @param string|array $keys Key(s) to merge with group(s).
  1812. * @param string|array $groups Group(s) to merge with key(s).
  1813. * @return array Array that combines keys and groups into a single set of memcached keys.
  1814. */
  1815. public function buildKeys( $keys, $groups = 'default' ) {
  1816. $derived_keys = array();
  1817. // If strings sent, convert to arrays for proper handling.
  1818. if ( ! is_array( $groups ) ) {
  1819. $groups = (array) $groups;
  1820. }
  1821. if ( ! is_array( $keys ) ) {
  1822. $keys = (array) $keys;
  1823. }
  1824. // If we have equal numbers of keys and groups, merge $keys[n] and $group[n].
  1825. if ( count( $keys ) === count( $groups ) ) {
  1826. for ( $i = 0; $i < count( $keys ); $i++ ) {
  1827. $derived_keys[] = $this->buildKey( $keys[ $i ], $groups[ $i ] );
  1828. }
  1829. // If more keys are received than groups, merge $keys[n] and $group[n]
  1830. // until no more groups are left; remaining groups are 'default'.
  1831. } elseif ( count( $keys ) > count( $groups ) ) {
  1832. for ( $i = 0; $i < count( $keys ); $i++ ) {
  1833. if ( isset( $groups[ $i ] ) ) {
  1834. $derived_keys[] = $this->buildKey( $keys[ $i ], $groups[ $i ] );
  1835. } elseif ( count( $groups ) === 1 ) {
  1836. $derived_keys[] = $this->buildKey( $keys[ $i ], $groups[0] );
  1837. } else {
  1838. $derived_keys[] = $this->buildKey( $keys[ $i ], 'default' );
  1839. }
  1840. }
  1841. }
  1842. return $derived_keys;
  1843. }
  1844. /**
  1845. * Ensures that a proper expiration time is set.
  1846. *
  1847. * Memcached treats any value over 30 days as a timestamp. If a developer sets the expiration
  1848. * for greater than 30 days or less than the current timestamp, the timestamp is in the past
  1849. * and the value isn't cached. This function detects values in that range and corrects them.
  1850. *
  1851. * @param string|int $expiration The dirty expiration time.
  1852. * @return string|int The sanitized expiration time.
  1853. */
  1854. public function sanitize_expiration( $expiration ) {
  1855. if ( $expiration > $this->thirty_days && $expiration <= $this->now ) {
  1856. $expiration = $expiration + $this->now;
  1857. }
  1858. return $expiration;
  1859. }
  1860. /**
  1861. * Concatenates two values and casts to type of the first value.
  1862. *
  1863. * This is used in append and prepend operations to match how these functions are handled
  1864. * by memcached. In both cases, whichever value is the original value in the combined value
  1865. * will dictate the type of the combined value.
  1866. *
  1867. * @param mixed $original Original value that dictates the combined type.
  1868. * @param mixed $pended Value to combine with original value.
  1869. * @param string $direction Either 'pre' or 'app'.
  1870. * @return mixed Combined value casted to the type of the first value.
  1871. */
  1872. public function combine_values( $original, $pended, $direction ) {
  1873. $type = gettype( $original );
  1874. // Combine the values based on direction of the "pend".
  1875. if ( 'pre' === $direction ) {
  1876. $combined = $pended . $original;
  1877. } else {
  1878. $combined = $original . $pended;
  1879. }
  1880. // Cast type of combined value.
  1881. settype( $combined, $type );
  1882. return $combined;
  1883. }
  1884. /**
  1885. * Simple wrapper for saving object to the internal cache.
  1886. *
  1887. * @param string $derived_key Key to save value under.
  1888. * @param mixed $value Object value.
  1889. */
  1890. public function add_to_internal_cache( $derived_key, $value ) {
  1891. if ( is_object( $value ) ) {
  1892. $value = clone $value;
  1893. }
  1894. $this->cache[ $derived_key ] = $value;
  1895. }
  1896. /**
  1897. * Determines if a no_mc_group exists in a group of groups.
  1898. *
  1899. * @param mixed $groups The groups to search.
  1900. * @return bool True if a no_mc_group is present; false if a no_mc_group is not present.
  1901. */
  1902. public function contains_no_mc_group( $groups ) {
  1903. if ( is_scalar( $groups ) ) {
  1904. return in_array( $groups, $this->no_mc_groups, true );
  1905. }
  1906. if ( ! is_array( $groups ) ) {
  1907. return false;
  1908. }
  1909. foreach ( $groups as $group ) {
  1910. if ( in_array( $group, $this->no_mc_groups, true ) ) {
  1911. return true;
  1912. }
  1913. }
  1914. return false;
  1915. }
  1916. /**
  1917. * Adds global groups.
  1918. *
  1919. * This function comes straight from the original WP Memcached Object cache.
  1920. *
  1921. * @author Ryan Boren
  1922. * @link http://wordpress.org/extend/plugins/memcached/
  1923. *
  1924. * @param array $groups Array of groups.
  1925. * @return void
  1926. */
  1927. public function add_global_groups( $groups ) {
  1928. if ( ! is_array( $groups ) ) {
  1929. $groups = (array) $groups;
  1930. }
  1931. $this->global_groups = array_merge( $this->global_groups, $groups );
  1932. $this->global_groups = array_unique( $this->global_groups );
  1933. }
  1934. /**
  1935. * Adds non-persistent groups.
  1936. *
  1937. * This function comes straight from the original WP Memcached Object cache.
  1938. *
  1939. * @author Ryan Boren
  1940. * @link http://wordpress.org/extend/plugins/memcached/
  1941. *
  1942. * @param array $groups Array of groups.
  1943. * @return void
  1944. */
  1945. public function add_non_persistent_groups( $groups ) {
  1946. if ( ! is_array( $groups ) ) {
  1947. $groups = (array) $groups;
  1948. }
  1949. $this->no_mc_groups = array_merge( $this->no_mc_groups, $groups );
  1950. $this->no_mc_groups = array_unique( $this->no_mc_groups );
  1951. }
  1952. /**
  1953. * Gets a value specifically from the internal, run-time cache, not memcached.
  1954. *
  1955. * @param int|string $key Key value.
  1956. * @param int|string $group Group that the value belongs to.
  1957. * @return bool|mixed Value on success, false on failure.
  1958. */
  1959. public function get_from_runtime_cache( $key, $group ) {
  1960. $derived_key = $this->buildKey( $key, $group );
  1961. if ( isset( $this->cache[ $derived_key ] ) ) {
  1962. return $this->cache[ $derived_key ];
  1963. }
  1964. return false;
  1965. }
  1966. /**
  1967. * Switches blog prefix, which changes the cache that is accessed.
  1968. *
  1969. * @param int $blog_id Blog to switch to.
  1970. * @return void
  1971. */
  1972. public function switch_to_blog( $blog_id ) {
  1973. global $table_prefix;
  1974. $blog_id = (int) $blog_id;
  1975. $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ) . ':';
  1976. }
  1977. }
  1978. // phpcs:enable