Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
file.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 namespace phpbb\cache\driver;
015
016 /**
017 * ACM File Based Caching
018 */
019 class file extends \phpbb\cache\driver\base
020 {
021 var $var_expires = array();
022
023 /**
024 * Set cache path
025 *
026 * @param string $cache_dir Define the path to the cache directory (default: $phpbb_root_path . 'cache/')
027 */
028 function __construct($cache_dir = null)
029 {
030 global $phpbb_root_path;
031 $this->cache_dir = !is_null($cache_dir) ? $cache_dir : $phpbb_root_path . 'cache/';
032 }
033
034 /**
035 * {@inheritDoc}
036 */
037 function load()
038 {
039 return $this->_read('data_global');
040 }
041
042 /**
043 * {@inheritDoc}
044 */
045 function unload()
046 {
047 parent::unload();
048 unset($this->var_expires);
049 $this->var_expires = array();
050 }
051
052 /**
053 * {@inheritDoc}
054 */
055 function save()
056 {
057 if (!$this->is_modified)
058 {
059 return;
060 }
061
062 global $phpEx;
063
064 if (!$this->_write('data_global'))
065 {
066 if (!function_exists('phpbb_is_writable'))
067 {
068 global $phpbb_root_path;
069 include($phpbb_root_path . 'includes/functions.' . $phpEx);
070 }
071
072 // Now, this occurred how often? ... phew, just tell the user then...
073 if (!phpbb_is_writable($this->cache_dir))
074 {
075 // We need to use die() here, because else we may encounter an infinite loop (the message handler calls $cache->unload())
076 die('Fatal: ' . $this->cache_dir . ' is NOT writable.');
077 exit;
078 }
079
080 die('Fatal: Not able to open ' . $this->cache_dir . 'data_global.' . $phpEx);
081 exit;
082 }
083
084 $this->is_modified = false;
085 }
086
087 /**
088 * {@inheritDoc}
089 */
090 function tidy()
091 {
092 global $phpEx;
093
094 $dir = @opendir($this->cache_dir);
095
096 if (!$dir)
097 {
098 return;
099 }
100
101 $time = time();
102
103 while (($entry = readdir($dir)) !== false)
104 {
105 if (!preg_match('/^(sql_|data_(?!global))/', $entry))
106 {
107 continue;
108 }
109
110 if (!($handle = @fopen($this->cache_dir . $entry, 'rb')))
111 {
112 continue;
113 }
114
115 // Skip the PHP header
116 fgets($handle);
117
118 // Skip expiration
119 $expires = (int) fgets($handle);
120
121 fclose($handle);
122
123 if ($time >= $expires)
124 {
125 $this->remove_file($this->cache_dir . $entry);
126 }
127 }
128 closedir($dir);
129
130 if (file_exists($this->cache_dir . 'data_global.' . $phpEx))
131 {
132 if (!sizeof($this->vars))
133 {
134 $this->load();
135 }
136
137 foreach ($this->var_expires as $var_name => $expires)
138 {
139 if ($time >= $expires)
140 {
141 $this->destroy($var_name);
142 }
143 }
144 }
145
146 set_config('cache_last_gc', time(), true);
147 }
148
149 /**
150 * {@inheritDoc}
151 */
152 function get($var_name)
153 {
154 if ($var_name[0] == '_')
155 {
156 if (!$this->_exists($var_name))
157 {
158 return false;
159 }
160
161 return $this->_read('data' . $var_name);
162 }
163 else
164 {
165 return ($this->_exists($var_name)) ? $this->vars[$var_name] : false;
166 }
167 }
168
169 /**
170 * {@inheritDoc}
171 */
172 function put($var_name, $var, $ttl = 31536000)
173 {
174 if ($var_name[0] == '_')
175 {
176 $this->_write('data' . $var_name, $var, time() + $ttl);
177 }
178 else
179 {
180 $this->vars[$var_name] = $var;
181 $this->var_expires[$var_name] = time() + $ttl;
182 $this->is_modified = true;
183 }
184 }
185
186 /**
187 * {@inheritDoc}
188 */
189 function purge()
190 {
191 parent::purge();
192 $this->var_expires = array();
193 }
194
195 /**
196 * {@inheritDoc}
197 */
198 function destroy($var_name, $table = '')
199 {
200 global $phpEx;
201
202 if ($var_name == 'sql' && !empty($table))
203 {
204 if (!is_array($table))
205 {
206 $table = array($table);
207 }
208
209 $dir = @opendir($this->cache_dir);
210
211 if (!$dir)
212 {
213 return;
214 }
215
216 while (($entry = readdir($dir)) !== false)
217 {
218 if (strpos($entry, 'sql_') !== 0)
219 {
220 continue;
221 }
222
223 if (!($handle = @fopen($this->cache_dir . $entry, 'rb')))
224 {
225 continue;
226 }
227
228 // Skip the PHP header
229 fgets($handle);
230
231 // Skip expiration
232 fgets($handle);
233
234 // Grab the query, remove the LF
235 $query = substr(fgets($handle), 0, -1);
236
237 fclose($handle);
238
239 foreach ($table as $check_table)
240 {
241 // Better catch partial table names than no table names. ;)
242 if (strpos($query, $check_table) !== false)
243 {
244 $this->remove_file($this->cache_dir . $entry);
245 break;
246 }
247 }
248 }
249 closedir($dir);
250
251 return;
252 }
253
254 if (!$this->_exists($var_name))
255 {
256 return;
257 }
258
259 if ($var_name[0] == '_')
260 {
261 $this->remove_file($this->cache_dir . 'data' . $var_name . ".$phpEx", true);
262 }
263 else if (isset($this->vars[$var_name]))
264 {
265 $this->is_modified = true;
266 unset($this->vars[$var_name]);
267 unset($this->var_expires[$var_name]);
268
269 // We save here to let the following cache hits succeed
270 $this->save();
271 }
272 }
273
274 /**
275 * {@inheritDoc}
276 */
277 function _exists($var_name)
278 {
279 if ($var_name[0] == '_')
280 {
281 global $phpEx;
282 return file_exists($this->cache_dir . 'data' . $var_name . ".$phpEx");
283 }
284 else
285 {
286 if (!sizeof($this->vars))
287 {
288 $this->load();
289 }
290
291 if (!isset($this->var_expires[$var_name]))
292 {
293 return false;
294 }
295
296 return (time() > $this->var_expires[$var_name]) ? false : isset($this->vars[$var_name]);
297 }
298 }
299
300 /**
301 * {@inheritDoc}
302 */
303 function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl)
304 {
305 // Remove extra spaces and tabs
306 $query = preg_replace('/[\n\r\s\t]+/', ' ', $query);
307
308 $query_id = sizeof($this->sql_rowset);
309 $this->sql_rowset[$query_id] = array();
310 $this->sql_row_pointer[$query_id] = 0;
311
312 while ($row = $db->sql_fetchrow($query_result))
313 {
314 $this->sql_rowset[$query_id][] = $row;
315 }
316 $db->sql_freeresult($query_result);
317
318 if ($this->_write('sql_' . md5($query), $this->sql_rowset[$query_id], $ttl + time(), $query))
319 {
320 return $query_id;
321 }
322
323 return $query_result;
324 }
325
326 /**
327 * Read cached data from a specified file
328 *
329 * @access private
330 * @param string $filename Filename to write
331 * @return mixed False if an error was encountered, otherwise the data type of the cached data
332 */
333 function _read($filename)
334 {
335 global $phpEx;
336
337 $file = "{$this->cache_dir}$filename.$phpEx";
338
339 $type = substr($filename, 0, strpos($filename, '_'));
340
341 if (!file_exists($file))
342 {
343 return false;
344 }
345
346 if (!($handle = @fopen($file, 'rb')))
347 {
348 return false;
349 }
350
351 // Skip the PHP header
352 fgets($handle);
353
354 if ($filename == 'data_global')
355 {
356 $this->vars = $this->var_expires = array();
357
358 $time = time();
359
360 while (($expires = (int) fgets($handle)) && !feof($handle))
361 {
362 // Number of bytes of data
363 $bytes = substr(fgets($handle), 0, -1);
364
365 if (!is_numeric($bytes) || ($bytes = (int) $bytes) === 0)
366 {
367 // We cannot process the file without a valid number of bytes
368 // so we discard it
369 fclose($handle);
370
371 $this->vars = $this->var_expires = array();
372 $this->is_modified = false;
373
374 $this->remove_file($file);
375
376 return false;
377 }
378
379 if ($time >= $expires)
380 {
381 fseek($handle, $bytes, SEEK_CUR);
382
383 continue;
384 }
385
386 $var_name = substr(fgets($handle), 0, -1);
387
388 // Read the length of bytes that consists of data.
389 $data = fread($handle, $bytes - strlen($var_name));
390 $data = @unserialize($data);
391
392 // Don't use the data if it was invalid
393 if ($data !== false)
394 {
395 $this->vars[$var_name] = $data;
396 $this->var_expires[$var_name] = $expires;
397 }
398
399 // Absorb the LF
400 fgets($handle);
401 }
402
403 fclose($handle);
404
405 $this->is_modified = false;
406
407 return true;
408 }
409 else
410 {
411 $data = false;
412 $line = 0;
413
414 while (($buffer = fgets($handle)) && !feof($handle))
415 {
416 $buffer = substr($buffer, 0, -1); // Remove the LF
417
418 // $buffer is only used to read integers
419 // if it is non numeric we have an invalid
420 // cache file, which we will now remove.
421 if (!is_numeric($buffer))
422 {
423 break;
424 }
425
426 if ($line == 0)
427 {
428 $expires = (int) $buffer;
429
430 if (time() >= $expires)
431 {
432 break;
433 }
434
435 if ($type == 'sql')
436 {
437 // Skip the query
438 fgets($handle);
439 }
440 }
441 else if ($line == 1)
442 {
443 $bytes = (int) $buffer;
444
445 // Never should have 0 bytes
446 if (!$bytes)
447 {
448 break;
449 }
450
451 // Grab the serialized data
452 $data = fread($handle, $bytes);
453
454 // Read 1 byte, to trigger EOF
455 fread($handle, 1);
456
457 if (!feof($handle))
458 {
459 // Somebody tampered with our data
460 $data = false;
461 }
462 break;
463 }
464 else
465 {
466 // Something went wrong
467 break;
468 }
469 $line++;
470 }
471 fclose($handle);
472
473 // unserialize if we got some data
474 $data = ($data !== false) ? @unserialize($data) : $data;
475
476 if ($data === false)
477 {
478 $this->remove_file($file);
479 return false;
480 }
481
482 return $data;
483 }
484 }
485
486 /**
487 * Write cache data to a specified file
488 *
489 * 'data_global' is a special case and the generated format is different for this file:
490 * <code>
491 * <?php exit; ?>
492 * (expiration)
493 * (length of var and serialised data)
494 * (var)
495 * (serialised data)
496 * ... (repeat)
497 * </code>
498 *
499 * The other files have a similar format:
500 * <code>
501 * <?php exit; ?>
502 * (expiration)
503 * (query) [SQL files only]
504 * (length of serialised data)
505 * (serialised data)
506 * </code>
507 *
508 * @access private
509 * @param string $filename Filename to write
510 * @param mixed $data Data to store
511 * @param int $expires Timestamp when the data expires
512 * @param string $query Query when caching SQL queries
513 * @return bool True if the file was successfully created, otherwise false
514 */
515 function _write($filename, $data = null, $expires = 0, $query = '')
516 {
517 global $phpEx;
518
519 $file = "{$this->cache_dir}$filename.$phpEx";
520
521 $lock = new \phpbb\lock\flock($file);
522 $lock->acquire();
523
524 if ($handle = @fopen($file, 'wb'))
525 {
526 // File header
527 fwrite($handle, '<' . '?php exit; ?' . '>');
528
529 if ($filename == 'data_global')
530 {
531 // Global data is a different format
532 foreach ($this->vars as $var => $data)
533 {
534 if (strpos($var, "\r") !== false || strpos($var, "\n") !== false)
535 {
536 // CR/LF would cause fgets() to read the cache file incorrectly
537 // do not cache test entries, they probably won't be read back
538 // the cache keys should really be alphanumeric with a few symbols.
539 continue;
540 }
541 $data = serialize($data);
542
543 // Write out the expiration time
544 fwrite($handle, "\n" . $this->var_expires[$var] . "\n");
545
546 // Length of the remaining data for this var (ignoring two LF's)
547 fwrite($handle, strlen($data . $var) . "\n");
548 fwrite($handle, $var . "\n");
549 fwrite($handle, $data);
550 }
551 }
552 else
553 {
554 fwrite($handle, "\n" . $expires . "\n");
555
556 if (strpos($filename, 'sql_') === 0)
557 {
558 fwrite($handle, $query . "\n");
559 }
560 $data = serialize($data);
561
562 fwrite($handle, strlen($data) . "\n");
563 fwrite($handle, $data);
564 }
565
566 fclose($handle);
567
568 if (!function_exists('phpbb_chmod'))
569 {
570 global $phpbb_root_path;
571 include($phpbb_root_path . 'includes/functions.' . $phpEx);
572 }
573
574 phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE);
575
576 $return_value = true;
577 }
578 else
579 {
580 $return_value = false;
581 }
582
583 $lock->release();
584
585 return $return_value;
586 }
587 }
588