Session-Variable in Plugins

  • Hallo zusammen,

    ich hab ein Problem mit $_SESSION von PHP und Wordpress. Das Problem ist, dass ich zwar Werte in $_SESSION-Variablen schreiben kann, diesen Wert dann aber nach dem Seitenwechsel nicht mehr auslesen kann.

    In wp-config.php habe ich die Session mit session_start() gestartet. Ich überprüfe davon sogar, ob es eine Session-ID gibt und setze diese (um ganz sicher zu gehen) vor session_start(). Wordpress sollte also nun auch mit Sessions umgehen können.

    PHP
    // enable Sessions for WP
    if (isset($_GET['PHPSESSID']))
    {
    	session_id($_GET['PHPSESSID']);
    }
    	
    session_start();

    Dies scheint mir auch soweit ok zu sein, da dann in der URL jeweils die PHPSESSID als Argument vorhanden ist. Die Session-ID wird übergeben und beim session_start() auch verwendet (was sich ja mit einem echo-Befehl einfach nachvollziehen lässt).

    Soweit so gut. Zum weiteren Verständnis: Ich versuche mich gerade an Plugins und habe ein Plugin geschrieben, das nichts anderes macht, als ein Top-Level-Menu in der Administratoransicht von WP anzulegen. Unterhalb diesem Top-Level-Menu werden zwei Sub-Menus erzeugt. Das Problem ist nun, dass ich auf der Seite des Top-Level-Menu's eine Session-Variable setzen ([FONT="Courier New"]$_SESSION['TestData'] = "HELLO WORLD";[/FONT]) und deren Wert dann auf den Seiten der Sub-Menus auslesen möchte ([FONT="Courier New"]echo "SessionData:".$_SESSION['TestData'];[/FONT]). Eigentlich ja ganz einfach.

    ... und hier springt der Frosch ins Wasser: Nach dem Seitenwechsel von einem Menü in das nächste gehen mir die Session-Variablen verloren.

    Hat mir irgendjemand einen Tipp oder hat schon jemand ähnliche oder gleiche Erfahrungen gemacht und vielleicht sogar einen Lösungsweg?

    Einmal editiert, zuletzt von Alphawolf (20. August 2008 um 11:45)

    • Anzeige

    Hallo!

    Wenn du gerade an deiner Website arbeitest oder dein aktuelles Hosting überdenkst: Wir betreiben mit NetzLiving eine Hosting-Plattform, die speziell auf Performance, Sicherheit und einfache Verwaltung ausgelegt ist.

    • ✔️ Schnelle Ladezeiten (optimiert für WordPress & Co.)
    • ✔️ Deutsche Server & DSGVO-konform
    • ✔️ Persönlicher Support (kein 0815-Ticket-System)

    Mehr erfahren

  • Problem gefunden in wp-settings.php

    Hallo Leute,

    nachdem ich im Internet nix neues oder hilfreiches zu diesem Thema mehr gefunden habe, habe ich mich halt doch mal an den SourceCode von WordPress herangewagt. So konnte ich wenigstens herausfinden wo der Frosch ins Wasser hüpft...

    Nun ... hier meine Ergebnissse:

    Aus welchem Grund auch immer gibt es in der Datei wp-settings.php eine Funktion names wp_unregister_GLOBALS(). Diese Funktion soll dafür sorgen, dass globale Variablen gesäubert werden. Leider beinhaltet diese Funktion auch $_SESSION. Daher werden bei jedem Aufruf von WordPress sauber die Werte in $_SESSION aufgeräumt bzw. weggeschmissen. Sehr zu meinem Erstaunen, da daher das ganze $_SESSION-Prinzip keinen Sinn macht.

    Um hier nun abhilfe zu schaffen muss man folgende Änderung (Hack) vornehmen:

    Hier der originale Code aus der Version 2.6.0 von WordPress:

    Man beachte dabei die Zeile mit ...[FONT="Courier New"], isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array()[/FONT] ... Hier werden die Werte in $_SESSION in das Array aufgenommen, das schliesslich dann durchlaufen wird, um die Werte aufzuräumen (Was in diesem Falle natürlich nicht in meinem Sinne ist).

    Und hier nun die modifizierte Variante:

    Nach dieser Modifikation läuft das ganze wie gewünscht. Es lassen sich ohne weitere Probleme Werte in $_SESSION schreiben und lesen.

    Vielen Dank für die Aufmerksamkeit und vielleicht hilfts ja auch jemand anderem weiter.

    Cheers,
    Bernd

    Einmal editiert, zuletzt von Alphawolf (20. August 2008 um 11:46)

  • Ist völlig überflüssig, denn wie man mit Sessions umgeht kann man hier nachlesen: PHP: session_start - Manual

    Ergänzung: ... und session_start() benutzt man im Theme (header.php) oder einem eigenen Plugin im init Hook, jedoch nie vor der Initialisierung von WP !

  • ... so nicht ganz richtig ...

    Hallo codestyling,

    dass man session_start() nur im Theme jedoch nie vor der Initialisierung von WP aufrufen sollte ist so nicht richtig, da es unter Umständen sein kann, dass man die Session auf dem Server starten muss bevor irgendetwas zum Client geschickt worden ist. Anderfalls bekommt man einen Fehler, dass die Session nicht gestartet werden kann, da schon mit dem Output begonnen wurde. Dies gilt besonders dann, wenn man Session-Cookies verwenden möchte.

    Unabhängig davon wurde in anderen Foren diese Vorgehensweise vorgeschlagen ... und ausserdem gibt es immer mehrere Wege nach Rom.:-D

    Im Hinblick auf Deine Ergänzung: Wie Du aus meinen vorangegangenen Ausführungen entnehmen kannst ist der Umgang mit Session-Variablen ja auch nicht das Problem. Das Problem liegt eher darin, dass die Session von WordPress bei jedem Aufruf gesäubert wird. Zumindest in der Version 2.6.0. Kannst es ja mal ausprobieren und mir dann mal Bescheid geben, ob Du andere Ergebnisse erzielst. Es sollte ja detailiert genug beschrieben sein, was gewünscht war und welchen Weg ich dazu beschritten habe. Wenn Du noch Fragen zu meiner Vorgehensweise haben solltest, dann kannst Du Dich gerne an mich wenden.:-D

    Andernfalls, wenn Du eine bessere Vorgehensweise (ohne Hack) oder sogar eine gängige Lösung zu diesem Problem bieten kannst, dann wäre ich Dir um so dankbarer.

    Hier ein paar Links für diejenigen, die weitere Informationen brauchen:
    Search › session id
    WordPress › Support » Custom Session Variables Unset immediately?
    WordPress MU › setting a session variable « WordPress MU Forums
    http://forum.wordpress-deutschland.org/design/22863-s…uebergeben.html

    Einmal editiert, zuletzt von taiko1976 (20. August 2008 um 11:14)

  • Warum wird eigentlich immer erstmal alles angezweifelt, was erfahrene WordPresser hier von sich geben... :twisted:

    Hallo codestyling,
    dass man session_start() nur im Theme jedoch nie vor der Initialisierung von WP aufrufen sollte ist so nicht richtig, da es unter Umständen sein kann, dass man die Session auf dem Server starten muss bevor irgendetwas zum Client geschickt worden ist. Anderfalls bekommt man einen Fehler, dass die Session nicht gestartet werden kann, da schon mit dem Output begonnen wurde. Dies gilt besonders dann, wenn man Session-Cookies verwenden möchte.


    Das ist korrekt, aber nicht das was codestyling meinte. Die header.php oder functions.php des Themes wird ebenfalls aufgerufen, bevor irgendwelcher Code an den Client gesendet wird. Aber nach der Initialisierung von WordPress selbst, und im speziellen nach der "Säuberung" der globalen Variablen (was im übrigen ein Sicherheitsfeature ist, was das Scheuentor "register globals" schließt). Codestylings Hinweis sollte dein Problem also lösen. Ansonsten darfst du auch gerne in die Doku gucken, z.B. zum von codestyling angegebenen init-Hook:

    Zitat

    init
    Runs after WordPress has finished loading but before any headers are sent. Useful for intercepting $_GET or $_POST triggers.


    Plugin API/Action Reference « WordPress Codex

  • ... ?

    Hallo Marx,

    wie Du meinst ... wäre nur schön gewesen, wenn an der Aussage von CodeStyle so ausgeführt gewesen wäre, dass man es als kleiner dummer Anfänger auch verstanden hätte, was damit gemeint war. Denn vielleicht sollte man auch die Hintergründe mitgeteilt bekommen, um es verstehen zu können. Daher danke für Deine Ausführungen, die mir den Hintergrund liefern, warum der Vorschlag von CodeStyle besser ist. Das Problem ist halt, dass man von einen Problem mit PHP-Session nicht unbedingt auf den init-Hook kommt, da die Dokumentation über die Verwendung von PHP-Session im Allgemeinen nur dünn gesäht ist ... ausser ich bin in meiner Unwissenheit über die Antwort gestolpert und habe sie als solche nicht erkannt, weil mir die allmächtige Weissheit eines "erfahrenen WordPressers" fehlt.

    Entschuldigt meine Beschränktheit und Ignoranz. Ich werde versuchen mich zu bessern ...

    Einmal editiert, zuletzt von taiko1976 (20. August 2008 um 11:43)

  • Das Problem liegt eher darin, dass die Session von WordPress bei jedem Aufruf gesäubert wird. Zumindest in der Version 2.6.0.


    Das stimmt im Übrigen nicht. WP 2.5.0 und auch WP 2.3.3 (zumindest kenne ich den Code dieser beiden sehr genau) haben das ebenso gehandhabt. Auch in diesen Versionen wurden aus Sicherheitsgründen die angebenen Werte und globals gelöscht, denn die Einbrüche in Server mit register_globals = on sind nun mal ein ernstzunehmendes Problem.
    Die Verwendung von session_start() beginnt eine neue Session oder nimmt eine existierende Session wieder auf, falls diese noch gültig ist. Somit werden alle deine "gemerkten" Session Variablen wieder verfügbar, wenn der session_start() nach der Initialisierung ("Säuberungscode") von WP ausgeführt wird.
    Warum man das als 1. Zeile im header.php, direkt in der functions.php des Themes oder eben per Plugin unter Zuhilfenahme des init Hooks macht, hat MarX ja schon erklärt.
    PS: Die Jungs von WordPress.org sind nicht mit dem Klammersack gepudert und bauen Sachen ein, die eine Sessionverwaltung unmöglich machen.

    Nachtrag wegen Überschneidung der Post:
    Niemand will dich in die Schublade "kleiner dummer Anfänger" legen. Nur in deinen Eingangsposts bist du direkt auf Code-Ebene eingestiegen und mit Modifikationen am WP Kern. Deshalb hat sich meine Antwort auch daran orientiert und ein wenig Programmiererfahrung vorausgesetzt. Sorry, wenn meine Anwort unter falschen Voraussetzungen erfolgte, ich hab manchmal die Angewohnheit, auf dem Niveau zu antworten, was ich aus der Fragestellung meine, erkannt zu haben. Und ich maße mir auch nicht an, "allmächtige Weissheit" zu besitzen, wenn das falsch rübergekommen ist, tut es mir leid.

  • wie Du meinst ... wäre nur schön gewesen, wenn an der Aussage von CodeStyle so ausgeführt gewesen wäre, dass man es als kleiner dummer Anfänger auch verstanden hätte, was damit gemeint war.


    Da kann man nachfragen, wenn man etwas nicht gleich komplett versteht. Aber das ganze erstmal völlig abzulehnen und in Frage zu stellen, obwohl es faktisch korrekt war, ist IMHO der falsche Weg.

    Zitat

    Denn vielleicht sollte man auch die Hintergründe mitgeteilt bekommen, um es verstehen zu können. Daher danke für Deine Ausführungen, die mir den Hintergrund liefern, warum der Vorschlag von CodeStyle besser ist.


    Da hast du wohl recht. Das kann man sicher mit der Angabe von ein paar Doku-Links noch verdeutlichen. Allerdings liefert eine Google-Suche nach "wordpress init hook" direkt die von mir oben verlinkte Seite an erster Stelle.

    Zitat

    Entschuldigt meine Beschränktheit und Ignoranz. Ich werde versuchen mich zu bessern ...


    Wie gesagt, nachfragen kostet nix und zeugt auch nicht von Beschränktheit. Eine angebotene Lösung unversucht als "so nicht richtig" abzulehnen dagegen schon, obwohl man eigentlich gar nicht verstanden hat, was genau die Lösung ist. Und dann noch mit einem solchen Posting nachzutreten kannst du dir dann auch sparen.

    just my 2 cent...

  • ... weitergehend

    wunderbar ... mir ist eine Lösung ohne Hack auch lieber ... gibt weniger Probleme beim nächsten Update.

    Nur stellt sich mir immernoch eine Frage (wenn Ihr euch hier schon als die Helden von WordPress geoutet habt): Zwar hab ich nun die SessionID von PHP für alle Links in der administrativen Ansicht, jedoch in der "normalen" Ansicht ist die SessionID nicht angehängt. Bedeutet das, dass in der "normalen" Ansicht Sessions nicht aktiv sind? Was muss man machen, dass diese in der normalen Ansicht auch angehängt werden?

  • Wie hast du es denn nun genau gelöst? Poste bitte mal deinen Code bisher, daran kann man dann sicher sehen woran es im Frontend hakt. Wenn Cookies erlaubt sind wird die SID vielleicht darüber weitergegeben, und nicht über die URL.

    [SIZE="1"]PS: ich bin nur Mod hier, kein Held. Lass bitte den Sarkasmus. Danke.[/SIZE]

  • Und beim Posten von Code bitte die PHP-Tags benutzen, hab das oben schon überall hinzugefügt, da es die Lesbarkeit verbessert.

    [SIZE="1"]Ich weiß ja nicht, wie's mit euch ist, aber ich bin Mod UND Held. ^^[/SIZE]

    wpseek.com - Die WordPress-Code-Suchmaschine

  • SourceCode vom PlugIn

    [FONT=Arial]Es ist nicht viel, aber hier das PlugIn, wie ich es auf die Schnelle mal zusammengezimmert hab.[/FONT]


    Denke mal, dass ich da noch was vergessen oder übersehen hab.

  • Zum weiteren Verständnis: Ich versuche mich gerade an Plugins und habe ein Plugin geschrieben, das nichts anderes macht, als ein Top-Level-Menu in der Administratoransicht von WP anzulegen. Unterhalb diesem Top-Level-Menu werden zwei Sub-Menus erzeugt. Das Problem ist nun, dass ich auf der Seite des Top-Level-Menu's eine Session-Variable setzen ([FONT=Courier New]$_SESSION['TestData'] = "HELLO WORLD";[/FONT]) und deren Wert dann auf den Seiten der Sub-Menus auslesen möchte ([FONT=Courier New]echo "SessionData:".$_SESSION['TestData'];[/FONT]). Eigentlich ja ganz einfach.

    ... und hier springt der Frosch ins Wasser: Nach dem Seitenwechsel von einem Menü in das nächste gehen mir die Session-Variablen verloren.


    Nach deinem Code vom Plugin zu urteilen, willst du die Session per URL dranhängen (use_trans_sid). Was spricht dagegen, cookies/session cookies zu benutzen, wenn du sowieso cookies für das Admin Interface von WP brauchst ?

    PHP
    $duration = 365*24*60*60;
    @setcookie('MyCookieName','MyManyCookieVars',time()+$duration,'/');

    und dann im Code auswertest über $_COOKIE['MyCookieName'].
    Rücksetzen solltest du es ggf. bei einem logoff Filter, falls es nicht stehen bleiben soll.
    Ich verstehe aber die Absicht nicht ganz, wozu man überhaupt sessions/cookies benötigt, wenn man vom einem Hauptpunkt einen Unterpunkt aufruft. Kannst du das näher erläutern ?

  • Cookies ...

    Hmm ... für das Admin-Interface verwendet WordPress Cookies... Allerdings soll der Standarduser nicht auf das Admin-Interface zugreifen und soll nur mit dem Frontend arbeiten ... und wenn der Standarduser auf seinem Rechner Cookies nicht zulässt, dann wäre die Prozesssicherheit der Anwendung gefährdet. Die Benutzer, die auf das Admin-Interface zugreifen dürfen, denen kann ich auch vorschreiben, dass Sie gefälligst Cookies zulassen zu haben.

    Natürlich stellen Cookies grundsätzlich eine Alternative dar, wenn man einfach voraussetzt, dass der Client Cookies akzeptiert. Allerdings finde ich den Cookie-Mechanismus persönlich auch etwas unschön (Daten auf dem Client-Rechner zu speichern)... und natürlich gibt es auch Vorteile von Cookies ... z.B. dass Daten Session-übergreifend gespeichert werden können. Aber das möchte ich in diesem Fall gerade nicht.

    Deshalb sehe ich als einzige Variante, dass man mit einer Session via SessionID arbeitet, um Session-relevante Daten für die Dauer der Verwendung zu speichern (anmelden - abmelden eines Standardusers).

    Irgendwelche Ideen?

  • Hmm, leider ist der entsprechende Anwendungsfall immer noch unklar.
    Wenn du Benutzern von WP zwar Admin GUI nicht geben willst, aber sie sich dennoch anmelden müssen, um zu "arbeiten", braucht es Cookies.
    Wenn jedoch jeder x-beliebige anonyme User bei dir was machen können soll, trackst du quasi die Bewegung in den Seiten mit. Läuft das Ganze auf ein Seitentracking mit Auswertung hinaus oder kann jeder irgendwas bei deinem Blog "abladen" ohne bekannt zu sein ?

  • ... zum Anwendungsfall und besseren Verständnis ...

    ... also, um den Hintergrund meines Bedürfnisses klar zu machen:

    Es gibt eine Entwicklung, die ich von einiger Zeit gemacht habe. Dabei handelt es sich um eine Arbeitsgruppenverwaltung für das Inter- bzw. Internet. Die Idee ist nun, dass ich die GUI-Verwaltung von WordPress nutzen möchte. Ebenso die Blogging- und ContentManagement - Funktionalität, um eine z.B. andere Daten und Informationen hinterlegen zu können, die nur indirekt was mit der Arbeitsgruppenverwaltung zu tun hat, aber dennoch von Interesse sein könnte. Die Arbeitsgruppenverwaltung verwendet Sessions ohne Cookies. Dabei melden sich Benutzer nicht bei WordPress an sondern bei der Arbeitsgruppenverwaltung direkt. Und das will ich eigentlich auch so belassen, aus schon vorher genannten Gründen.

    Deswegen war die Idee für ein PlugIn für WordPress, das die Arbeitsgruppenverwaltung in die Umgebung von WordPress implementiert. Auf der administrativen Ebene können generelle Zugriffsdaten hinterlegt werden, z.B. Datenbankserver etc. Die soll der "normale" Benutzer auch nicht ändern können. Ein Administrator sehr wohl. Wie das alles genau funktionieren soll... das weiss ich auch noch nicht. Bin ja gerade deshalb am Testen und Ausprobieren, ob ich überhaupt die notwendigen Rahmenbedingungen für mein Vorhaben geschaffen werden können.

    Aber unabhängig von meinem Bedürfnis oder meinen schrägen Ideen sollte es doch möglich sein mit WordPress und PHP-Sessions ohne Cookies arbeiten können, oder? ... oder etwa doch nicht?

    Einmal editiert, zuletzt von taiko1976 (20. August 2008 um 22:00)

  • ... weitere Informationen ...

    Hab heute Abend nochmals ein wenig Zeit investiert und versucht mehr über das Thema im Internet zu finden. Leider war ich nicht erfolgreich. Dennoch hab ich versucht noch ein bischen Licht ins Dunkel zu bringen...

    Ich hab versucht mal sicher zu stellen, dass das PlugIn auch ausgeführt wird, wenn nur das FrontEnd aufgebaut wird, nicht die administrative Seite von WordPress. Dies hab ich versucht indem ich einfach die SessionID in eine Datei schreibe.

    ... und wie es zu erwarten war wird die Session auch brav gestartet. Aber warum (zum Teufel) wird dann im FrontEnd nicht die SessionID den Links hinzugefügt, wie es auf der administrativen Seite ja auch funktioniert? ...

    Kennt einer eine Antwort zu dieser Frage?

  • ... die Lösung?

    Also ... ich hab jetzt glaube ich einen gangbaren Weg gefunden, wie ich das FrontEnd von WordPress zwingen kann Session-IDs in den Links zu übergeben. Hier ist wie ich es gemacht hab:

    Es gibt die Möglichkeit mittels der Filter-Funktionalität bei der Erstellung der Links Einfluss auf die verwendete Adresse zu nehmen. So ist es ein einfaches der Adresse eine Session-ID anzuhängen. Die Filter werden direkt in der PHP-Datei des jeweiligen PlugIns gesetzt. Nachfolgend den SourceCode meines Test-PlugIns:



    Eine Liste der verfügbaren Filter von WordPress findet man hier:
    Plugin API/Filter Reference « WordPress Codex

    Kommentare? Anregungen? Verbesserungsvorschläge? ... oder ist mein Vorgehen hier eventuell wieder nicht Regelkonform? ... wie auch immer ... Danke für eure bisherigen Mühen und Kommentare.:)

    Einmal editiert, zuletzt von taiko1976 (21. August 2008 um 09:56)

  • Da gibt es erstmal kein Einwände nur ein Hinweis für "vermehrte" Session ID's.
    Wenn ein anderes Plugin, aus welchen Gründen auch immer zum Beispiel das hier aufruft:

    PHP
    apply_filter('page_link', $link);

    würde deine Erweiterung erneut die Session ID an den Link anhängen! Ein Test, ob eine Session ID schon im Link drin ist, wäre nicht verkehrt und verhindert sich aufschaukelnde URL's durch Filter-Kaskaden, die gern mal z.B. durch multi-lingual Plugins ausgelöst werden.
    Und für einen Search Engine Bot, sofern deine Seiten indiziert werden können und der Benutzer eine Google oder Alexa Toolbar aktiv im Browser hat, ist die Session ID mit in der gespiderten URL drin, die die Toolbar überträgt und daraufhin den Bot genauso vorbeischickt. Eine Erkennung dafür wäre ggf. auch nötig.
    Wegen Suchmachinen Indizierung samt Session ID finde ich die Verwendungvon Sessions in der URI nicht besonders berauschend, aber das ist Ansichts- und Anwendungssache.

  • Danke für die weiteren Tipps

    Hallo Codestyling,

    danke für die weiteren Tipps. Entsprechende Überlegungen machen natürlich Sinn. Natürlich zeigt sich hier auch der Weitblick. Soweit hatte ich gar nicht gedacht, dass diese Fälle auch eintreten könnten. Naja ... man buddelt halt schon zu lange alleine in seinem eigenen Sandkasten. :-D ... Aber das ist natürlich richtig, dass solche Überlegungen immer auch in die Entwicklung mit einfliessen müssen, um eventuelle unliebsame Nebeneffekte zu vermeiden.

    Also nochmals Danke für die Unterstützung und viele Grüsse an die WordPress-Gemeinde.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!