dolibarr 19.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
25global $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
68function 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 (!getDolGlobalString('MAIN_CACHE_COUNT')) {
76 return 0;
77 }
78 }
79
80 if (isModEnabled('memcached') && 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(':', getDolGlobalString('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 (isModEnabled('memcached') && 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(':', getDolGlobalString('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
140function dol_getcache($memoryid)
141{
142 global $conf;
143
144 if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
145 if (!getDolGlobalString('MAIN_CACHE_COUNT')) {
146 return null;
147 }
148 }
149
150 // Using a memcached server
151 if (isModEnabled('memcached') && class_exists('Memcached')) {
152 global $m;
153 if (empty($m) || !is_object($m)) {
154 $m = new Memcached();
155 $tmparray = explode(':', getDolGlobalString('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 (isModEnabled('memcached') && 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(':', getDolGlobalString('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
219function 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
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
255function 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
292function 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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_setcache($memoryid, $data, $expire=0)
Save data into a memory area shared by all users, all sessions on server.
dol_getcache($memoryid)
Read a memory area shared by all users, all sessions on server.
dol_listshmop()
Return list of contents of all memory area shared.
dol_setshmop($memoryid, $data, $expire)
Save data into a memory area shared by all users, all sessions on server.
dol_getshmopaddress($memoryid)
Return shared memory address used to store dataset with key memoryid.
dol_getshmop($memoryid)
Read a memory area shared by all users, all sessions on server.