Frage zum Caching mit PHP

Ideal wäre wohl beim erstellen von Inhalt das cachen anzubinden.
Als zweitr Lösung wäre dann die Funktion zumindest den Cache zu leeren.

PHP:
<?php
class cache{
public function __construct($url){}
public function iscache(){}
public function deletecache(){}
pubilc function updatecache(){}
public function insertcache(){}
}
?>

Da kann man sofort nen interface für erstellen und dann für die schnittstellen Datenbank, XML, INI usw. das ganze erstellen.
Schick schick!
 
Aber wie willst du denn das Last Modified Datum prüfen beim löschen einer Datei? Macht ja wenig Sinn aus meiner sicht.

Bzgl. cachen nur wenn sich Inhalt geändert hat ist halt so eine Sache, kann man machen, ist aber "komplizierter in der Anwendung". Ich werde aber beides vorsehen in meiner Caching Klasse. Erstmal berücksichtige ich nur das erstellen nach X Sekunden. Das macht Sinn, wenn man News darstellt ohne irgendwelchen Schnörkel dazu. Hat man aber ein News-Script mit Kommtarfunktion und soll die Anzahl der Kommentare auf der Startseite mit angezeigt werden, macht ein sequentielles Cachen schon Sinn, aber 5 Sek. halte ich auch für zu niedrig. Das liegt aber an der Auslastung des Servers & an der Besucherzahl.

Ideal wäre wohl beim erstellen von Inhalt das cachen anzubinden.
Als zweitr Lösung wäre dann die Funktion zumindest den Cache zu leeren.

PHP:
<?php
class cache{
public function __construct($url){}
public function iscache(){}
public function deletecache(){}
pubilc function updatecache(){}
public function insertcache(){}
}
?>

Da kann man sofort nen interface für erstellen und dann für die schnittstellen Datenbank, XML, INI usw. das ganze erstellen.
Schick schick!
Es geht allerdings nicht um die URL, sondern um die Dateien, die eingebunden werden. Ich denke ich 2-3 Wochen kann ich meine Scripts veröffentlichen. Allerdings fehlt die Website noch, wo Sie veröffentlicht werden sollen *g* - dann können wir darüber nochmal genauer diskutieren, aber dann vielleicht besser nicht hier im Forum.

EDIT:
DeleteCache ist vielleicht bissl überflüssig... ich setz hier gleich mal meine Caching-Klasse rein, wenn das Caching denn gleich wieder läuft...
 
@Radhad
Ich prüfe mit Sicherheit keine gelöschten Dateien :D
Habe das so programmiert,dass ich VOR dem löschen prüfe, ob die Datei existiert - wenn ja, prüfen wie alt sie ist ...wenn zu alt -> dann löschen und neu erstellen, sonst cache laden und anzeigen. Das löschen mache ich eigentlich auch NUR, da lastmodified nach meinen Erkenntnissen auf Windows-Rechnern manchmal lügt -warum weiss ich leider ned mehr, aber da war mal was ...wenn ich wüsste, dass das Änderungsdatum der Datei beim verändern des Inhaltes inzwischen neu gesetzt wird (Leider weiss ich nicht mehr, welche PHP-Version das betrifft), bin ich der letzte, der das nicht umprogrammiert.

ABER:
Weiter oben wurde kurz genannt, dass Cachen mehr festplattenzugriffe verursacht ...ist natürlich logisch - aber interessiert mich das, wenn ich den Webserver gemietet habe ? Ehrlich gesagt ist das Sache des ISP, und nicht mein Problem ...Gut, wenn der Server deshalb ausfällt ists ärgerlich, aber das passiert ja auch nicht jede Woche *denk*
 
Ok, wie versprochen hier meine Caching-Klasse (PHP5), so umgebaut, dass sie einzelne Template-Files cachen kann.
PHP:
<?php
class Caching
{
	private $CacheDir;
	private $Lifetime;
	private $CacheFile;
	public $Content;

	private static $instance = NULL;

	private function __construct($cache_filename, $cache_lifetime = 0)
	{
		$this->CacheDir = "templates_cached".DIRECTORY_SEPARATOR;
		
		$this->Lifetime = $cache_lifetime;
		$this->CacheFile = $this->CacheDir.$cache_filename;
	}
	
	public static function getInstance($cache_filename = "", $cache_lifetime = 0)
	{
		if(self::$instance === NULL)
		{
			self::$instance = new Caching($cache_filename, $cache_lifetime);
			return self::$instance;
		}
		else
		{
			return self::$instance;
		}
	}
	
	public function fileExists()
	{
		if(file_exists($this->CacheFile))
		{
			return true;
		}
		return false;
	}
	
	public function isValid()
	{
		$LastModified = filemtime($this->CacheFile);
		if((time() - $LastModified) > $this->Lifetime)
		{
			return false;
		}
		return true;
	}
	
	public function createFile()
	{
		if(!file_exists($this->CacheFile))
		{
			$handle = fopen($this->CacheFile, "w");
			fclose($handle);
		}
		file_put_contents($this->CacheFile, $this->Content, LOCK_EX);
	}
	
	public function getContent()
	{
		return file_get_contents($this->CacheFile);
	}
}
?>
Die Klasse wird später auf der Seite CodeGroup.de veröffentlicht werden, sobald alles läuft ;)

Falls Kommentare erwünscht sind, füg ich die morgen mal hinzu.


Gruß Radhad
 
Eines versteh ich daran nicht: Warum Singleton Pattern, wenn du mit dem Constructor verschiedene Cache Files behandeln willst? Ab dem zweiten Aufruf liefert es dir das erste gecachte Element - Ob du willst oder nicht :confused:

Singleton ist für eine Caching-Klasse ein netter Ansatz, aber ich würde es anders einsetzen:

PHP:
<?php
interface Cache
{
    /**
     * Cache Directory
     */
    const CACHE_DIR = '/srv/www/vhosts/domain/cache/';

    /**
     * constructor
     */
    private function __construct();

    /**
     * Singleton
     *
     * @return instance of self
     */
    public function getInstance();

    /**
     * Lesen
     *
     * @param string $file (Dateiname)
     * @param integer $expires (Lebensdauer, via filemtime() überprüfen)
     * @param string $path (optionale Unterverzeichnisse in self::CACHE_DIR)
     * @throws Cache_Exception
     */
    public function readCache($file, $expires = 3600, $path = '');

    /**
     * Schreiben
     *
     * @param string $identifier (zB hash des Request Strings
     * @param string $path (optionale Unterverzeichnisse in self::CACHE_DIR)
     */
    public function writeCache($identifier, $path = '');

    // etc
}

Wie du es letztendlich implementierst, ist dir dann überlassen.
Natürlich könntest du alternativ zu den $path Parametern ein Stack an Pfaden anlegen, welches durchprobiert wird (Bei Misserfolg => Exception), aber das ist auch dir überlassen. Ich habs für mich zur Sicherheit, dass die korrekten Daten rauskommen oder eine Fehlermeldung, über eine feste Pfadangabe ohne Stack gelöst.
 
Zuletzt bearbeitet:
Ich hab das Singleton über nen Registry-Pattern, da ich dann immer den gleichen "Pfad zur Instanz" habe.
 
Ist ja schön und gut, aber ich kann mir nicht vorstellen, dass du mehr als eine einzige Cache-Datei damit be- oder verarbeiten kannst, denn
PHP:
    private function __construct($cache_filename, $cache_lifetime = 0)
    {
        $this->CacheDir = "templates_cached".DIRECTORY_SEPARATOR;
        
        $this->Lifetime = $cache_lifetime;
        $this->CacheFile = $this->CacheDir.$cache_filename;
    }
    
    public static function getInstance($cache_filename = "", $cache_lifetime = 0)
    {
        if(self::$instance === NULL)
        {
            self::$instance = new Caching($cache_filename, $cache_lifetime);
            return self::$instance;
        }
        else
        {
            return self::$instance;
        }
    }
erstellt die Instanz einmalig, und Caching::$CacheFile wird nur ein Mal belegt im Constructor, ansonsten bleibt es immer so, da die Instanz nicht immer wieder neu erzeugt wird sondern nur eine Referenz darauf übergeben wird, weil Caching::$instance nach dem Erzeugen nie wieder null annimmt.
Was ist nun, wenn du mehrere Sachen in einem Task cachen möchtest? Funktioniert nach meinem Verständnis des Singleton-Pattern somit nicht mehr.
Ansonsten hast du weder eine Methode implementiert, um den Pfad zu ändern noch eine Möglichkeit, die Lebensdauer zu benennen.

Vor dem file_put_contents solltest du des Weiteren überlegen, die Daten zu serialisieren - Nur für den Fall der Fälle, dass du ein Array oder ein Objekt cachen möchtest, was dann Sinn macht, wenn du nicht nur Templates sondern auch aus der Datenbank gefetchte Datenmengen cachen möchtest - Das ist vor allem dann lohnend, wenn du mehrere Templates zur gleichen Zeit nutzt oder auch einfach lieber die Daten speicherst als die gerenderte Ausgabe.
 
Hm... stimmt, bissl overhead mit dem Singleton. Dann schmeiß ich den raus, denn das Objekt existiert ja eigentlich nicht mehr. Datenbank-Ergebnis brauch ich nicht extra cachen, da ich die dann schon in ein Template einbinde.

Dazu ein Beispiel:
Index.tpl enthält z.B. folgende Anweisung:
Code:
{foreach $array news.tpl}
Bei 10 News würde er 10x die news.tpl in die index.tpl rendern. Das Ergebnis des ganzen wird dann gecacht, als z.B. "index.html".
Das Ziel ist also nur die fertigen Templates zu cachen - bzw. die Einzelteile einer Seite.
 
Zurück