// * ?md5().html * * Es wird für jede Seite und jeden Request-Parameter-Kombination, der in * $allowed_req_params angegeben ist, eine Seite im Cache angelegt. * * Parameter: * - $auto_update: erzeugt bei Scriptaufruf eine neue Cache-Datei, wenn: * a) die Cachedatei älter ist als die Scriptdatei oder * b) die Cachedatei älter ist als eine per include/require eingebunden * Scriptdatei * - $update_interval: eine Erneuerung der Cachedatei wird vorgenommen, wenn * die Cachedatei älter als $update_interval ist. * - $script-file: das Script, dessen Inhalt gecached werden soll, i.d.R * __FILE__ * - $allowed_req_params: Liste der erlaubten Request-Parameter, dient zur * Bildung des Cachedateinamens * - $debug: erzeugt Debug-Ausgaben * * Die Einbindung in ein Script erfolgt nach Einbindung per include/require * der zusätzlich erforderlichen Bibliothen mit: * * if (printCachedPage($auto_update,$update_interval,__FILE__)) * return; * * Der mit printCachedPage erzeugte HTML-Bereich wird mit HTML-Kommentaren * umrandet und kann so im Gesamt-Quelltext identifiziert werden. */ define ('MAX_CACHE_WAIT_SECS',1); function printCachedPage ( $script_file, $auto_update = true, $update_interval = 86400, $allowed_req_params = -1, $debug = 0) { if (USE_SCRIPT_CACHE == 0) return 0; $em_parameter = ""; if (isset ($_REQUEST["em_parameter"])) $em_parameter = $_REQUEST["em_parameter"]; if (!empty($em_parameter)) $GLOBALS["em_parameter"] = $em_parameter; if (!empty($GLOBALS["em_parameter"])) $em_parameter = $GLOBALS["em_parameter"]; $content = ""; if (isset($_REQUEST["NOCACHE"])) { if (isset($_REQUEST["PHP_SELF"])) { $_SERVER["PHP_SELF"]=$_REQUEST["PHP_SELF"]; // --- DEBUG OUTPUT ------- if ($debug) echo "
PHP_SELF wurde gesetzt: " . $_SERVER["PHP_SELF"]; // --- END DEBUG OUTPUT --- } return 0; } // --- DEBUG OUTPUT ------- $t1 = NULL; if ($debug) $t1 = getMilliSeconds (); if ($debug) { echo "
Startzeit: ".strftime("%H:%M:%S"); echo "
Script-Datei: ".$script_file; echo "
PHP_SELF: ".$_SERVER["PHP_SELF"]; echo "
Erlaubte Cache-Dateien pro Verzeichnis: " . MAX_FILES_IN_CACHE_DIR; } // --- END DEBUG OUTPUT --- $subclient_id = getSubclientIDByUrl(); $len = strlen ($_SERVER["DOCUMENT_ROOT"]); $script_name = substr ($script_file, $len); // --- DEBUG OUTPUT ------- if ($debug) echo "
DOCUMENT ROOT: " . $_SERVER["DOCUMENT_ROOT"]; if ($debug) echo "
Script-Name: $script_name"; // --- END DEBUG OUTPUT --- $cache_file = realpath (CACHEDIR) . "/" . $subclient_id . "/" . substr(dirname($script_name),1) . "/" . basename($script_name) . "/" . basename($script_name,".php"); $params = ""; $query_string = ""; foreach ($_REQUEST as $key => $val) { if (is_array ($allowed_req_params) && in_array ($key,$allowed_req_params)) { $val = urlencode (trim($val)); $key = urlencode (trim($key)); // --- DEBUG OUTPUT ------- if ($debug) echo "
Hänge Request-Parameter an: _$key-$val"; // --- END DEBUG OUTPUT --- $params .= "_". $key . "-" . $val; $query_string .= $key . "=" . $val . "&"; } } if (!empty ($em_parameter)) { $params .= "_" . $em_parameter; $query_string .= "em_parameter=" . $em_parameter; } if (!empty ($params)) $cache_file = $cache_file . "_" . md5($params) . ".html"; else $cache_file = $cache_file . ".html"; $url = getProtocol () . "://" . $_SERVER["SERVER_NAME"] . $script_name . "?" . $query_string; $cached_dir = dirname($cache_file); // --- DEBUG OUTPUT ------- if ($debug) { echo "
Cache-Datei: $cache_file"; echo "
Script-Datei: $script_file"; echo "
URL: ".htmlspecialchars($url); echo "
Cache Dir: $cached_dir"; } // --- END DEBUG OUTPUT --- if (!is_dir ($cached_dir)) { if (!is_dir (CACHEDIR . $subclient_id)) mkdir (CACHEDIR . $subclient_id); $cachedir = CACHEDIR . $subclient_id; $dir_arr = explode ("/", dirname($script_name) . "/" . basename($script_name)); foreach ($dir_arr as $dir) { if (!is_dir($cachedir . "/" . $dir)) { mkdir ($cachedir. "/" . $dir); chmod ($cachedir. "/" . $dir, 0777); // --- DEBUG OUTPUT ------- if ($debug) echo "
Erzeuge Verzeichnis: $cachedir/$dir"; // --- END DEBUG OUTPUT --- } $cachedir .= "/" . $dir; } } $is_updated = 0; if (!file_exists ($cache_file)) { $file_count = count (scandir ($cached_dir)) - 2; // --- DEBUG OUTPUT ------- if ($debug) echo "
Es sind $file_count im Cacheverzeichnis. " . "Erlaubt sind " . MAX_FILES_IN_CACHE_DIR. "."; // --- END DEBUG OUTPUT --- if ($file_count <= MAX_FILES_IN_CACHE_DIR) { $content = makeCacheFile ($cache_file, $url, $debug); $is_updated = 1; // --- DEBUG OUTPUT ------- if ($debug) echo "
Cache-Datei wurde erzeugt, " . "weil diese nicht existierte."; // --- END DEBUG OUTPUT --- } else { // --- DEBUG OUTPUT ------- if ($debug) { echo "
Es sind mehr Dateien im Cacheverzeichnis als " . "erlaubt: " . $file_count . "
Die Seite kann daher nicht gecached werden."; } // --- END DEBUG OUTPUT --- } } else { if ($auto_update) { $do_update=0; if (filemtime($cache_file) < filemtime($script_file)) { $do_update = 1; // --- DEBUG OUTPUT ------- if ($debug) echo "
Cache-Datei wird erzeugt, weil die Cache-Datei " . "älter als die Script-Datei ist."; // --- END DEBUG OUTPUT --- } else { $includes = get_included_files (); foreach($includes as $inc) { if (strstr ($inc, realpath (HOME . "/../"))) { // --- DEBUG OUTPUT ------- if ($debug) echo "
Untersuche Abhängigkeiten von $inc"; // --- END DEBUG OUTPUT --- if (filemtime($inc) > filemtime($cache_file)) { $do_update=1; // --- DEBUG OUTPUT ------- if ($debug) echo "
Cache-Datei wird erzeugt, weil " . $inc . "verändert wurde."; // --- END DEBUG OUTPUT --- break; } } } } if (!$do_update) { $content = getCacheContent ($cache_file, $debug); } else { $content = makeCacheFile ($cache_file, $url, $debug); $is_updated = 1; // --- DEBUG OUTPUT ------- if ($debug) echo "
Cache-Datei wurde erzeugt: Auto-Update"; // --- END DEBUG OUTPUT --- } } if ($update_interval >= 10 && !$is_updated) { $diff = time() - filemtime($cache_file); // --- DEBUG OUTPUT ------- if ($debug) echo "
Noch " . $update_interval - $diff . " Sekunden bis zum nächsten Interval-Update"; // --- END DEBUG OUTPUT --- if ($diff > $update_interval) { $content = makeCacheFile($cache_file, $url, $debug); $is_updated=1; // --- DEBUG OUTPUT ------- if ($debug) echo "
Cache-Datei wurde erzeugt: Interval-Update"; // --- END DEBUG OUTPUT --- } else { $content = getCacheContent($cache_file, $debug); } } } // --- DEBUG OUTPUT ------- if ($debug) echo "
"; // --- END DEBUG OUTPUT --- if (!empty($content)) echo "\n\n"; echo $content; if (!empty($content)) echo "\n\n"; // --- DEBUG OUTPUT ------- if ($debug) echo "

Gecachter Content wurde ausgeliefert."; if ($debug) echo "
Verarbeitungsdauer (in ms): ".(intval(getMilliSeconds()-$t1)); // --- END DEBUG OUTPUT --- if (empty($content)) return 0; else return 1; } function makeCacheFile($cache_file, $url, $debug) { if (preg_match("/^http.*\?.*/",$url)) $url = $url."&NOCACHE=1&PHP_SELF=".urlencode($_SERVER["PHP_SELF"]); else $url = $url."?NOCACHE=1&PHP_SELF=".urlencode($_SERVER["PHP_SELF"]); if ($debug) echo "
Encoded URL: $url"; // --- DEBUG OUTPUT ------- $t1 = ''; if ($debug) $t1=getMilliSeconds(); // --- END DEBUG OUTPUT --- $content = file_get_contents($url); // --- DEBUG OUTPUT ------- if ($debug) echo "
Laden der Seite ohne Cache dauerte: " . getMilliSeconds() - $t1 . " ms"; flush(); if ($debug) { echo "
Cache-Datei ist gesperrt: "; var_dump (is_file ($cache_file.".LCK")); } // --- END DEBUG OUTPUT --- $ctr = 0; while (cacheFileIsLocked ($cache_file)) { usleep (100000); $ctr++; if ($debug) { echo "
Cache-Datei ist gesperrt ..."; flush(); } if ($ctr>(MAX_CACHE_WAIT_SECS*10)) return $content; clearstatcache(); } $is_locked = lockCacheFile($cache_file); if ($is_locked) { $fp = fopen($cache_file, "w"); if ($fp) { fwrite($fp,$content); // for ($x=0;$x<25;$x++) // { // echo "
Test sleep ... $x"; // flush(); // sleep(1); // } fclose($fp); chmod($cache_file,0777); } } else if ($debug) echo "
Cache-Datei konnte nicht geschrieben werden, " . "weil die Lock-Datei nicht gesperrt werden konnte"; if ($is_locked) unlockCacheFile($cache_file); return $content; } function lockCacheFile($cache_file) { $lock_file = $cache_file.".LCK"; if (is_file($lock_file)) { if (is_writable($lock_file)) { chmod($lock_file,0555); clearstatcache(); return 1; } else return 0; } else { $fp = fopen($lock_file,'w'); if ($fp) { fclose($fp); chmod($lock_file,0555); clearstatcache(); return 1; } else return 0; } } function unlockCacheFile($cache_file) { $lock_file = $cache_file.".LCK"; chmod($lock_file,0777); if (is_file($lock_file)) { unlink($lock_file); clearstatcache(); } } function cacheFileIsLocked($cache_file) { $lock_file = $cache_file.".LCK"; $is_locked = is_file($lock_file); if ($is_locked) return 1; return 0; } function getProtocol() { $proto = $_SERVER["SERVER_PROTOCOL"]; if (preg_match("/^HTTP\/.*$/",$proto)) return 'http'; if (preg_match("/^HTTPS\/.*$/",$proto)) return 'https'; } function getCacheContent($cache_file, $debug) { $ctr = 0; while (cacheFileIsLocked($cache_file)) { usleep(100000); $ctr++; if ($debug) { echo "
Kann Content nicht ausliefern, da Cache-Datei gesperrt ist ..."; flush(); } if ($ctr>(MAX_CACHE_WAIT_SECS*10)) return ""; clearstatcache(); } return file_get_contents($cache_file); } function cleanupCache() { $log = "

Cleanup Cache Script

\n
    "; $def_vars = get_defined_constants(); if (!array_key_exists('CACHE_CLEANUP_TIME',$def_vars)) { $log .= "
  • Konstante CACHE_CLEANUP_TIME ist nicht definiert - breche Cleanup-Skript ab.
"; return $log; } else if (!array_key_exists('CACHECLEANUPFILE',$def_vars)) { $log .= "
  • Konstante CACHECLEANUPFILE ist nicht definiert - breche Cleanup-Skript ab.
  • "; return $log; } else if (!preg_match("/^([0-9][0-9]:[0-9][0-9],{0,1})*$/",CACHE_CLEANUP_TIME)) { $log .= "
  • Konstante CACHE_CLEANUP_TIME '".CACHE_CLEANUP_TIME."' ist im falschen Format - breche Cleanup-Skript ab.
  • "; return $log; } $cachecleanup_file = CACHEDIR.CACHECLEANUPFILE; $cleanup = 0; $err_reporting = ini_get("error_reporting"); ini_set("error_reporting",0); if (file_exists($cachecleanup_file)) { $lastmodified = filemtime($cachecleanup_file); $cachecleanup_file = realpath($cachecleanup_file); $log .= "
  • Cache-Cleanup-Datei $cachecleanup_file existiert.
  • "; $log .= "
  • Cache-Cleanup-Datei $cachecleanup_file wurde letzmals aktualisiert am: ".strftime("%d.%m.%Y %H:%M:%S",$lastmodified)." Uhr
  • "; } else $lastmodified = -1; $cleanuptime_arr = explode(",",CACHE_CLEANUP_TIME); foreach($cleanuptime_arr as $cleanup_time) { $log .= "
  • Checke Cleanup-Time $cleanup_time Uhr
      "; $ct_arr = explode(":",$cleanup_time); if (count($ct_arr)>=2) { $hour = $ct_arr[0]; $minute = $ct_arr[1]; $today = getdate(); $cleanup_timestamp = mktime($hour,$minute,0,$today["mon"],$today["mday"],$today["year"]); $now = time(); $diff1 = $now-$cleanup_timestamp; $log .= "
    • Untersuche Differenz: now()-$cleanup_time=$diff1 Sekunden
    • "; if ($diff1>0) { $log .= "
    • Cleanup-Zeitpunkt ist überschritten
    • "; if ($cleanup_timestamp>$lastmodified) { $cleanup=1; $log .= "
    • Cleanup-Zeitpunkt muss durchgeführt werden.
    • "; } else $log .= "
    • Kein Cleanup erforderlich, weil ".basename($cachecleanup_file)." nach der Cleanup-Zeit" . " $cleanup_time Uhr verändert wurde."; } else $log .= "
    • Kein Cleanup erforderlich. Es dauert noch ".(-$diff1)." Sekunden bis zum nächsten Cleanup.
    • "; } $log .= "
  • "; } if ($cleanup) { $log .= "
  • Führe jetzt Cleanup durch ..."; $files = scandir(CACHEDIR); foreach($files as $key=>$file) { if ($file=='.' || $file=='..' || $file=='.svn' || $file==LASTLOGFILE || $file==CACHECLEANUPFILE) unset($files[$key]); } if (count($files)==0) $log .= "
  • Cache ist leer.
  • "; foreach($files as $file) { $file = realpath(CACHEDIR.$file); $success = 0; if (is_file($file)) { $log .= "
  • lösche Datei $file : "; $success = unlink($file); } else if (is_dir($file)) { $log .= "
  • lösche Verzeichnis $file : "; delTree($file); if (!is_dir($file)) $success = 1; } if ($success) $log .= " gelöscht.
  • "; else $log .= " Löschen fehlgeschlagen."; } $fp = fopen($cachecleanup_file,"w"); fclose($fp); } $log .= "\n\nCleanup beendet."; ini_set($err_reporting); return $log; } function delTree($path) { if (is_dir($path)) { $entries = scandir($path); foreach ($entries as $entry) { if ($entry != '.' && $entry != '..') { deltree($path.DIRECTORY_SEPARATOR.$entry); } } rmdir($path); } else { unlink($path); } } ?>