dolibarr  20.0.0-beta
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  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  * or see https://www.gnu.org/
19  */
20 
26 global $shmkeys, $shmoffset;
27 
28 $shmkeys = array(
29  'main' => 1,
30  'admin' => 2,
31  'dict' => 3,
32  'companies' => 4,
33  'suppliers' => 5,
34  'products' => 6,
35  'commercial' => 7,
36  'compta' => 8,
37  'projects' => 9,
38  'cashdesk' => 10,
39  'agenda' => 11,
40  'bills' => 12,
41  'propal' => 13,
42  'boxes' => 14,
43  'banks' => 15,
44  'other' => 16,
45  'errors' => 17,
46  'members' => 18,
47  'ecm' => 19,
48  'orders' => 20,
49  'users' => 21,
50  'help' => 22,
51  'stocks' => 23,
52  'interventions' => 24,
53  'donations' => 25,
54  'contracts' => 26,
55 );
56 $shmoffset = 1000; // Max number of entries found into a language file. If too low, some entries will be overwritten.
57 
58 
59 
69 function dol_setcache($memoryid, $data, $expire = 0)
70 {
71  global $conf;
72 
73  $result = 0;
74 
75  if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
76  if (!getDolGlobalString('MAIN_CACHE_COUNT')) {
77  return 0;
78  }
79  }
80 
81  if (isModEnabled('memcached') && class_exists('Memcached')) {
82  // Using a memcached server
83  global $dolmemcache;
84  if (empty($dolmemcache) || !is_object($dolmemcache)) {
85  $dolmemcache = new Memcached();
86  $tmparray = explode(':', getDolGlobalString('MEMCACHED_SERVER'));
87  $result = $dolmemcache->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
88  if (!$result) {
89  return -1;
90  }
91  }
92 
93  $memoryid = session_name().'_'.$memoryid;
94  //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
95  $dolmemcache->add($memoryid, $data, $expire); // This fails if key already exists
96  $rescode = $dolmemcache->getResultCode();
97  if ($rescode == 0) {
98  return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
99  } else {
100  return -$rescode;
101  }
102  } elseif (isModEnabled('memcached') && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
103  // Using a memcache server
104  global $dolmemcache;
105  if (empty($dolmemcache) || !is_object($dolmemcache)) {
106  $dolmemcache = new Memcache();
107  $tmparray = explode(':', getDolGlobalString('MEMCACHED_SERVER'));
108  $result = $dolmemcache->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
109  if (!$result) {
110  return -1;
111  }
112  }
113 
114  $memoryid = session_name().'_'.$memoryid;
115  //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
116  $result = $dolmemcache->add($memoryid, $data, 0, $expire); // This fails if key already exists
117  if ($result) {
118  return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
119  } else {
120  return -1;
121  }
122  } elseif (getDolGlobalInt('MAIN_OPTIMIZE_SPEED') & 0x02) { // This is a really not reliable cache ! Use Memcached instead.
123  // Using shmop
124  $result = dol_setshmop($memoryid, $data, $expire);
125  } else {
126  // No intersession cache system available, we use at least the perpage cache
127  $conf->cache['cachememory_'.$memoryid] = $data;
128  $result = is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
129  }
130 
131  return $result;
132 }
133 
141 function dol_getcache($memoryid)
142 {
143  global $conf;
144 
145  if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
146  if (!getDolGlobalString('MAIN_CACHE_COUNT')) {
147  return null;
148  }
149  }
150 
151  // Using a memcached server
152  if (isModEnabled('memcached') && class_exists('Memcached')) {
153  global $m;
154  if (empty($m) || !is_object($m)) {
155  $m = new Memcached();
156  $tmparray = explode(':', getDolGlobalString('MEMCACHED_SERVER'));
157  $result = $m->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
158  if (!$result) {
159  return -1;
160  }
161  }
162 
163  $memoryid = session_name().'_'.$memoryid;
164  //$m->setOption(Memcached::OPT_COMPRESSION, false);
165  //print "Get memoryid=".$memoryid;
166  $data = $m->get($memoryid);
167  $rescode = $m->getResultCode();
168  //print "memoryid=".$memoryid." - rescode=".$rescode." - count(response)=".count($data)."\n<br>";
169  //var_dump($data);
170  if ($rescode == 0) {
171  return $data;
172  } elseif ($rescode == 16) { // = Memcached::MEMCACHED_NOTFOUND but this constant doe snot exists.
173  return null;
174  } else {
175  return -$rescode;
176  }
177  } elseif (isModEnabled('memcached') && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
178  global $m;
179  if (empty($m) || !is_object($m)) {
180  $m = new Memcache();
181  $tmparray = explode(':', getDolGlobalString('MEMCACHED_SERVER'));
182  $result = $m->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
183  if (!$result) {
184  return -1;
185  }
186  }
187 
188  $memoryid = session_name().'_'.$memoryid;
189  //$m->setOption(Memcached::OPT_COMPRESSION, false);
190  $data = $m->get($memoryid);
191  //print "memoryid=".$memoryid." - rescode=".$rescode." - data=".count($data)."\n<br>";
192  //var_dump($data);
193  if ($data) {
194  return $data;
195  } else {
196  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.
197  }
198  } elseif (getDolGlobalInt('MAIN_OPTIMIZE_SPEED') & 0x02) { // This is a really not reliable cache ! Use Memcached instead.
199  // Using shmop
200  $data = dol_getshmop($memoryid);
201  return $data;
202  } else {
203  // No intersession cache system available, we use at least the perpage cache
204  if (isset($conf->cache['cachememory_'.$memoryid])) {
205  return $conf->cache['cachememory_'.$memoryid];
206  }
207  }
208 
209  return null;
210 }
211 
212 
213 
220 function dol_getshmopaddress($memoryid)
221 {
222  global $shmkeys, $shmoffset;
223  if (empty($shmkeys[$memoryid])) { // No room reserved for this memoryid, no way to use cache
224  return 0;
225  }
226  return $shmkeys[$memoryid] + $shmoffset;
227 }
228 
234 function dol_listshmop()
235 {
236  global $shmkeys, $shmoffset;
237 
238  $resarray = array();
239  foreach ($shmkeys as $key => $val) {
240  $result = dol_getshmop($key);
241  if (!is_numeric($result) || $result > 0) {
242  $resarray[$key] = $result;
243  }
244  }
245  return $resarray;
246 }
247 
256 function dol_setshmop($memoryid, $data, $expire)
257 {
258  global $shmkeys, $shmoffset;
259 
260  //print 'dol_setshmop memoryid='.$memoryid."<br>\n";
261  if (empty($shmkeys[$memoryid]) || !function_exists("shmop_write")) {
262  return 0;
263  }
264  $shmkey = dol_getshmopaddress($memoryid);
265  if (empty($shmkey)) {
266  return 0; // No key reserved for this memoryid, we can't cache this memoryid
267  }
268 
269  $newdata = serialize($data);
270  $size = strlen($newdata);
271  //print 'dol_setshmop memoryid='.$memoryid." shmkey=".$shmkey." newdata=".$size."bytes<br>\n";
272  $handle = shmop_open($shmkey, 'c', 0644, 6 + $size);
273  if ($handle) {
274  $shm_bytes_written1 = shmop_write($handle, str_pad((string) $size, 6), 0);
275  $shm_bytes_written2 = shmop_write($handle, $newdata, 6);
276  if ($shm_bytes_written1 + $shm_bytes_written2 != 6 + dol_strlen($newdata)) {
277  print "Couldn't write the entire length of data\n";
278  }
279  // @phan-suppress-next-line PhanDeprecatedFunctionInternal
280  shmop_close($handle);
281  return ($shm_bytes_written1 + $shm_bytes_written2);
282  } else {
283  print 'Error in shmop_open for memoryid='.$memoryid.' shmkey='.$shmkey.' 6+size=6+'.$size;
284  return -1;
285  }
286 }
287 
294 function dol_getshmop($memoryid)
295 {
296  global $shmkeys, $shmoffset;
297 
298  $data = null;
299 
300  if (empty($shmkeys[$memoryid]) || !function_exists("shmop_open")) {
301  return null;
302  }
303  $shmkey = dol_getshmopaddress($memoryid);
304  if (empty($shmkey)) {
305  return null; // No key reserved for this memoryid, we can't cache this memoryid
306  }
307 
308  //print 'dol_getshmop memoryid='.$memoryid." shmkey=".$shmkey."<br>\n";
309  $handle = @shmop_open($shmkey, 'a', 0, 0);
310  if ($handle) {
311  $size = (int) trim(shmop_read($handle, 0, 6));
312  if ($size) {
313  $data = unserialize(shmop_read($handle, 6, $size));
314  } else {
315  return -1;
316  }
317  // @phan-suppress-next-line PhanDeprecatedFunctionInternal
318  shmop_close($handle);
319  } else {
320  return null; // Can't open existing block, so we suppose it was not created, so nothing were cached yet for the memoryid
321  }
322  return $data;
323 }
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_setcache($memoryid, $data, $expire=0)
Save data into a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:69
dol_getcache($memoryid)
Read a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:141
dol_listshmop()
Return list of contents of all memory area shared.
Definition: memory.lib.php:234
dol_setshmop($memoryid, $data, $expire)
Save data into a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:256
dol_getshmopaddress($memoryid)
Return shared memory address used to store dataset with key memoryid.
Definition: memory.lib.php:220
dol_getshmop($memoryid)
Read a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:294