$_POST ohne Post
Matthias Apsel
- php
Om nah hoo pez nyeetz, alle!
Ist es möglich, das $_POST-array händisch zu füllen etwa für die Weiterleitung nach einem Logout?
~~~php
session_start();
session_destroy();
$hostname = $_SERVER['HTTP_HOST'];
$path = dirname($_SERVER['PHP_SELF']);
$_POST['action'] = 'logout';
header('Location: http://'.$hostname.($path == '/' ? '' : $path).'/index.php');
Ich hielte das für schöner als
`header('Location: http://'.$hostname.($path == '/' ? '' : $path).'/index.php?action=logout');`{:.language-php}
oder gar
`header('Location: http://'.$hostname.($path == '/' ? '' : $path).'/logout.php');`{:.language-php}
Leider ergibt ein Test, dass die erste naiv gedachte Variante nicht funktioniert.
Matthias
--
1/z ist kein Blatt Papier.
![](http://www.billiger-im-urlaub.de/kreis_sw.gif)
Tach!
Ist es möglich, das $_POST-array händisch zu füllen etwa für die Weiterleitung nach einem Logout?
Das $_POST-Array (und auch die anderen) wird von PHP angelegt, nachdem der Webserver den Request zum Abarbeiten übergibt und bevor der Script-Code verarbeitet wird. Am Script-Ende wird es wie alle anderen Variablen aufgeräumt. Abgesehen davon kannst du es auch beschreiben - aber eben nur für deine aktuelle Requestbearbeitung.
Leider ergibt ein Test, dass die erste naiv gedachte Variante nicht funktioniert.
Du kannst keine Variablen von Script zu Script mitnehmen, auch $_* nicht. Lediglich die Session-Variablen werden aufgehoben.
$_POST['action'] = 'logout';
header('Location: http://'.$hostname.($path == '/' ? '' : $path).'/index.php');
Mit dem Location-Header weist du den Browser an, einen neuen Request zu stellen. Es ist nicht vorgesehen, dass der Webserver den neuen Request irgendeinem alten Request zuordnen kann. Wenn du Daten hinüberretten willst, musst du sie dem Browser übergeben, aufdass er sie beim neuen Request wieder mitsendet. Allerdings wüsste ich auch nicht, wie man den Browser dazu bringen kann, einen POST-Request mit vordefinierten Parametern zu stellen - abgesehen von Javascript.
Der Mechanismus, Daten zwischen den Requests auf dem Server zu halten, nennt sich Session. Er beruht darauf, dass der Browser ein eindeutiges Identifikationsmerkmal mitsendet - üblicherweise die Session-ID.
dedlfix.
Om nah hoo pez nyeetz, dedlfix!
Du kannst keine Variablen von Script zu Script mitnehmen, auch $_* nicht. Lediglich die Session-Variablen werden aufgehoben.
Na dann eben nicht.
Der Mechanismus, Daten zwischen den Requests auf dem Server zu halten, nennt sich Session. Er beruht darauf, dass der Browser ein eindeutiges Identifikationsmerkmal mitsendet - üblicherweise die Session-ID.
Die Session soll ja mit dem Klick auf Logout sterben.
Was ist mit dem Wikipedia-Beispiel? Ließe sich dies mit header kombinieren?
Matthias
Hi,
Die Session soll ja mit dem Klick auf Logout sterben.
Na dann gebe ihr diese Info doch einfach als finale Information mit.
Was ist mit dem Wikipedia-Beispiel? Ließe sich dies mit header kombinieren?
Nein. Nicht so, wie du es dir vorstellst. Verstehe den Unterschied zwischen HTTP-Request und HTTP-Response.
MfG ChrisB
Tach!
Was ist mit dem Wikipedia-Beispiel? Ließe sich dies mit header kombinieren?
Wie gesagt, ich wüsste nicht wie. Es gibt da meines Wissens nur den 307er Statuscode. Der veranlasst den Browser temporär anderwo den Request zu wiederholen und dabei die Methode (GET/POST) beizubehalten und vermutlich auch die bereits gesendeten POST-Parameter zu wiederholen. Neue oder andere unterschieben kannst du damit auch nicht. Wenn du den Request nicht nur 1:1 umleiten willst, ist das also auch nichts für dich.
dedlfix.
Die Session soll ja mit dem Klick auf Logout sterben.
Es gäbe noch das gute|böse alte Cookie...
Fred
Om nah hoo pez nyeetz, Fred Furunkelstein 2012!
Es gäbe noch das gute|böse alte Cookie...
ja, nee, schon klar. Es gibt ja eine funktionierende Lösung. Ich dachte halt, es ginge hübscher.
Matthias
Hallo Matthias!
Die Session soll ja mit dem Klick auf Logout sterben.
Wenn du gerade dabei bist, den Logout-Request zu verarbeiten, dann kannst du doch einfach auf $_SESSION zugreifen - zumindest bis diese zerstört hast. Was spricht gegen dieses Vorgehen:
session_start();
$hostname = $_SERVER['HTTP_HOST'];
$path = dirname($_SERVER['PHP_SELF']);
header('Location: http://'.$hostname.($path == '/' ? '' : $path).'/index.php?action='.$_SESSION['target_after_logout']);
session_destroy();
exit();
?
Viele Grüße,
Claudius
Om nah hoo pez nyeetz, Claudius L.!
Ja, genauso läuft es ja auch. Siehe OP.
Matthias
Hallo Matthias,
Ja, genauso läuft es ja auch. Siehe OP.
stimmt, mein Beispiel war schlecht gewählt, weil es deiner "So-soll-es-nicht-sein"-Situation zu ähnlich ist. Der Code, den du im OP gezeigt hast, ist aber doch der, der das Ausloggen übernehmen soll (session_destroy();
). Laut OP willst du nach dem Logout auf eine bestimmte Seite weiterleiten. Da verstehe ich ehrlich gesagt nicht, warum du meinst, irgendwas irgendwo ($_POST;
) zwischenspeichern zu müssen. Könntest du vielleicht nochmal erklären, was wann passieren soll?
Viele Grüße,
Claudius
Om nah hoo pez nyeetz, Claudius L.!
Könntest du vielleicht nochmal erklären, was wann passieren soll?
Ich leite nach dem Logout weiter auf index.php?action=logout. Dort erscheint der Hinweis "erfolgreich ausgeloggt", indem ich das $_GET-Array abfrage.
_Rein *kosmetisch* unschön_ finde ich, dass "action=logout" in der Adresszeile des Browsers steht.
Matthias
Ich leite nach dem Logout weiter auf index.php?action=logout. Dort erscheint der Hinweis "erfolgreich ausgeloggt", indem ich das $_GET-Array abfrage.
_Rein *kosmetisch* unschön_ finde ich, dass "action=logout" in der Adresszeile des Browsers steht.
Äh?
Warum lässt Du nach dem tatsächlichen Logout (Zerstören der Session) nicht einfach den Teil des Skriptes als Funktion abarbeiten, der den Hinweis "erfolgreich ausgeloggt" anzeigt?
Was Du willst (Weiterleitung) erscheint mir wie "von hinten durch die Brust ins Auge"...
Fred
Hallo Matthias,
Ich leite nach dem Logout weiter auf index.php?action=logout. Dort erscheint der Hinweis "erfolgreich ausgeloggt", indem ich das $_GET-Array abfrage.
danke, jetzt hab ich auch verstanden, was du meinst. ;-)
Wie wäre es, nach dem Logout eine neue Session zu starten?
session_destroy();
session_start();
$_SESSION['logged_out'] = true;
header('Location: '/* Weiterleitung zu index.php */);
Und in der index.php:
session_start();
if (isset($_SESSION['logged_out']) && $_SESSION['logged_out']) {
echo '<p>Erfolgreich Abgemeldet</p>';
}
Viele Grüße,
Claudius
Om nah hoo pez nyeetz, Claudius L.!
Wie wäre es, nach dem Logout eine neue Session zu starten?
Die Idee find ich gut.
Matthias
Tach!
Wie wäre es, nach dem Logout eine neue Session zu starten?
Die Idee find ich gut.
Dazu braucht es doch keine neue Session. Es reicht, wenn du in der alten Session das "(un)angemeldet" merkst. Eine Session hat nicht direkt was mit angemeldet/abgemeldet zu tun, sondern dient lediglich ganz allgemein zur Client-Wiedererkennung und Speicherung von Daten. Du musst die Session nicht unbedingt zerstören, PHP räumt sie sowieso selbst weg. $_SESSION = array() oder unset($_SESSION[was_bestimmtes]) täte es auch, um die Daten zu löschen.
Wenn du unbedingt ein "Erfolgreich ausgeloggt" und noch dazu erst nach einer nicht unbedingt notwendigen Umleitung anzeigen willst, kannst du noch ein Zusatz-Flag "gerade abgemeldet" hinzufügen, das du gleich nach dem Abfragen wieder leerst/entfernst. Eine Notwendigkeit der Weiterleitung sehe ich nur, wenn du aus einem POST- einen GET-Request machen willst, damit in der Browser-History kein "sollen daten nochmal senden?" auftaucht.
dedlfix.
Om nah hoo pez nyeetz, dedlfix!
Dazu braucht es doch keine neue Session. Es reicht, wenn du in der alten Session das "(un)angemeldet" merkst. Eine Session hat nicht direkt was mit angemeldet/abgemeldet zu tun, sondern dient lediglich ganz allgemein zur Client-Wiedererkennung und Speicherung von Daten. Du musst die Session nicht unbedingt zerstören, PHP räumt sie sowieso selbst weg. $_SESSION = array() oder unset($_SESSION[was_bestimmtes]) täte es auch, um die Daten zu löschen.
Zur Orientierung diente mir der Wikiartikel.
Daher stammt die Weiterleitungsidee die ich a) sehr gut nachvollziehen kann und b) auch anstandslos funktioniert.
Eine Notwendigkeit der Weiterleitung sehe ich nur, wenn du aus einem POST- einen GET-Request machen willst, damit in der Browser-History kein "sollen daten nochmal senden?" auftaucht.
Wenn du unbedingt ein "Erfolgreich ausgeloggt" und noch dazu erst nach einer nicht unbedingt notwendigen Umleitung anzeigen willst, kannst du noch ein Zusatz-Flag "gerade abgemeldet" hinzufügen, das du gleich nach dem Abfragen wieder leerst/entfernst.
Ja, hab ich so auch umgesetzt.
Matthias
Om nah hoo pez nyeetz, Matthias!
Ich möchte ja beim Mitlesen auch immer etwas dazulernen, deshalb hätte ich da ein paar Fragen ...!
Speicherst du die Session nicht (in einem Cookie)?
Würde sich "dein Problem" nicht vereinfachen, wenn du für Javascript verfügbar/aktiviert die Sache per AJAX machen würdest (und sonst nur einen Fallback)?
_Rein *kosmetisch* unschön_ finde ich, dass "action=logout" in der Adresszeile des Browsers steht.
Da fiel mir beim Lesen gleich mod_rewrite und eine Server Variable (set environment variable) ein ...!
Gruß Gunther
Tach!
Würde sich "dein Problem" nicht vereinfachen, wenn du für Javascript verfügbar/aktiviert die Sache per AJAX machen würdest (und sonst nur einen Fallback)?
Nö, dann käme das ja noch zur Javascript-freien Lösung hinzu.
_Rein *kosmetisch* unschön_ finde ich, dass "action=logout" in der Adresszeile des Browsers steht.
Da fiel mir beim Lesen gleich mod_rewrite und eine Server Variable (set environment variable) ein ...!
Wie stellst du dir das vor? Die Umgebungsvariable bleibt schließlich nicht zwischen zwei Requests bestehen sondern kann lediglich für einen einzelnen Request in der RewriteRule gesetzt werden. Und um diese setzen zu können, muss man erstmal irgendein Merkmal des Requests auswerten können. Das einzig verlässliche unsichtbare dürfte ein Cookie sein. Und den kann man dann auch in PHP auswerten und braucht weder mod_rewrite noch Umgebungsvariable. Aber da sowieso schon eine Session vorhanden ist, kann man die gleich mit verwenden.
dedlfix.
Tach!
Würde sich "dein Problem" nicht vereinfachen, wenn du für Javascript verfügbar/aktiviert die Sache per AJAX machen würdest (und sonst nur einen Fallback)?
Nö, dann käme das ja noch zur Javascript-freien Lösung hinzu.
OK, aber wenn mal davon ausgeht, dass X% der potentiellen Besucher Javascript haben, stellt sich die Frage, ob man überhaupt eine Javascript-freie Lösung braucht.
Denn ehrlich gesagt setzen 99,9% der mir bekannten Seiten wo Sessions wirklich benötigt werden eh JS und Cookies voraus.
_Rein *kosmetisch* unschön_ finde ich, dass "action=logout" in der Adresszeile des Browsers steht.
Da fiel mir beim Lesen gleich mod_rewrite und eine Server Variable (set environment variable) ein ...!Wie stellst du dir das vor? Die Umgebungsvariable bleibt schließlich nicht zwischen zwei Requests bestehen sondern kann lediglich für einen einzelnen Request in der RewriteRule gesetzt werden. Und um diese setzen zu können, muss man erstmal irgendein Merkmal des Requests auswerten können. Das einzig verlässliche unsichtbare dürfte ein Cookie sein. Und den kann man dann auch in PHP auswerten und braucht weder mod_rewrite noch Umgebungsvariable. Aber da sowieso schon eine Session vorhanden ist, kann man die gleich mit verwenden.
Hier geht es doch rein um die "Optik" in der Adresszeile.
Kann man dann nicht den Query String "abschneiden" und stattdessen eine Umgebungsvariable setzen?
Gruß Gunther
Om nah hoo pez nyeetz, Gunther!
Hier geht es doch rein um die "Optik" in der Adresszeile.
Kann man dann nicht den Query String "abschneiden" und stattdessen eine Umgebungsvariable setzen?
Ich hab ihn (lax formuliert) in eine Session-Variable gesteckt. Und nein, ich verwende keine Kekse und mein Projekt setzt zwar JS voraus, aber nicht für Login oder Logout. - Mehr wird nicht verraten ;-)
Matthias
Tach!
Kann man dann nicht den Query String "abschneiden" und stattdessen eine Umgebungsvariable setzen?
Nein, nicht um das angestrebte Ziel zu erreichen. In welcher "Umgebung" willst du die Variable denn setzen? Die einzigen client-/nutzerspezifischen Umgebungen rund um HTTP, die länger als einen Request bestehenbleiben, sind Sessions/Cookies (abgesehen von Querystring und POST-Daten).
dedlfix.
Tach!
Kann man dann nicht den Query String "abschneiden" und stattdessen eine Umgebungsvariable setzen?
Nein, nicht um das angestrebte Ziel zu erreichen. In welcher "Umgebung" willst du die Variable denn setzen? Die einzigen client-/nutzerspezifischen Umgebungen rund um HTTP, die länger als einen Request bestehenbleiben, sind Sessions/Cookies (abgesehen von Querystring und POST-Daten).
Auf dem Server (jetzt mal vorausgesetzt, dass es sich dabei um einen Apache handelt).
SetEnv in Kombination mit mod_rewrite.
Wie gesagt, ich habe keine Ahnung ob das machbar ist. Vorstellen tue ich es mir jedenfalls so:
Prüfe ob QS "action=logout" => falls ja, setzte Umgebungsvariable => rewrite zu REQUEST_URI ohne QS.
Gruß Gunther
*** Der Post von ChrisB scheint aufgrund der Probleme mit dem Forum verlorengegangen zu sein ***
Hi,
Wie gesagt, ich habe keine Ahnung ob das machbar ist. Vorstellen tue ich es mir jedenfalls so:
Prüfe ob QS "action=logout" => falls ja, setzte Umgebungsvariable => rewrite zu REQUEST_URI ohne QS.Nein, nicht machbar.
„rewrite zu“ wird hier tatsächlich ein external redirect sein müssen – und damit, tschüss aktueller Request, hallo neuer Request -> Umgebungsvariablen wieder auf „default“ stellen.
OK, ist wie gesagt überhaupt nicht meine Baustelle, aber ich habe das zumindest bisher so verstanden, dass die gesetzte Umgebungsvariable dann aber immer noch "verfügbar" ist.
Oder andere Variante:
RewriteRule ...php? [L,E=LOGOUT:1]
Gruß Gunther
Tach!
Auf dem Server (jetzt mal vorausgesetzt, dass es sich dabei um einen Apache handelt).
SetEnv in Kombination mit mod_rewrite.
Du meinst wohl eher das in RewriteRule eingebaute Flag env|E. SetEnv hingegen ist unbedingt. SetEnvIf könnte sich auch noch eignen.
Wie gesagt, ich habe keine Ahnung ob das machbar ist. Vorstellen tue ich es mir jedenfalls so:
Prüfe ob QS "action=logout" => falls ja, setzte Umgebungsvariable => rewrite zu REQUEST_URI ohne QS.
In dem Fall muss der Client einen QS schicken, den er auch brav in der URL anzeigt, was ja gerade nicht gewollt ist. Ein Rewrite ist ein interner Vorgang, der ändert am Client nichts. Es bleibt die ursprünglich aufgerufene URL stehen. Sie ändert sich nicht irgendwie von Zauberhand. Um die angezeigte URL zu ändern muss der Browser einen Redirect bekommen, woraufhin er die neue URL aufruft. Damit ist aber der alte Request erledigt und die damals gesetzten Umgebungsvariablen nicht mehr vorhanden, weil jeder Request in einer neuen Umgebung abgehandelt wird.
dedlfix.
Damit ist aber der alte Request erledigt und die damals gesetzten Umgebungsvariablen nicht mehr vorhanden, weil jeder Request in einer neuen Umgebung abgehandelt wird.
Nein. Der Gunther will was anderes.
Der will kein Cookie setzen, sondern mittels header('Location: ...') zu einer hübscheren URL umleiten z.B. "http://examle.com/logout". Der allfällige Request soll dann mittels mod_rewrite wieder durch die index.php abgearbeitet werden. Allerdings kann er da, statt umständlich ENV-Parameter zu setzen, auch die index.php?action=logout angeben - sieht ja keiner.
Einen nochmaligen Request nach einer Antwort mit dem Statuscode 301 oder 302 hat sich der Gunther gerade nicht vorgestellt.
Ich selbst bin übrigens kein Freund dieser "Monsterskripte" in einer index.php. Ich habe da erhebliche Vorbehalte.
Fred
Tach!
Damit ist aber der alte Request erledigt und die damals gesetzten Umgebungsvariablen nicht mehr vorhanden, weil jeder Request in einer neuen Umgebung abgehandelt wird.
Nein. Der Gunther will was anderes.
Der will kein Cookie setzen, sondern mittels header('Location: ...') zu einer hübscheren URL umleiten z.B. "http://examle.com/logout".
Selbst wenn es so wäre, wäre das nicht das ursprüngliche Ziel. Das war, die index.php ohne Anhang einmal in ihrer normalen Form und einmal für einen "Sie haben sich erfolgreich ausgeloggt"-Text zu verwenden. Und das geht ohne Session/Cookie/QS auf keinen Fall - abgesehen vielleicht noch vom unsicheren Referrer.
Wenn der "Sie haben sich erfolgreich ausgeloggt"-Text in einer separaten Ressource erscheinen soll, wäre doch der ganze Aufwand nicht nötig. Dann kann diese den Text direkt ausgeben. Auch wenn mod_rewrite intern zur index.php umschreiben sollte, kann man ohne weiteren Aufwand einfach REQUEST_URI befrage, was denn wirklich angefragt wurde.
dedlfix.
Tach!
Zur Orientierung diente mir der Wikiartikel.
Daher stammt die Weiterleitungsidee die ich a) sehr gut nachvollziehen kann und b) auch anstandslos funktioniert.
Mit je einer Datei für login/logout/auth ist das ja auch recht übersichtlich auseinandergenommen. Aber notwendig ist solch eine Aufteilung nicht. Man kann das alles in einer Seite und mit Fallunterscheidungen einbauen und spart sich so zwei Dateien inklusive deren Wartung.
dedlfix.
Hi,
Wie wäre es, nach dem Logout eine neue Session zu starten?
Die Idee find ich gut.Dazu braucht es doch keine neue Session. Es reicht, wenn du in der alten Session das "(un)angemeldet" merkst.
Halte ich nicht für ausreichend.
Klar, beim nächsten Seitenaufruf wird ggf. ein neuer Login fällig – aber wenn dann dort die Session auch nicht aufgeräumt wird, kann da noch sonstwas benutzerspezifisches drin liegen.
Eine Session hat nicht direkt was mit angemeldet/abgemeldet zu tun, sondern dient lediglich ganz allgemein zur Client-Wiedererkennung und Speicherung von Daten.
Wenn man rein die HTTP-Ebene betrachtet, vielleicht.
Aber in jedem mir bekannten gängigen Web-Authentifizierungssystem wird eine Session als logisch mit einem Benutzer, nicht mit einem Client, zusammengehörig betrachtet.
Du musst die Session nicht unbedingt zerstören, PHP räumt sie sowieso selbst weg. $_SESSION = array() oder unset($_SESSION[was_bestimmtes]) täte es auch, um die Daten zu löschen.
Das ist aber schon mehr als das vorherige ausschließliche „merken von Status unangemeldet“.
MfG ChrisB
Tach!
Dazu braucht es doch keine neue Session. Es reicht, wenn du in der alten Session das "(un)angemeldet" merkst.
Halte ich nicht für ausreichend.
Klar, beim nächsten Seitenaufruf wird ggf. ein neuer Login fällig – aber wenn dann dort die Session auch nicht aufgeräumt wird, kann da noch sonstwas benutzerspezifisches drin liegen.
Wer seine nicht mehr benötigten Daten nicht aufräumt, muss sich nicht wundern, wenn er später wieder drüberstolpert. Ob das Aufräumen nun session_destroy() oder $_SESSION=array() oder unset($_SESSION[daten]) oder sonstwie erfolgt, ist dabei egal.
Eine Session hat nicht direkt was mit angemeldet/abgemeldet zu tun, sondern dient lediglich ganz allgemein zur Client-Wiedererkennung und Speicherung von Daten.
Wenn man rein die HTTP-Ebene betrachtet, vielleicht.
Aber in jedem mir bekannten gängigen Web-Authentifizierungssystem wird eine Session als logisch mit einem Benutzer, nicht mit einem Client, zusammengehörig betrachtet.
Achwas. Man kann Sessions auch zum Datenablegen verwenden, ohne dass ein Nutzername existieren muss. Die Session wird erst dann von client- zu nutzerspezifisch erweitert, wenn ein Nutzeranmeldung erfolgt. Als Shop-Besucher möchte ich aber auch ohne Anmeldung bereits meinen Warenkorb füllen können. Das geht dann nur client-spezifisch.
Du musst die Session nicht unbedingt zerstören, PHP räumt sie sowieso selbst weg. $_SESSION = array() oder unset($_SESSION[was_bestimmtes]) täte es auch, um die Daten zu löschen.
Das ist aber schon mehr als das vorherige ausschließliche „merken von Status unangemeldet“.
Versteh ich nicht, was du damit meinst. Siehst du ein Problem darin, wenn man zusätzlich zum Ändern des Anmeldestatus auch noch nicht mehr benötigte Daten löscht?
dedlfix.
Hi,
Siehst du ein Problem darin, wenn man zusätzlich zum Ändern des Anmeldestatus auch noch nicht mehr benötigte Daten löscht?
Nein – ich hatte angenommen, du wolltest dich ausschließlich auf ersteres beschränken.
MfG ChrisB
hi,
Ist es möglich, das $_POST-array händisch zu füllen etwa für die Weiterleitung nach einem Logout?
In Perl nutze ich dafür CGI::param()
; für PHP habe ich diese Methode, mit dem gleichen Namen, 'nachgebaut' ;)
Die Parameter werden somit nicht mehr direkt aus dem $_POST-Array gelesen sondern aus diesem mit der param()
-Methode. Hinzu kommt ein Array als Puffer für Parameter, die hinzugefügt werden können. Siehe auch array_merge()
.
Hotti