Zum Inhalt springen

Richtig Cachen mit pibase basierter Extension

Erstellt am 19. Mai 2012 · 10 Antworten · letzte Antwort am 8. Oktober 2013

Tags: Cache & Performance, Frage

Unbekannter Benutzer ·

Hi,

ich habe eine stark gewachsene pibase basierte Extension "aufgeräumt". Bisher steckte alles in der Pi1-Klasse, was das reines Chaos war. Ich habe jetzt alles in mehrere Controller unterteilt, so dass man die Extension sauber und strukturiert weiterentwickeln kann.

Es gibt jetzt also einen neuen Ordner "controller", in dem es pro DisplayMode (DetailView, ListView, etc.) eine eigene Controller-Klasse gibt (z.B. class.tx_meineext_displayview_controller.php). In der Pi1-Klasse wird dann nur noch abgefragt, welcher Wert aus dem Flexform kommt und der entsprechende Controller instanziert und aufgerufen.

switch($displayMode)
{
case 'detailView':
   $dVController = t3lib_div::makeInstance('tx_meineext_detailview_controller', $this);
   $content = $dVController->main();
   break;
...
}

Jetzt weiß ich aber nicht wie sich das Caching verhält. Vor meiner Umstruktierung war die Extension gemäß dieser Seite konfiguriert:
http://www.sk-typo3.de/Richtiges-Cachen-mit-pi_base.188.0.html

Nun hab ich das was auf dieser Seite beschrieben wird in jedem Controller nachgebildet. Jeder Controller hat eine eigene "main"-Funktion, welche nach der Instanzierung in Pi1 aufgerufen wird. In einer solchen "main"-Funktion stehen am Anfang folgende Zeilen:

$cache = 0;
$this->getPiBase()->pi_USER_INT_obj = 1;

"getPiBase()" ist eine eigene Funktion um das aktuelle Object der Pi1-Klasse zu erhalten. Sollte jetzt nicht weiter stören.

In der Pi1-Klasse gibt es folgende Klassenattribute:

public $pi_checkCHash = TRUE;
public $pi_USER_INT_obj;

"main"-Funktion in Pi1 setzt auch folgende Variable:

$this->pi_USER_INT_obj = 1;

In der Listenansicht gibt es z.B. eine Sortierfunktion (title, crdate). Die Listenansicht darf also nicht gecachet werden, sonst funktioniert die Sortierung nicht. Mit $this->getPiBase()->pi_USER_INT_obj = 1; im entsprechenden Controller sollte ich also erreichen können, dass nichts gecachet werden soll, oder?

Aber das funktioniert nicht. Ich öffne die Seite, klicke auf die Sortierung und erhalte wieder die Standardausgabe, welche anscheinend beim ersten Seitenaufruf gecachet wurde.

In der ext_localconf.php Datei steht auch folgendes:

t3lib_extMgm::addPItoST43($_EXTKEY, 'pi1/class.tx_meineext_pi1.php', '_pi1', 'list_type', 1);

Was gibt es noch zu beachten?
Kann man die Cache-Steuerung pro Controller überhaupt machen oder gilt das nur für die Pi1-Klasse?

aemka ·

Check doch erst mal selber mit dem Admin-Panel und durch Inspizieren der Cache-Tabellen, ob das funktioniert. Im Grunde sollte es das aber.

Unbekannter Benutzer ·
aemka schrieb

Check doch erst mal selber mit dem Admin-Panel und durch Inspizieren der Cache-Tabellen, ob das funktioniert. Im Grunde sollte es das aber.

Hallo aemka,
danke für deinen Tipp. Folgendes habe ich nun gemacht und dabei "entdeckt":

1.
Im Install-Tool habe ich alle Cache-Tabellen geleert. Die Seiteneigenschaft "Cache deaktivieren" ist nicht aktiv. Darauf hin habe ich die Seite aufgerufen und im Install-Tool gesehen, dass Einträge in "cache_pages" sowie "cache_pagesection", "cache_hash" und "cache_imagesizes" erstellt wurden.

Ein Klick auf die oben beschriebene Sortierfunktion im FE zeigte keine Änderungen in der Ausgabe. Die Seite wurde also vollständig gecachet.

Wenn ich im Backend die Seiteneigenschaft "Cache deaktivieren" einschalte funktioniert die Sortierfunktion im FE wie gewünscht. Die Ausgabe wird entsprechend des ausgewählten Sortierung dargestellt. Im Install-Tool sehe ich, dass die Tabellen "cache_pages" und "cache_pagesection" komplett leer bleiben, jedoch werden die Tabellen "cache_hash" und "cache_imagesizes" gefüllt.

2.
Das ganze Spie nochmal: "Cache deaktvieren" im Backend wieder ausgeschaltet, alle Cache-Tabellen geleert, Seite im FE aufgerufen. Cache-Tabellen wurden wie oben beschrieben gefüllt.

Jetzt klicke ich auf eine Sortierfunktion (z.B. Sortierung nach crdate). Die Ausgabe ändert sicht erst Mal nicht. Nun lösche ich die Cache-Tabellen erneut und klicke erneut auf die gleiche Sortierfunktion. Im Install-Tool sehe ich nun, dass die Seite NICHT gecachet wurde! Ein Klick auf die andere Sortierfunktion (Sortierung nach title) erzeugt die gewünschte Ausgabe, nämlich dass die Liste nach dem Feld "title" sortiert ausgegeben wird. Ein erneuter Blick ins Install-Tool zeigt wieder, dass die Seite nicht gecachet wurde: Tabelle "cache_pages" ist leer, Tabellen "cache_pagesection", "cache_hash" und "cache_imagesizes" sind gefüllt.

Jetzt greift also die Konfiguration im PHP Code und die Seite wird nicht gecachet.

Wenn ich jetzt aber die Seite über die Seiten-Navigation im FE erneut öffne, wird die Seite gecachet! Erst wenn ich die Tabellen wieder leere kann ich im FE sortieren!

Wie zum Geier ist das möglich?
Kann mir das einer bitte erklären?

Unbekannter Benutzer ·

Nachtrag:

Ich habe gerade eben folgende Seite gefunden:

http://www.pi-phi.de/164.html

Hier sind zwei Pi-Klassen dargestellt: Pi1 ist mit aktiviertem Caching und Pi2 ohne aktiviertem Caching.

Jetzt habe ich einfach mal die Konfiguration von Pi2 übernommen und siehe, es wird nicht mehr gecachet bzw. jetzt wird die Seite korrekt gecachet! Die Sortierfunktionen liefern jetzt die entsprechende Ausgabe 🙂

Folgende Änderungen habe ich vorgenommen:

ext_localconf.php

<?php
// ALT
t3lib_extMgm::addPItoST43($_EXTKEY, 'pi1/class.tx_meineext_pi1.php', '_pi1', 'list_type', 1);

// NEU
t3lib_extMgm::addPItoST43($_EXTKEY, 'pi1/class.tx_meineext_pi1.php', '_pi1', 'list_type', 0);
?>

class.tx_meineext_pi1.php

<?php
// ALT
public $pi_checkCHash = TRUE;

// NEU (auskommentiert/gelöscht)
// public $pi_checkCHash = TRUE;
?>

Das Problem hat sich also erst Mal erledigt! Werde es weiterhin beobachten und ggf. mich hier wieder melden.

aemka ·

Nicht cachen ist eigentlcih nicht die richtige Lösung. Ich denke eher du linkst falsch und ohne cHash in der URL, nimm den mal mit rein in der URL-Generierung.

Unbekannter Benutzer ·
aemka schrieb

Nicht cachen ist eigentlcih nicht die richtige Lösung. Ich denke eher du linkst falsch und ohne cHash in der URL, nimm den mal mit rein in der URL-Generierung.

hi,
ok da magst du recht haben. Aber das funktioniert nur bei Links. Ich habe jedoch ein Formular mit lauter Checkboxen. Wie kann ich denn für das "action" Attribut eines Formulars eine URL mit cHash generieren?

Hab das folgendermaßen versucht, jedoch ohne Erfolg. Im Formular "action" Attribut steht der RealUrl Pfad zur angegebenen Seite, jedoch ohne cHash Parameter.

<?php
$this->getCObj()->typoLink_URL(array('parameter'=>$pageid, 'useCacheHash'=>$cache));
?>
Unbekannter Benutzer ·

Nachtrag:

Gerade bin ich über den ersten Kommentar auf folgender Seite gespolter:

http://typo3blogger.de/config-no_cache-1-ist-bose/

von Jonas am 05. August 2009 um 12:50

Oft möchten Entwickler ein pi1 gecacht haben aber nicht wenn ein Formular ausgefüllt wird.

Das Problem dabei ist, dass oft der cHash falsch gesetzt wird, dadurch setzt TYPO3 auf no_cache. Der cHash kann für ein Formular aber nicht richtig gesetzt werden, wenn dieses irgend eine individuelle eingabe zulässt.

Deswegen muss man dort mit einer TypoScript condition arbeiten, welche den Parameter abfragt und die Extension auf USER_INT setzt, wenn einer gesetzt ist. Sonst ist die Extension auf USER und damit im gesamtcache der Seite.

Beispielsweise ist felogin per default auf USER_INT, was den cache von vielen Seiten verlangsamt. Mit zwei drei Zeilen TypoScript kann man felogin aber perfekt als USER/vollgecachte ERweiterung einrichten, so dass im normalzustand (ohne eingabe) alles gecacht wird.

Das ist auch für static_file_cache wichtig.[...]

Wie hat er den Vorschlag mit Typoscript gemeint? Soll das Formular einen speziellen URL Parameter mitsenden (z.B: formSend=1) den man in Typoscript abfrägt und ggf. das ganze Plugin (Pi1) auf USER_INT setzen?

[globalVar = GP:tx_meineext_pi1|formSend=1]
plugin.tx_meineext_pi1 = USER_INT
[global]

In ext_localconf.php das Plugin dann standardmäßig als USER anlegen (letzter Parameter => 1):

<?php
t3lib_extMgm::addPItoST43($_EXTKEY, 'pi1/class.tx_meineext_pi1.php', '_pi1', 'list_type', 1);
?>

Was ist mit diesen zwei Einstellungen in Pi1 und Controllern?

<?php
// Pi1 Klassen-Attribut
public $pi_checkCHash = TRUE;

// Ausschnitt main-Funktion
public function main($content, $conf)
{
   $this->pi_USER_INT_obj = 1;
   ...
}
?>

Wie sollten diese nun definiert werden, so dass nur einzelne Controller als USER_INT gelten, der Rest aber als USER läuft?

Muss man noch weitere Anpassungen vornehmen?

Unbekannter Benutzer ·

Zweiter Nachtrag:

Ich habe es nun folgendermaßen probiert und es scheint zu funktionieren!

1.
Plugin standardmäßig auf Typ USER setzen (siehe Einstellung für ext_localconf.php aus vorherigem Post).

2.
In Pi1-Klasse:

<?php
// Klassenattribute aktiviert/eingefügt
public $pi_checkCHash = TRUE;
public $pi_USER_INT_obj;

// In main()-Funktion ganz oben eingefügt:
public function main($content, $conf)
{
   $this->pi_USER_INT_obj = 0;
   ...
}
?>

Die Controller, die nicht gecachet werden dürfen (z.B. mein Controller für das Formular) habe ich mittels $this->getPiBase()->pi_USER_INT_obj = 1; als USER_INT definiert.

Bei allen anderen Controllern, welche gecachet werden dürfen, steht folgendes:

<?php
$cache = 1;
$this->getPiBase()->pi_USER_INT_obj = 0;

// z.b ein Link für die Sortierung nach "Alphabet"
$sortingABC = $this->getPiBase()->pi_linkTP_keepPIvars('ABC', array('sorting'=>'abc'), $cache);
?>

Wichtig hierbei ist der Parameter $cache am Ende von pi_linkTP_keepPIvars(). Dadurch wird der generierte Link um den URL-Parameter cHash erweitert.

3.
Damit $this->getPiBase()->pi_USER_INT_obj = 1; überhaupt greift und das Plugin wirklich als USER_INT Obejct geladen wird brauchen wir folgendes Typoscript:

[globalVar = GP:tx_meinext_pi1|user_int=1]
plugin.tx_meinext_pi1 = USER_INT
[global]

Bedeutet also, jedes Mal wenn ich das Plugin als USER_INT Object laden möchte, muss ich den URL-Parameter tx_meineext_pi1[user_int]=1 mitsenden. Fehlt dieser Parameter wird das Plugin mit der Standardeinstellung geladen, also als USER Object.

Für mein Formular habe ich also einfach ein Hidden-Feld eingefügt, welches bei jedem Absenden des Formulars mitgesendet wird.

Erste Tests waren bisher positiv. Ich hoffe ich habe nichts vergessen. Falls doch, bitte ergänzen! 🙂

Ich denke diese "Anleitung" wird sicherlich vielen eine große Hilfe sein.

Unbekannter Benutzer ·
aemka schrieb

Jap, so sollte man das tun. Bei Formularen mache ich auch einen USER_INT draus.

Dann sind wir uns ja jetzt einig 😉

Problem ist für mich gelöst!

WaltherMacht ·

Wie sieht das denn für Typo mit Extbase/Fluid die es seit Version 4.x gibt aus?

Die zwei folgenden Funktionen (pi) werden in meiner IDE als nicht vorhanden markiert und die Ausgabe im Frontend zeigt eine leere Seite.
Die folgenden Anweisungen habe ich in meinem Controller sucheAction() implementiert:

$this->getPiBase()->pi_USER_INT_obj = 0;

$sortingABC = $this->getPiBase()->pi_linkTP_keepPIvars('ABC', array('sorting'=>'abc'), $cache);