dolibarr 21.0.0-alpha
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-2024 Frédéric France <frederic.france@free.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
26global $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
69function 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 $port = (empty($tmparray[1]) ? 0 : $tmparray[1]);
88 $result = $dolmemcache->addServer($tmparray[0], ($port || strpos($tmparray[0], '/') !== false) ? $port : 11211);
89 if (!$result) {
90 return -1;
91 }
92 }
93
94 $memoryid = session_name().'_'.$memoryid;
95 //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
96 $dolmemcache->add($memoryid, $data, $expire); // This fails if key already exists
97 $rescode = $dolmemcache->getResultCode();
98 if ($rescode == 0) {
99 return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
100 } else {
101 return -$rescode;
102 }
103 } elseif (isModEnabled('memcached') && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
104 // Using a memcache server
105 global $dolmemcache;
106 if (empty($dolmemcache) || !is_object($dolmemcache)) {
107 $dolmemcache = new Memcache();
108 $tmparray = explode(':', getDolGlobalString('MEMCACHED_SERVER'));
109 $port = (empty($tmparray[1]) ? 0 : $tmparray[1]);
110 $result = $dolmemcache->addServer($tmparray[0], ($port || strpos($tmparray[0], '/') !== false) ? $port : 11211);
111 if (!$result) {
112 return -1;
113 }
114 }
115
116 $memoryid = session_name().'_'.$memoryid;
117 //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false);
118 $result = $dolmemcache->add($memoryid, $data, 0, $expire); // This fails if key already exists
119 if ($result) {
120 return is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
121 } else {
122 return -1;
123 }
124 } elseif (getDolGlobalInt('MAIN_OPTIMIZE_SPEED') & 0x02) { // This is a really not reliable cache ! Use Memcached instead.
125 // Using shmop
126 $result = dol_setshmop($memoryid, $data, $expire);
127 } else {
128 // No intersession cache system available, we use at least the perpage cache
129 $conf->cache['cachememory_'.$memoryid] = $data;
130 $result = is_array($data) ? count($data) : (is_scalar($data) ? strlen($data) : 0);
131 }
132
133 return $result;
134}
135
143function dol_getcache($memoryid)
144{
145 global $conf;
146
147 if (strpos($memoryid, 'count_') === 0) { // The memoryid key start with 'count_...'
148 if (!getDolGlobalString('MAIN_CACHE_COUNT')) {
149 return null;
150 }
151 }
152
153 // Using a memcached server
154 if (isModEnabled('memcached') && class_exists('Memcached')) {
155 global $m;
156 if (empty($m) || !is_object($m)) {
157 $m = new Memcached();
158 $tmparray = explode(':', getDolGlobalString('MEMCACHED_SERVER'));
159 $port = (empty($tmparray[1]) ? 0 : $tmparray[1]);
160 $result = $m->addServer($tmparray[0], ($port || strpos($tmparray[0], '/') !== false) ? $port : 11211);
161 if (!$result) {
162 return -1;
163 }
164 }
165
166 $memoryid = session_name().'_'.$memoryid;
167 //$m->setOption(Memcached::OPT_COMPRESSION, false);
168 //print "Get memoryid=".$memoryid;
169 $data = $m->get($memoryid);
170 $rescode = $m->getResultCode();
171 //print "memoryid=".$memoryid." - rescode=".$rescode." - count(response)=".count($data)."\n<br>";
172 //var_dump($data);
173 if ($rescode == 0) {
174 return $data;
175 } elseif ($rescode == 16) { // = Memcached::MEMCACHED_NOTFOUND but this constant doe snot exists.
176 return null;
177 } else {
178 return -$rescode;
179 }
180 } elseif (isModEnabled('memcached') && class_exists('Memcache')) { // This is a really not reliable cache ! Use Memcached instead.
181 global $m;
182 if (empty($m) || !is_object($m)) {
183 $m = new Memcache();
184 $tmparray = explode(':', getDolGlobalString('MEMCACHED_SERVER'));
185 $port = (empty($tmparray[1]) ? 0 : $tmparray[1]);
186 $result = $m->addServer($tmparray[0], ($port || strpos($tmparray[0], '/') !== false) ? $port : 11211);
187 if (!$result) {
188 return -1;
189 }
190 }
191
192 $memoryid = session_name().'_'.$memoryid;
193 //$m->setOption(Memcached::OPT_COMPRESSION, false);
194 $data = $m->get($memoryid);
195 //print "memoryid=".$memoryid." - rescode=".$rescode." - data=".count($data)."\n<br>";
196 //var_dump($data);
197 if ($data) {
198 return $data;
199 } else {
200 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.
201 }
202 } elseif (getDolGlobalInt('MAIN_OPTIMIZE_SPEED') & 0x02) { // This is a really not reliable cache ! Use Memcached instead.
203 // Using shmop
204 $data = dol_getshmop($memoryid);
205 return $data;
206 } else {
207 // No intersession cache system available, we use at least the perpage cache
208 if (isset($conf->cache['cachememory_'.$memoryid])) {
209 return $conf->cache['cachememory_'.$memoryid];
210 }
211 }
212
213 return null;
214}
215
216
217
224function dol_getshmopaddress($memoryid)
225{
226 global $shmkeys, $shmoffset;
227 if (empty($shmkeys[$memoryid])) { // No room reserved for this memoryid, no way to use cache
228 return 0;
229 }
230 return $shmkeys[$memoryid] + $shmoffset;
231}
232
239{
240 global $shmkeys, $shmoffset;
241
242 $resarray = array();
243 foreach ($shmkeys as $key => $val) {
244 $result = dol_getshmop($key);
245 if (!is_numeric($result) || $result > 0) {
246 $resarray[$key] = $result;
247 }
248 }
249 return $resarray;
250}
251
260function dol_setshmop($memoryid, $data, $expire)
261{
262 global $shmkeys, $shmoffset;
263
264 //print 'dol_setshmop memoryid='.$memoryid."<br>\n";
265 if (empty($shmkeys[$memoryid]) || !function_exists("shmop_write")) {
266 return 0;
267 }
268 $shmkey = dol_getshmopaddress($memoryid);
269 if (empty($shmkey)) {
270 return 0; // No key reserved for this memoryid, we can't cache this memoryid
271 }
272
273 $newdata = serialize($data);
274 $size = strlen($newdata);
275 //print 'dol_setshmop memoryid='.$memoryid." shmkey=".$shmkey." newdata=".$size."bytes<br>\n";
276 $handle = shmop_open($shmkey, 'c', 0644, 6 + $size);
277 if ($handle) {
278 $shm_bytes_written1 = shmop_write($handle, str_pad((string) $size, 6), 0);
279 $shm_bytes_written2 = shmop_write($handle, $newdata, 6);
280 if ($shm_bytes_written1 + $shm_bytes_written2 != 6 + dol_strlen($newdata)) {
281 print "Couldn't write the entire length of data\n";
282 }
283 // @phan-suppress-next-line PhanDeprecatedFunctionInternal
284 shmop_close($handle);
285 return ($shm_bytes_written1 + $shm_bytes_written2);
286 } else {
287 print 'Error in shmop_open for memoryid='.$memoryid.' shmkey='.$shmkey.' 6+size=6+'.$size;
288 return -1;
289 }
290}
291
298function dol_getshmop($memoryid)
299{
300 global $shmkeys, $shmoffset;
301
302 $data = null;
303
304 if (empty($shmkeys[$memoryid]) || !function_exists("shmop_open")) {
305 return null;
306 }
307 $shmkey = dol_getshmopaddress($memoryid);
308 if (empty($shmkey)) {
309 return null; // No key reserved for this memoryid, we can't cache this memoryid
310 }
311
312 //print 'dol_getshmop memoryid='.$memoryid." shmkey=".$shmkey."<br>\n";
313 $handle = @shmop_open($shmkey, 'a', 0, 0);
314 if ($handle) {
315 $size = (int) trim(shmop_read($handle, 0, 6));
316 if ($size) {
317 $data = unserialize(shmop_read($handle, 6, $size));
318 } else {
319 return -1;
320 }
321 // @phan-suppress-next-line PhanDeprecatedFunctionInternal
322 shmop_close($handle);
323 } else {
324 return null; // Can't open existing block, so we suppose it was not created, so nothing were cached yet for the memoryid
325 }
326 return $data;
327}
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 a 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.