Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]

   1  <?php
   2  /**
   3   * Memory caching.
   4   *
   5   * This file is part of ADOdb, a Database Abstraction Layer library for PHP.
   6   *
   7   * @package ADOdb
   8   * @link https://adodb.org Project's web site and documentation
   9   * @link https://github.com/ADOdb/ADOdb Source code and issue tracker
  10   *
  11   * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
  12   * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
  13   * any later version. This means you can use it in proprietary products.
  14   * See the LICENSE.md file distributed with this source code for details.
  15   * @license BSD-3-Clause
  16   * @license LGPL-2.1-or-later
  17   *
  18   * @copyright 2000-2013 John Lim
  19   * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
  20   */
  21  
  22  // security - hide paths
  23  if (!defined('ADODB_DIR')) die();
  24  
  25  global $ADODB_INCLUDED_MEMCACHE;
  26  $ADODB_INCLUDED_MEMCACHE = 1;
  27  
  28  global $ADODB_INCLUDED_CSV;
  29  if (empty($ADODB_INCLUDED_CSV)) include_once (ADODB_DIR.'/adodb-csvlib.inc.php');
  30  
  31  	 class ADODB_Cache_MemCache {
  32  	 	 var $createdir = false; // create caching directory structure?
  33  
  34  	 	 // $library will be populated with the proper library on connect
  35  	 	 // and is used later when there are differences in specific calls
  36  	 	 // between memcache and memcached
  37  	 	 var $library = false;
  38  
  39  	 	 //-----------------------------
  40  	 	 // memcache specific variables
  41  
  42  	 	 var $hosts;	 // array of hosts
  43  	 	 var $port = 11211;
  44  	 	 var $compress = false; // memcache compression with zlib
  45  
  46  	 	 var $_connected = false;
  47  	 	 var $_memcache = false;
  48  
  49  		function __construct(&$obj)
  50  	 	 {
  51  	 	 	 $this->hosts = $obj->memCacheHost;
  52  	 	 	 $this->port = $obj->memCachePort;
  53  	 	 	 $this->compress = $obj->memCacheCompress;
  54  	 	 }
  55  
  56  	 	 // implement as lazy connection. The connection only occurs on CacheExecute call
  57  		function connect(&$err)
  58  	 	 {
  59  	 	 	 // do we have memcache or memcached?
  60  	 	 	 if (class_exists('Memcache')) {
  61  	 	 	 	 $this->library='Memcache';
  62  	 	 	 	 $memcache = new MemCache;
  63  	 	 	 } elseif (class_exists('Memcached')) {
  64  	 	 	 	 $this->library='Memcached';
  65  	 	 	 	 $memcache = new MemCached;
  66  	 	 	 } else {
  67  	 	 	 	 $err = 'Neither the Memcache nor Memcached PECL extensions were found!';
  68  	 	 	 	 return false;
  69  	 	 	 }
  70  
  71  	 	 	 if (!is_array($this->hosts)) $this->hosts = array($this->hosts);
  72  
  73  	 	 	 $failcnt = 0;
  74  	 	 	 foreach($this->hosts as $host) {
  75  	 	 	 	 if (!@$memcache->addServer($host,$this->port)) {
  76  	 	 	 	 	 $failcnt += 1;
  77  	 	 	 	 }
  78  	 	 	 }
  79  	 	 	 if ($failcnt == sizeof($this->hosts)) {
  80  	 	 	 	 $err = 'Can\'t connect to any memcache server';
  81  	 	 	 	 return false;
  82  	 	 	 }
  83  	 	 	 $this->_connected = true;
  84  	 	 	 $this->_memcache = $memcache;
  85  	 	 	 return true;
  86  	 	 }
  87  
  88  	 	 // returns true or false. true if successful save
  89  		function writecache($filename, $contents, $debug, $secs2cache)
  90  	 	 {
  91  	 	 	 if (!$this->_connected) {
  92  	 	 	 	 $err = '';
  93  	 	 	 	 if (!$this->connect($err) && $debug) ADOConnection::outp($err);
  94  	 	 	 }
  95  	 	 	 if (!$this->_memcache) return false;
  96  
  97  	 	 	 $failed=false;
  98  	 	 	 switch ($this->library) {
  99  	 	 	 	 case 'Memcache':
 100  	 	 	 	 	 if (!$this->_memcache->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) {
 101  	 	 	 	 	 	 $failed=true;
 102  	 	 	 	 	 }
 103  	 	 	 	 	 break;
 104  	 	 	 	 case 'Memcached':
 105  	 	 	 	 	 if (!$this->_memcache->set($filename, $contents, $secs2cache)) {
 106  	 	 	 	 	 	 $failed=true;
 107  	 	 	 	 	 }
 108  	 	 	 	 	 break;
 109  	 	 	 	 default:
 110  	 	 	 	 	 $failed=true;
 111  	 	 	 	 	 break;
 112  	 	 	 }
 113  
 114  	 	 	 if($failed) {
 115  	 	 	 	 if ($debug) ADOConnection::outp(" Failed to save data at the memcache server!<br>\n");
 116  	 	 	 	 return false;
 117  	 	 	 }
 118  
 119  	 	 	 return true;
 120  	 	 }
 121  
 122  	 	 // returns a recordset
 123  		function readcache($filename, &$err, $secs2cache, $rsClass)
 124  	 	 {
 125  	 	 	 $false = false;
 126  	 	 	 if (!$this->_connected) $this->connect($err);
 127  	 	 	 if (!$this->_memcache) return $false;
 128  
 129  	 	 	 $rs = $this->_memcache->get($filename);
 130  	 	 	 if (!$rs) {
 131  	 	 	 	 $err = 'Item with such key doesn\'t exist on the memcache server.';
 132  	 	 	 	 return $false;
 133  	 	 	 }
 134  
 135  	 	 	 // hack, should actually use _csv2rs
 136  	 	 	 $rs = explode("\n", $rs);
 137              unset($rs[0]);
 138              $rs = join("\n", $rs);
 139   	 	 	 $rs = unserialize($rs);
 140  	 	 	 if (! is_object($rs)) {
 141  	 	 	 	 $err = 'Unable to unserialize $rs';
 142  	 	 	 	 return $false;
 143  	 	 	 }
 144  	 	 	 if ($rs->timeCreated == 0) return $rs; // apparently have been reports that timeCreated was set to 0 somewhere
 145  
 146  	 	 	 $tdiff = intval($rs->timeCreated+$secs2cache - time());
 147  	 	 	 if ($tdiff <= 2) {
 148  	 	 	 	 switch($tdiff) {
 149  	 	 	 	 	 case 2:
 150  	 	 	 	 	 	 if ((rand() & 15) == 0) {
 151  	 	 	 	 	 	 	 $err = "Timeout 2";
 152  	 	 	 	 	 	 	 return $false;
 153  	 	 	 	 	 	 }
 154  	 	 	 	 	 	 break;
 155  	 	 	 	 	 case 1:
 156  	 	 	 	 	 	 if ((rand() & 3) == 0) {
 157  	 	 	 	 	 	 	 $err = "Timeout 1";
 158  	 	 	 	 	 	 	 return $false;
 159  	 	 	 	 	 	 }
 160  	 	 	 	 	 	 break;
 161  	 	 	 	 	 default:
 162  	 	 	 	 	 	 $err = "Timeout 0";
 163  	 	 	 	 	 	 return $false;
 164  	 	 	 	 }
 165  	 	 	 }
 166  	 	 	 return $rs;
 167  	 	 }
 168  
 169  		function flushall($debug=false)
 170  	 	 {
 171  	 	 	 if (!$this->_connected) {
 172  	 	 	 	 $err = '';
 173  	 	 	 	 if (!$this->connect($err) && $debug) ADOConnection::outp($err);
 174  	 	 	 }
 175  	 	 	 if (!$this->_memcache) return false;
 176  
 177  	 	 	 $del = $this->_memcache->flush();
 178  
 179  	 	 	 if ($debug)
 180  	 	 	 	 if (!$del) ADOConnection::outp("flushall: failed!<br>\n");
 181  	 	 	 	 else ADOConnection::outp("flushall: succeeded!<br>\n");
 182  
 183  	 	 	 return $del;
 184  	 	 }
 185  
 186  		function flushcache($filename, $debug=false)
 187  	 	 {
 188  	 	 	 if (!$this->_connected) {
 189    	 	 	 	 $err = '';
 190    	 	 	 	 if (!$this->connect($err) && $debug) ADOConnection::outp($err);
 191  	 	 	 }
 192  	 	 	 if (!$this->_memcache) return false;
 193  
 194  	 	 	 $del = $this->_memcache->delete($filename);
 195  
 196  	 	 	 if ($debug)
 197  	 	 	 	 if (!$del) ADOConnection::outp("flushcache: $key entry doesn't exist on memcache server!<br>\n");
 198  	 	 	 	 else ADOConnection::outp("flushcache: $key entry flushed from memcache server!<br>\n");
 199  
 200  	 	 	 return $del;
 201  	 	 }
 202  
 203  	 	 // not used for memcache
 204  		function createdir($dir, $hash)
 205  	 	 {
 206  	 	 	 return true;
 207  	 	 }
 208  	 }