dolibarr  16.0.5
memory.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2009-2010 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2021 Frédéric France <frederic.france@netlogic.fr>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  * or see https://www.gnu.org/
18  */
19 
25 global $shmkeys, $shmoffset;
26 
27 $shmkeys = array(
28  'main' => 1,
29  'admin' => 2,
30  'dict' => 3,
31  'companies' => 4,
32  'suppliers' => 5,
33  'products' => 6,
34  'commercial' => 7,
35  'compta' => 8,
36  'projects' => 9,
37  'cashdesk' => 10,
38  'agenda' => 11,
39  'bills' => 12,
40  'propal' => 13,
41  'boxes' => 14,
42  'banks' => 15,
43  'other' => 16,
44  'errors' => 17,
45  'members' => 18,
46  'ecm' => 19,
47  'orders' => 20,
48  'users' => 21,
49  'help' => 22,
50  'stocks' => 23,
51  'interventions' => 24,
52  'donations' => 25,
53  'contracts' => 26,
54 );
55 $shmoffset = 1000; // Max number of entries found into a language file. If too low, some entries will be overwritten.
56 
57 
58 
68 function dol_setcache($memoryid, $data, $expire = 0)
69 {
70  global $conf;
71  $result = 0;
72 
73  if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
74  if (empty($conf->global->MAIN_CACHE_COUNT)) {
75  return 0;
76  }
77  }
78 
79  if (!empty($conf->memcached->enabled) && class_exists('Memcached')) {
80  // Using a memcached server
81  global $dolmemcache;
82  if (empty($dolmemcache) || !is_object($dolmemcache)) {
83  $dolmemcache = new Memcached();
84  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
85  $result = $dolmemcache->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
86  if (!$result) {
87  return -1;
88  }
89  }
90 
91  $memoryid = session_name().'_'.$memoryid;
92  //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
93  $dolmemcache->add($memoryid, $data, $expire); // This fails if key already exists
94  $rescode = $dolmemcache->getResultCode();
95  if ($rescode == 0) {
96  return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
97  } else {
98  return -$rescode;
99  }
100  } elseif (!empty($conf->memcached->enabled) && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
101  // Using a memcache server
102  global $dolmemcache;
103  if (empty($dolmemcache) || !is_object($dolmemcache)) {
104  $dolmemcache = new Memcache();
105  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
106  $result = $dolmemcache->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
107  if (!$result) {
108  return -1;
109  }
110  }
111 
112  $memoryid = session_name().'_'.$memoryid;
113  //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
114  $result = $dolmemcache->add($memoryid, $data, false, $expire); // This fails if key already exists
115  if ($result) {
116  return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
117  } else {
118  return -1;
119  }
120  } elseif (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x02)) { // This is a really not reliable cache ! Use Memcached instead.
121  // Using shmop
122  $result = dol_setshmop($memoryid, $data, $expire);
123  }
124 
125  return $result;
126 }
127 
135 function dol_getcache($memoryid)
136 {
137  global $conf;
138 
139  if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
140  if (empty($conf->global->MAIN_CACHE_COUNT)) {
141  return null;
142  }
143  }
144 
145  // Using a memcached server
146  if (!empty($conf->memcached->enabled) && class_exists('Memcached')) {
147  global $m;
148  if (empty($m) || !is_object($m)) {
149  $m = new Memcached();
150  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
151  $result = $m->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
152  if (!$result) {
153  return -1;
154  }
155  }
156 
157  $memoryid = session_name().'_'.$memoryid;
158  //$m->setOption(Memcached::OPT_COMPRESSION, false);
159  //print "Get memoryid=".$memoryid;
160  $data = $m->get($memoryid);
161  $rescode = $m->getResultCode();
162  //print "memoryid=".$memoryid." - rescode=".$rescode." - count(response)=".count($data)."\n<br>";
163  //var_dump($data);
164  if ($rescode == 0) {
165  return $data;
166  } elseif ($rescode == 16) { // = Memcached::MEMCACHED_NOTFOUND but this constant doe snot exists.
167  return null;
168  } else {
169  return -$rescode;
170  }
171  } elseif (!empty($conf->memcached->enabled) && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
172  global $m;
173  if (empty($m) || !is_object($m)) {
174  $m = new Memcache();
175  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
176  $result = $m->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
177  if (!$result) {
178  return -1;
179  }
180  }
181 
182  $memoryid = session_name().'_'.$memoryid;
183  //$m->setOption(Memcached::OPT_COMPRESSION, false);
184  $data = $m->get($memoryid);
185  //print "memoryid=".$memoryid." - rescode=".$rescode." - data=".count($data)."\n<br>";
186  //var_dump($data);
187  if ($data) {
188  return $data;
189  } else {
190  return null; // There is no way to make a difference between NOTFOUND and error when using Memcache. So do not use it, use Memcached instead.
191  }
192  } elseif (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x02)) { // This is a really not reliable cache ! Use Memcached instead.
193  // Using shmop
194  $data = dol_getshmop($memoryid);
195  return $data;
196  }
197 
198  return null;
199 }
200 
201 
202 
209 function dol_getshmopaddress($memoryid)
210 {
211  global $shmkeys, $shmoffset;
212  if (empty($shmkeys[$memoryid])) { // No room reserved for thid memoryid, no way to use cache
213  return 0;
214  }
215  return $shmkeys[$memoryid] + $shmoffset;
216 }
217 
223 function dol_listshmop()
224 {
225  global $shmkeys, $shmoffset;
226 
227  $resarray = array();
228  foreach ($shmkeys as $key => $val) {
229  $result = dol_getshmop($key);
230  if (!is_numeric($result) || $result > 0) {
231  $resarray[$key] = $result;
232  }
233  }
234  return $resarray;
235 }
236 
245 function dol_setshmop($memoryid, $data, $expire)
246 {
247  global $shmkeys, $shmoffset;
248 
249  //print 'dol_setshmop memoryid='.$memoryid."<br>\n";
250  if (empty($shmkeys[$memoryid]) || !function_exists("shmop_write")) {
251  return 0;
252  }
253  $shmkey = dol_getshmopaddress($memoryid);
254  if (empty($shmkey)) {
255  return 0; // No key reserved for this memoryid, we can't cache this memoryid
256  }
257 
258  $newdata = serialize($data);
259  $size = strlen($newdata);
260  //print 'dol_setshmop memoryid='.$memoryid." shmkey=".$shmkey." newdata=".$size."bytes<br>\n";
261  $handle = shmop_open($shmkey, 'c', 0644, 6 + $size);
262  if ($handle) {
263  $shm_bytes_written1 = shmop_write($handle, str_pad($size, 6), 0);
264  $shm_bytes_written2 = shmop_write($handle, $newdata, 6);
265  if (($shm_bytes_written1 + $shm_bytes_written2) != (6 + dol_strlen($newdata))) {
266  print "Couldn't write the entire length of data\n";
267  }
268  shmop_close($handle);
269  return ($shm_bytes_written1 + $shm_bytes_written2);
270  } else {
271  print 'Error in shmop_open for memoryid='.$memoryid.' shmkey='.$shmkey.' 6+size=6+'.$size;
272  return -1;
273  }
274 }
275 
282 function dol_getshmop($memoryid)
283 {
284  global $shmkeys, $shmoffset;
285 
286  $data = null;
287 
288  if (empty($shmkeys[$memoryid]) || !function_exists("shmop_open")) {
289  return null;
290  }
291  $shmkey = dol_getshmopaddress($memoryid);
292  if (empty($shmkey)) {
293  return null; // No key reserved for this memoryid, we can't cache this memoryid
294  }
295 
296  //print 'dol_getshmop memoryid='.$memoryid." shmkey=".$shmkey."<br>\n";
297  $handle = @shmop_open($shmkey, 'a', 0, 0);
298  if ($handle) {
299  $size = trim(shmop_read($handle, 0, 6));
300  if ($size) {
301  $data = unserialize(shmop_read($handle, 6, $size));
302  } else {
303  return -1;
304  }
305  shmop_close($handle);
306  } else {
307  return null; // Can't open existing block, so we suppose it was not created, so nothing were cached yet for the memoryid
308  }
309  return $data;
310 }
dol_setcache
dol_setcache($memoryid, $data, $expire=0)
Save data into a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:68
dol_getcache
dol_getcache($memoryid)
Read a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:135
dol_getshmop
dol_getshmop($memoryid)
Read a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:282
dol_getshmopaddress
dol_getshmopaddress($memoryid)
Return shared memory address used to store dataset with key memoryid.
Definition: memory.lib.php:209
dol_setshmop
dol_setshmop($memoryid, $data, $expire)
Save data into a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:245
dol_strlen
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
Definition: functions.lib.php:3747
dol_listshmop
dol_listshmop()
Return list of contents of all memory area shared.
Definition: memory.lib.php:223