dolibarr  17.0.4
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 
72  $result = 0;
73 
74  if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
75  if (empty($conf->global->MAIN_CACHE_COUNT)) {
76  return 0;
77  }
78  }
79 
80  if (!empty($conf->memcached->enabled) && class_exists('Memcached')) {
81  // Using a memcached server
82  global $dolmemcache;
83  if (empty($dolmemcache) || !is_object($dolmemcache)) {
84  $dolmemcache = new Memcached();
85  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
86  $result = $dolmemcache->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
87  if (!$result) {
88  return -1;
89  }
90  }
91 
92  $memoryid = session_name().'_'.$memoryid;
93  //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
94  $dolmemcache->add($memoryid, $data, $expire); // This fails if key already exists
95  $rescode = $dolmemcache->getResultCode();
96  if ($rescode == 0) {
97  return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
98  } else {
99  return -$rescode;
100  }
101  } elseif (!empty($conf->memcached->enabled) && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
102  // Using a memcache server
103  global $dolmemcache;
104  if (empty($dolmemcache) || !is_object($dolmemcache)) {
105  $dolmemcache = new Memcache();
106  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
107  $result = $dolmemcache->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
108  if (!$result) {
109  return -1;
110  }
111  }
112 
113  $memoryid = session_name().'_'.$memoryid;
114  //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
115  $result = $dolmemcache->add($memoryid, $data, false, $expire); // This fails if key already exists
116  if ($result) {
117  return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
118  } else {
119  return -1;
120  }
121  } elseif (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x02)) { // This is a really not reliable cache ! Use Memcached instead.
122  // Using shmop
123  $result = dol_setshmop($memoryid, $data, $expire);
124  } else {
125  // No intersession cache system available, we use at least the perpage cache
126  $conf->cache['cachememory_'.$memoryid] = $data;
127  $result = is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
128  }
129 
130  return $result;
131 }
132 
140 function dol_getcache($memoryid)
141 {
142  global $conf;
143 
144  if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
145  if (empty($conf->global->MAIN_CACHE_COUNT)) {
146  return null;
147  }
148  }
149 
150  // Using a memcached server
151  if (!empty($conf->memcached->enabled) && class_exists('Memcached')) {
152  global $m;
153  if (empty($m) || !is_object($m)) {
154  $m = new Memcached();
155  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
156  $result = $m->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
157  if (!$result) {
158  return -1;
159  }
160  }
161 
162  $memoryid = session_name().'_'.$memoryid;
163  //$m->setOption(Memcached::OPT_COMPRESSION, false);
164  //print "Get memoryid=".$memoryid;
165  $data = $m->get($memoryid);
166  $rescode = $m->getResultCode();
167  //print "memoryid=".$memoryid." - rescode=".$rescode." - count(response)=".count($data)."\n<br>";
168  //var_dump($data);
169  if ($rescode == 0) {
170  return $data;
171  } elseif ($rescode == 16) { // = Memcached::MEMCACHED_NOTFOUND but this constant doe snot exists.
172  return null;
173  } else {
174  return -$rescode;
175  }
176  } elseif (!empty($conf->memcached->enabled) && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
177  global $m;
178  if (empty($m) || !is_object($m)) {
179  $m = new Memcache();
180  $tmparray = explode(':', $conf->global->MEMCACHED_SERVER);
181  $result = $m->addServer($tmparray[0], $tmparray[1] ? $tmparray[1] : 11211);
182  if (!$result) {
183  return -1;
184  }
185  }
186 
187  $memoryid = session_name().'_'.$memoryid;
188  //$m->setOption(Memcached::OPT_COMPRESSION, false);
189  $data = $m->get($memoryid);
190  //print "memoryid=".$memoryid." - rescode=".$rescode." - data=".count($data)."\n<br>";
191  //var_dump($data);
192  if ($data) {
193  return $data;
194  } else {
195  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.
196  }
197  } elseif (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x02)) { // This is a really not reliable cache ! Use Memcached instead.
198  // Using shmop
199  $data = dol_getshmop($memoryid);
200  return $data;
201  } else {
202  // No intersession cache system available, we use at least the perpage cache
203  if (isset($conf->cache['cachememory_'.$memoryid])) {
204  return $conf->cache['cachememory_'.$memoryid];
205  }
206  }
207 
208  return null;
209 }
210 
211 
212 
219 function dol_getshmopaddress($memoryid)
220 {
221  global $shmkeys, $shmoffset;
222  if (empty($shmkeys[$memoryid])) { // No room reserved for thid memoryid, no way to use cache
223  return 0;
224  }
225  return $shmkeys[$memoryid] + $shmoffset;
226 }
227 
233 function dol_listshmop()
234 {
235  global $shmkeys, $shmoffset;
236 
237  $resarray = array();
238  foreach ($shmkeys as $key => $val) {
239  $result = dol_getshmop($key);
240  if (!is_numeric($result) || $result > 0) {
241  $resarray[$key] = $result;
242  }
243  }
244  return $resarray;
245 }
246 
255 function dol_setshmop($memoryid, $data, $expire)
256 {
257  global $shmkeys, $shmoffset;
258 
259  //print 'dol_setshmop memoryid='.$memoryid."<br>\n";
260  if (empty($shmkeys[$memoryid]) || !function_exists("shmop_write")) {
261  return 0;
262  }
263  $shmkey = dol_getshmopaddress($memoryid);
264  if (empty($shmkey)) {
265  return 0; // No key reserved for this memoryid, we can't cache this memoryid
266  }
267 
268  $newdata = serialize($data);
269  $size = strlen($newdata);
270  //print 'dol_setshmop memoryid='.$memoryid." shmkey=".$shmkey." newdata=".$size."bytes<br>\n";
271  $handle = shmop_open($shmkey, 'c', 0644, 6 + $size);
272  if ($handle) {
273  $shm_bytes_written1 = shmop_write($handle, str_pad($size, 6), 0);
274  $shm_bytes_written2 = shmop_write($handle, $newdata, 6);
275  if (($shm_bytes_written1 + $shm_bytes_written2) != (6 + dol_strlen($newdata))) {
276  print "Couldn't write the entire length of data\n";
277  }
278  shmop_close($handle);
279  return ($shm_bytes_written1 + $shm_bytes_written2);
280  } else {
281  print 'Error in shmop_open for memoryid='.$memoryid.' shmkey='.$shmkey.' 6+size=6+'.$size;
282  return -1;
283  }
284 }
285 
292 function dol_getshmop($memoryid)
293 {
294  global $shmkeys, $shmoffset;
295 
296  $data = null;
297 
298  if (empty($shmkeys[$memoryid]) || !function_exists("shmop_open")) {
299  return null;
300  }
301  $shmkey = dol_getshmopaddress($memoryid);
302  if (empty($shmkey)) {
303  return null; // No key reserved for this memoryid, we can't cache this memoryid
304  }
305 
306  //print 'dol_getshmop memoryid='.$memoryid." shmkey=".$shmkey."<br>\n";
307  $handle = @shmop_open($shmkey, 'a', 0, 0);
308  if ($handle) {
309  $size = trim(shmop_read($handle, 0, 6));
310  if ($size) {
311  $data = unserialize(shmop_read($handle, 6, $size));
312  } else {
313  return -1;
314  }
315  shmop_close($handle);
316  } else {
317  return null; // Can't open existing block, so we suppose it was not created, so nothing were cached yet for the memoryid
318  }
319  return $data;
320 }
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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($memoryid)
Read a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:140
dol_listshmop()
Return list of contents of all memory area shared.
Definition: memory.lib.php:233
dol_setshmop($memoryid, $data, $expire)
Save data into a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:255
dol_getshmopaddress($memoryid)
Return shared memory address used to store dataset with key memoryid.
Definition: memory.lib.php:219
dol_getshmop($memoryid)
Read a memory area shared by all users, all sessions on server.
Definition: memory.lib.php:292