wir sind gerade in einem Projekt Caching einzuführen, genauer gesagt geht es dabei um das Caching von großen Objekten (heißt > 100kb). Zuvor haben wir das ganze in der Session abgelegt. Da wir diese aber über CDbHttpSession in der Datenbank halten ist das ganze recht schnell an seine Grenzen gestoßen nämlich zu dem Zeitpunkt als das serialisierte Objekt nicht mehr in das Feld der Datenbank gepasst hat.
Das eigentliche Problem ist das wir ein Objekt über einen längeren Zeitraum immer verfügbar haben müssen und auf diesem Objekt auf verschiedenen Seiten Berechnungen durchgeführt werden, das Objekt geupdatet und so weiter.
Nun wollen wir das ganze mit XCache lösen in dem wir das Objekt in den Cache schreiben und dann rausholen wenn wir es brauchen. Das Problem ist nun das wenn das Objekt aus dem Cache geladen wird und es unserealisiert wird irgendwie die Behaviours auf der Strecke bleiben.
[update] Das TimestampUserBehavior gibt es und es funktioniert auch ganz normal bis das Objekt serialisiert und unserialisiert wird. [/update]
Was mach ich falsch? Muss man zuerst die Behaviors entfernen und später dann wieder aktivieren? Funktioniert das mit dem XCache überhaupt so wie wir uns das Vorstellen? Ist es dazu geeignet? Gibt es andere Möglichkeiten das zu realisieren was wir haben wollen?
Ich denke die "normalen" Yii Klassen sind nicht dafür geschrieben, komplett (inkl. Behaviors) serialisiert/deserialisiert zu werden. Aber schau dir doch mal die __sleep() und __wakeup() Funktionen an, damit könntest du deine Klasse anreichern und so die Sache selbst in die Hand nehmen:
Bzgl. XCache frag ich mich, ob es sich um Daten handelt, die sich pro Benutzer ändern, weil ihr ja bisher die Session verwendet habt. D.h. ihr müsst in den Cache-Keys die User-ID mit einfließen lassen. In solchen Fällen verwend ich meistens meine eigene erweiterte WebUser-Klasse und bau Methoden wie getIrgendwas()/setIrgenwas() ein. Dort kannst du dann den Cache Zugriff regeln und im Getter z.B. auch ein neues Objekt erstellen, falls noch keins im Cache vorliegt. Dann kannst du überall mit Yii::app()->user->irgendwas auf dieses Objekt zugreifen und hast das ganze schön gekapselt.
EDIT:
Das Behavior-Problem scheint doch ein anderes zu sein. Sieht aus, als wäre evtl. deine Konfiguration mit den Imports noch nicht geladen, wenn das Objekt Deserialisiert wird. Hmmm. Evtl. mal etwas im Core debuggen?
ja ich bin immer noch dabei das Problem weiter einzugrenzen. Wenn ich in der selben Action den Wert erst setze und dann wieder lese funktioniert alles wunderbar und völlig Problemlos. Wenn ich aber den Wert in einer anderen Action lesen möchte tritt das oben beschriebene Problem auf.
Ich setze die ID durch PHP uniqid("", true) Funktion und führe die für den einzelnen Benutzer . Sollte also schon einigermaßen eineindeutig sein.
Wie sieht denn die Codezeile aus, mit der du versuchst das Objekt zurück aus dem Cache zu lesen? Lass dir an der Stelle mal den PHP include_path anzeigen, um zu sehen, ob das Verzeichnis mit dem Behavior richtig importiert wurde.
Hab das mal genau so in der php.ini geändert, Server auch neu gestartet aber es zeigt keine Wirkung
php.ini
; The unserialize callback function will be called (with the undefined class'
; name as parameter), if the unserializer finds an undefined class
; which should be instantiated. A warning appears if the specified function is
; not defined, or if the function doesn't include/implement the missing class.
; So only set this entry, if you really want to implement such a
; callback-function.
unserialize_callback_func = 'spl_autoload_call'
Ich glaube Y!! hat genau das richtige gefunden. Aber du musst den richtigen Autoloader nehmen (den von Yii). Probier doch mal sowas hier, bevor du dein Objekt aus dem Cache holst:
Dürfte problematisch sein, da man evtl. keinen Array übergeben kann. Dann musst du eine Hilfsfunktion bauen, und entsprechend ‘mein_autoloader’ registerieren:
function mein_autoloader($classname)
{
return YiiBase::autoload($className);
}
Ich sehe gerade wenn ich print_r(esft_autoloader(‘TimestampUserBehavior’)); aufrufe dann findet es die Datei auch nicht. Also an der selben Stelle. Scheint also irgendwie ein generelleres Problem zu sein?
Was gibt es denn aus? Der Autoloader müsste true zurückliefern, wenn die Funktion gefunden wird. Kannst du auch mal Testhalber ein die(‘bla’); oder so in deinen Autoloader einbauen, um zu sehen, ob er überhaupt aufgerufen wird?
Genau das hab ich gerade auch gedacht und Probiert. Also wenn ich nach einer Model Klasse wie beispielsweise meiner Benutzerklasse suche dann geht es Problemlos und der Autoloader gibt mit
true zurück aber mit den Behaviors geht es nicht. Echt komisch. Muss ich das in der Config noch Festlegen in welchen Verzeichnissen nach Dateien gesucht werden soll durch den Autoloader?
Nein, das macht ja YiiBase::autoload() für dich. Wird denn dein Autoloader überhaupt aufgerufen, wenn du unserialize machst? Falls nicht, klappt die unserialize_callback_func Einstellung nicht. Falls er bei unserialize richtig aufgerufen wird, gib dort mal den Include Pfad aus. Yii::import() (was du in deiner Konfig angibts) macht nichts anderes, als diese Verzeichnisse zum include Pfad hinzuzufügen. Yii’s autoloader macht dann ein einfaches include mit dem Klassennamen.