PHP: Session
AirMax
- programmiertechnik
Hallo zusammen
Ich habe gerade meine erste Session gebastelt - und sie funktioniert sogar einwandfrei *freu*. Ich nutze sie für einen Login-Bereich, um die Usereingabe auf dem Server temporär zu speichern (besser gesagt nur den Benutzernamen - ohne Passwort). Die SID lege ich in einem Cookie ab. Jetzt fiel mir aber ein, dass es nicht so clever ist die SID in einem Cookie abzulegen. Wenn jemand die Cookies nämlich deaktiviert hat, dann ...
Als Alternative würde ich sie nun in einem 'hidden input' dem Formular anhängen. Jetzt habe ich aber dazu folgende Frage: Wird bei der Uservalidierung, falls die Eingaben ungültig sind und das Formular wieder aufgerufen wird, jedes Mal eine neue Session erstellt sammt SID? Falls ja, wäre das unnötig erzeugter Datenmüll. Wäre die Alternative dann nur die Übergabe der SID _NACH_ erfolgreicher Validierung per GET a la:
header('location: http://' . $_SERVER['SERVER_NAME'] . '/path/*.php?PHPSESSID=.....');
Ich hoffe, Ihr reißt mir nicht den Kopf ab, falls das Thema schon bis zum Erbrechen behandelt wurde.
Wäre für Eure Tipps oder links sehr dankbar!
Gruß
AirMax
Hi,
Die SID lege ich in einem Cookie ab. Jetzt fiel mir aber ein, dass es nicht so clever ist die SID in einem Cookie abzulegen. Wenn jemand die Cookies nämlich deaktiviert hat, dann ...
Da haben sich die PHP-Entwickler längst vor dir Gedanken drum macht ...
Als Alternative würde ich sie nun in einem 'hidden input' dem Formular anhängen.
Das geschieht schon automatisch, wenn in der Konfiguration die Optionen session.use_only_cookies auf 0/off und session.use_trans_sid auf 1/on stehen*. So lange noch nicht fest steht, ob die Übermittlung der SID per Cookie vom Client zurück an den Server erfolgreich war, wird sie dann immer wieder per GET?POST übergeben.
Jetzt habe ich aber dazu folgende Frage: Wird bei der Uservalidierung, falls die Eingaben ungültig sind und das Formular wieder aufgerufen wird, jedes Mal eine neue Session erstellt sammt SID?
Was verstehst du unter Uservalidierung?
Sofern du im Script, an welches du die Formulardaten sendest, die Session wieder aufnimmst, sollte es kein Problem geben.
Ich hoffe, Ihr reißt mir nicht den Kopf ab, falls das Thema schon bis zum Erbrechen behandelt wurde.
Ich weiss, dass Anfänger oft Probleme mit dem Konzept der Sessions und ihrer Umsetzung in PHP haben - und kann mir das nur so erklären, dass viel mehr Magie hineininterpretiert wird, als eigentlich vor sich geht.
Sieh $_SESSION als Variable an, in der du Werte hinterlegen kannst, die auch in einer nachfolgend vom gleichen Client angeforderten Instanz eines anderen (oder des gleichen) Scriptes immer noch zur Verfügung stehen.
Alles, was du im Normalfall dafür tun musst ist, session_start zu Beginn jeden Scriptes aufrufen.
MfG ChrisB
* Ob die Konfiguration auf deinem Webspace dem entspricht, kannst du feststellen, wenn du den entsprechenden Abschnitt der Ausgabe von phpinfo() mit der Liste der Session-Einstellungen im Manual abgleichst. Vorrangig interessant wären hier erst mal session.use_cookies/session.use_only_cookies sowie session.use_trans_sid und url_rewriter.tags.
Bei Abweichungen kannst du ggf. eine Änderung per .htaccess/eigener php.ini im Verzeichnis erreichen; oder du machst es (in jedem Script!) über ini_set().
Hi ChrisB
So lange noch nicht fest steht, ob die Übermittlung der SID per Cookie vom Client zurück an den Server erfolgreich war, wird sie dann immer wieder per GET?POST übergeben.
Das ist natürlich praktisch.
Was verstehst du unter Uservalidierung?
Ich gleiche die Benutzereingaben mit einer Datenbank ab. Falls keine Übereinstimmung: Formular ruft dich selbst wieder auf. Falls: Übereinstimmung: header ('...');
Ich weiss, dass Anfänger oft Probleme mit dem Konzept der Sessions und ihrer Umsetzung in PHP haben - und kann mir das nur so erklären, dass viel mehr Magie hineininterpretiert wird, als eigentlich vor sich geht.
Ich muss sagen, dass Sessions einfacher sind, als ich dachte. Im Grunde ist es ja nur ein Fünfzeiler.
Danke Dir zunächst für Deine Tipps zur späten Stunde. Ich werde mal den Cookie außen vor lassen und sehen, was passiert. Falls es Probleme gibt, melde ich mich wieder.
Gruß
Hi,
Ich gleiche die Benutzereingaben mit einer Datenbank ab. Falls keine Übereinstimmung: Formular ruft dich selbst wieder auf. Falls: Übereinstimmung:
header ('...');
In letzterem Fall solltest du die Session-ID selber übergeben, das macht PHP bei einem Location-Header nicht automatisch.
Hierfür kannst du die Konstante SID benutzen - die ist leer, wenn PHP bereits erkannt hat, dass es Cookies nutzen kann.
Wenn nicht, dann enthält sie den Text sessionname=sessionid, den du per ?SID bzw. wenn schon ein Querystring vorhanden ist per &SID an die Adresse des Location-Headers anhängen kannst. (Wenn du ? bzw. & nicht anhängen willst, wenn SID gar keinen Inhalt hat, dann fragst du das eben vorher auch noch mit ab.)
MfG ChrisB
Hi,
Ich gleiche die Benutzereingaben mit einer Datenbank ab. Falls keine Übereinstimmung: Formular ruft dich selbst wieder auf. Falls: Übereinstimmung:
header ('...');
In letzterem Fall solltest du die Session-ID selber übergeben, das macht PHP bei einem Location-Header nicht automatisch.
Wäre auch zu schön, um wahr zu sein ...
Hierfür kannst du die Konstante SID benutzen - die ist leer, wenn PHP bereits erkannt hat, dass es Cookies nutzen kann.
Wenn nicht, dann enthält sie den Text sessionname=sessionid, den du per ?SID bzw. wenn schon ein Querystring vorhanden ist per &SID an die Adresse des Location-Headers anhängen kannst. (Wenn du ? bzw. & nicht anhängen willst, wenn SID gar keinen Inhalt hat, dann fragst du das eben vorher auch noch mit ab.)
Das ist ein guter Tipp. Das heisst also, wenn Cookies akzeptiert werden, habe ich eine 'schöne' URL. Falls nicht, eine URL mit Querystring.
Noch eine andere Frage:
Ich habe zu Testzwecken mal echo session_save_path();
ausgegeben um zu schauen, wo PHP die Sessions abspeichert. Auf einem Windowsrechner war es 'C:/Windows/temp' (o.ä.). Unter MAC OS spuckt PHP mir nichts aus. Nicht einmal einen Parse-Error. Ich kann also nicht sehen, wo was gespeichert wird. Woran liegt denn das? Mach' ich einen Fehler?
Gruß
Hi!
Ich habe zu Testzwecken mal
echo session_save_path();
ausgegeben um zu schauen, wo PHP die Sessions abspeichert. Auf einem Windowsrechner war es 'C:/Windows/temp' (o.ä.). Unter MAC OS spuckt PHP mir nichts aus. Nicht einmal einen Parse-Error. Ich kann also nicht sehen, wo was gespeichert wird. Woran liegt denn das? Mach' ich einen Fehler?
Verwende für Testausgaben var_dump(), denn das zeigt im Gegensatz zu echo immer etwas an. Man kann dann auch zwischen Leerstring, false und null unterscheiden, für die ein echo keine Ausgabe erzeugt. In deinem Fall wirst du einen Leerstring sehen, denn das ist der Default-Wert von session.save_path. Du musst das also noch konfigurieren.
Das Session-Handling ist ja im Grunde genommen einfach (session_start() und $_SESSION verwenden), aber der Teufel steckt auch mal wieder im Detail. Es wird nämlich nicht zu jeder Session einzeln gespeichert, wann sie ausläuft, sondern nur der Zeitpunkt der letzten Änderung. Der Garbage Collector läuft auch nur dann, wenn ein PHP-Script anfängt, mit Sessions zu hantieren. Er unterscheidet dabei nicht zwischen (projekt)eigenen Sessions und anderen. Er putzt alles was er in seinem session.save_path findet. Und für die Berechnung des Timeouts hat er nur die Werte zur Vefügung, die für das gerade laufende Script eingestellt sind. Wenn du unterschiedliche Zeitwerte in verschiedenen Projekten verwendest, aber einen gemeinsamen session.save_path, dann räumen dir die von anderen Projekten aufgerufenen Garbage Collectoren deine Sessions früher auf, als du vorgesehen hast. Es ist also sinnvoll, jedem Projekt seinen eigenen session.save_path zu verpassen.
Lo!
Hallo Lo,
Das Session-Handling ist ja im Grunde genommen einfach (session_start() und $_SESSION verwenden), aber der Teufel steckt auch mal wieder im Detail. Es wird nämlich nicht zu jeder Session einzeln gespeichert, wann sie ausläuft, sondern nur der Zeitpunkt der letzten Änderung. Der Garbage Collector läuft auch nur dann, wenn ein PHP-Script anfängt, mit Sessions zu hantieren. Er unterscheidet dabei nicht zwischen (projekt)eigenen Sessions und anderen. Er putzt alles was er in seinem session.save_path findet. Und für die Berechnung des Timeouts hat er nur die Werte zur Vefügung, die für das gerade laufende Script eingestellt sind. Wenn du unterschiedliche Zeitwerte in verschiedenen Projekten verwendest, aber einen gemeinsamen session.save_path, dann räumen dir die von anderen Projekten aufgerufenen Garbage Collectoren deine Sessions früher auf, als du vorgesehen hast. Es ist also sinnvoll, jedem Projekt seinen eigenen session.save_path zu verpassen.
Das ist noch gut zu wissen. Ich hätte jetzt ein zentrales Verzeichnis angegeben. Danke für die Theorie!
Gruß
Hallo zusammen,
Verwende für Testausgaben var_dump(), denn das zeigt im Gegensatz zu echo immer etwas an. Man kann dann auch zwischen Leerstring, false und null unterscheiden, für die ein echo keine Ausgabe erzeugt. In deinem Fall wirst du einen Leerstring sehen, denn das ist der Default-Wert von session.save_path. Du musst das also noch konfigurieren.
Ich habe mal versucht den session.save_path per ini_set()
zu ändern:
ini_set('session.save_path', $_SERVER['DOCUMENT_ROOT'] . '/data');
session_start();
Aber wenn ich es lokal teste, scheint es ein Problem mit den Zugruffsrechten zu geben: "open(/Library/WebServer/Documents/data/sess_446bc904c6990b3bd2aaec5752eb4e6c, O_RDWR) failed: Permission denied (13)". Wenn ich es auf dem eigentlichen Webserver teste, kann ich ebenfalls nicht auf $_SESSION zugreifen. Kann mir einer einen Lösungsansatz geben? Danke!
Gruß
AirMax
Hi,
Ich habe mal versucht den session.save_path per
ini_set()
zu ändern:
ini_set('session.save_path', $_SERVER['DOCUMENT_ROOT'] . '/data');
session_start();
>
> Aber wenn ich es lokal teste, scheint es ein Problem mit den Zugruffsrechten zu geben: "open(/Library/WebServer/Documents/data/sess\_446bc904c6990b3bd2aaec5752eb4e6c, O\_RDWR) failed: Permission denied (13)".
Und wie sieht es mit den Zugriffsrechten für das genannte Verzeichnis aus - haben Webserver/PHP darauf Lese- und Schreibrecht?
MfG ChrisB
--
“Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
Hi ChrisB,
Und wie sieht es mit den Zugriffsrechten für das genannte Verzeichnis aus - haben Webserver/PHP darauf Lese- und Schreibrecht?
Hatte gerade nochmals gegoogelt und danach die Zugriffsrechte für das Verzeichnis dementsprechend angepasst (zumindest bei mir lokal). Jetzt legt PHP auch die Sessions in dieses Verzeichnis. Aber auf dem Zielserver klappt es nachwievor nicht. Also werde ich mit denen mal Kontakt aufnehmen & nachfragen, wie mit Zugriffsrechten aussieht, oder?!
Oder gibt's noch Alternativen?
Gruß
BTW: Gibt es einen funktionellen Unterschied zwischen session_save_path()
und session.save_path?
Hallo
BTW: Gibt es einen funktionellen Unterschied zwischen
session_save_path()
und session.save_path?
Nein. Ersteres ist halt eine Funktion, mit der du den Pfad setzen und ausgeben kannst, Letzteres ist der Name der entsprechenden Einstellung in der php.ini.
Tschö, Auge
Hallo, ich darf da mal noch ne Frage dran hängen.
Ich denke auch gerade über Sessions nach und bin auf der Suche nach einem guten Tutorial, das den richtigen Mittelweg zwischen den Minimalanforderungen und seitenweisen Beschreibungen einzelner Befehle geht.
Soll heißen ich wüsste einfach nur gerne, wie ich mir eine einfache und trotzdem sichere und dem Stand der Zeit entsprechende Sessionverwaltung einrichte.
Hat da jemand ne gute Seite?
Grad les ich z.B. etwas von jemandem, der in seinen Beschreibungen nicht mal zwischen der Session an sich und Sessionvariablen unterscheidet. Schwer zu lesen. Da vermutet man dann auch kein großes Hintergrundwissen mehr.
Hi!
Soll heißen ich wüsste einfach nur gerne, wie ich mir eine einfache und trotzdem sichere und dem Stand der Zeit entsprechende Sessionverwaltung einrichte.
Was konkret willst du erreichen? Die Sessions verwaltet PHP für dich schon recht gut, solange du nicht händisch eingreifst. Und wenn du das tust, solltest du nicht nur die Hälfte wissen und mehr Ungewolltes einstellen als Nützliches. Zumindest solltest du dir ansehen, was es alles gibt. Die beiden wesentlichen Themen, die man möglicherweise anpassen will sind die Cookie-Verwaltung und der session.save_path.
Hat da jemand ne gute Seite?
Ich nicht, ich lese nur noch im PHP-Handbuch.
Lo!
Na das ist doch schon mal ein Hinweis.
Was konkret willst du erreichen?
Ich will halt nicht nur das nötigste tun damit überhaupt was geht, sondern es richtig machen und auch kapieren was und warum ich da tu.
Die zwei Dinge werd ich mir mal angucken. Danke!
Hi,
Ich will halt nicht nur das nötigste tun damit überhaupt was geht, sondern es richtig machen und auch kapieren was und warum ich da tu.
Na dann mach' dir klar, wie Sessions funktionieren - und schau dir dann anschliessend an, welche Einstellungsmöglichkeiten es gibt (Handbuchseite wurde ja schon genannt), und wie deren Werte sich ggf. beeinflussen.
Das Konzept „Session” dient dazu, einem Client, der über das zustandslose Protokoll HTTP Anfragen stellt, über mehrere nacheinander erfolgende Anfragen hinweg Daten zuordnen zu können.
Dazu musst der Client identifizierbar gemacht werden, denn das wie gesagt zustandslose Protokoll HTTP gibt das nicht her.
Dazu dient die Session-ID. PHP denkt sich beim ersten Start der Session eine aus, und teilt sie dem Client mit. Und der Client schickt sie bei den nächsten Anfragen wieder mit, um sich zu „identifizieren” - ”hey, ich bin der, dem du gerade den Wert 'xyz123...' genannt hast, erinnerst du dich?”.
Es gibt verschiedene Möglichkeiten, die Übergabe dieser Session-ID vom Server an den Client und zurück zu realisieren - wobei man eigentlich nur zwischen den zweien, per Cookie oder anders, unterscheiden muss.
Per Cookie ist klar - Server setzt Cookie, Client akzeptiert diesen und schickt ihn bei allen folgenden Anfragen wieder mit.
Das ist erst mal der Default (in aktuellen PHP-Installationen). Ein paar Details kann man dazu noch einstellen, Parameter, die den Umgang mit dem Cookie beeinflussen (Gültigkeitsdauer, [Sub-]Domain, Pfad, ...)
Wenn der Client keine Cookies akzeptiert, dann muss die Übertragung der Session-ID anders erfolgen - iaR. entweder per GET (bei Links), oder per POST (bei Formularen mit entsprechender Methode).
Das macht PHP seit einiger Zeit nicht mehr per Default automatisch - man muss es extra aktivieren. Dazu schrieb ich in dieser Antwort in der Fussnote schon etwas.
Die Daten, die über die Laufzeit einzelner Scriptinstanzen hinaus erhalten bleiben sollen, müssen natürlich serverseitig auch irgendwo abgelegt werden. Per Default passiert dies im Dateisystem (kann aber auch anderswo sein, bspw. in einer Datenbank oder im RAM; dazu gibt es auch die Möglichkeit, einen eigenen Session-Handler zu definieren, die sich dann um „alles” - Speicherung, Einlesen, Aufräumen alter Daten - kümmern muss) - hier ist die schon erwähnte Einstellung session.save_path von besonderem Interesse, auch in Bezug auf das folgende:
Die Daten, die serverseitig abgelegt werden, müssen natürlich auch irgendwann mal wieder weggeräumt, entsorgt werden. Darum kümmert sich der Garbage Collector - der wird zufallsgesteuert aufgerufen, und löscht die Daten von Sessions, die ihre mit session.gc_maxlifetime angegebene „Lebensdauer” überschritten haben. Diese wird vom Zeitpunkt des letzten Zugriffes (der je nach verwendetem Speichersystem leicht unterschiedlich definiert sein kann) aus gemessen. Wobei die Benennung dieser Option leicht unglücklich ist - denn es handelt sich nicht um eine maximale, sondern eine *minimale* Lebensdauer; alles, was älter ist, *darf* weggeräumt werden, muss aber nicht sofort.
Dass man ggf. den save_path für unterschiedliche Anwendungen auch unterschiedlich definieren möchte, damit sich die „verschiedenen” Garbage-Kollektoren nicht in die Quere kommen, wurde im Thread ja bereits erwähnt.
Wie gesagt, einfach mal ein bisschen im Manual die Beschreibung der einzelnen Optionen durchlesen und schauen, wo sie im geschilderten Konzept „auftauchen” - dann sollte eigentlich das meiste schon klar werden. Wenn noch was unklar bleibt, dann einfach noch mal nachfragen.
Und wenn die Konfiguration dann erst mal den Ansprüchen genügend vorgenommen wurde - dann sind Sessions letztendlich wirklich simpel.
Man muss nur in jedem Script die Session wieder aufnehmen, und hat dann in $_SESSION die in vorherigen, durch den gleichen Client aufgerufenen Scriptinstanzen abgelegten Werten wieder zur Verfügung.
MfG ChrisB
Hallo,
also ich bin der Meinung, dass session das alles selber regelt. https://forum.selfhtml.org/?t=193435&m=1292270
du machst selbst garnix, außer session_start(). wenn das formular korrekt ausgefüllt wurde, setzt du $_SESSION["irgendwas"] = true; dann checkst du bei jedem weiteren aufruf, ob $_SESSION["irgendwas"] existiert. wenn nicht, ist es nicht dieselbe/irgendeine session. dann kommt das anmeldeformular.
Gruß
jobo