register_globals auf on
FraFu
- php
3 Sven Rautenberg
Hallo!
Ich hab gerade eine (für mich) komische Entdeckung gemacht. Bisher hab ich immer mir register_globals=off gearbeitet. Jetzt hab ich das für Testzwecken mal auf on gestellt.
Folgendes:
In $_SESSION['user_id'] hab ich nach erfolgreichem Login die ID des eingeloggten Users stehen. Das dient auf jeder Seite zur Überprüfung, ob der User eingeloggt ist oder nicht.
Auf der Seite, auf der man die User verwalten kann, wird per GET ein Parameter user_id übergeben.
Ausschnitt aus dem Code:
$user_id=$_GET['user_id'];
$user=new User($user_id);
Nach diesen Zeilen ist in $_SESSION['user_id'] plötzlich nicht mehr die ID des eingeloggten Users, sondern die von $_GET['user_id']
Warum werden bei register_gobals=on die Variablen von $_SESSION mit denen von $_GET besetzt?
Kann das so stimmen oder hab ich noch wo anders einen Fehler in meinem System?
mfg
frafu
Moin!
Ich hab gerade eine (für mich) komische Entdeckung gemacht. Bisher hab ich immer mir register_globals=off gearbeitet. Jetzt hab ich das für Testzwecken mal auf on gestellt.
Was ja böse ist, wie wir wissen. :)
In $_SESSION['user_id'] hab ich nach erfolgreichem Login die ID des eingeloggten Users stehen. Das dient auf jeder Seite zur Überprüfung, ob der User eingeloggt ist oder nicht.
Die Variable $_SESSION steht in jedem Skript nach dem Befehl session_start() zur Verfügung, vorher nicht. Das nur, weil es u.A. in diesem Fall um das Timing geht.
Auf der Seite, auf der man die User verwalten kann, wird per GET ein Parameter user_id übergeben.
Noch bevor dein Skript abläuft, werden mit register_globals=on die globalen Variablen aus $_GET, $_POST und $_COOKIE bevölkert, wobei es als Standardreihenfolge "GPC" gibt, d.h. zuerst GET, dann (ggf. überschreibend!) POST, dann COOKIE.
Wenn die Session gestartet wird, werden auch noch alle definierten Session-Variablen in den globalen Namensraum exportiert - und nach Ende des Skriptes wieder zurück in $_SESSION geschrieben! Das entspricht der Verhaltensweise, die man hat, wenn man globale Variablen mit session_register() zu Sessionvariablen macht.
Bevor dein Code also zur Ausführung gelangt, wurde $user_id zuerst mit dem Inhalt als $_GET['user_id'] gefüllt, und dann beim Session-Start mit dem Inhalt aus $_SESSION['user_id'].
Jetzt kommt dein Code:
$user_id=$_GET['user_id'];
// An dieser Stelle überschreibst du den Wert aus $_SESSION mit dem Wert aus $_GET
$user=new User($user_id);
Am Ende deines Codes wird $user\_id wieder in $\_SESSION gepackt.
Und schwups - schon haben sich die Werte getauscht.
Der Grund ist also dein absolut sinnloses Kopieren von $\_GET['user\_id'] nach $user\_id. Es ist absolut erlaubt und ratsam, $\_GET als read-only-Array (Schreibzugriffe sind aber absolut erlaubt, ich würde sie nur nicht unbedingt empfehlen, weil sie u.U. eher den Code verwirren) zu betrachten, und direkten Zugriff auf darin enthaltene Werte immer direkt aus $\_GET zu füttern.
Dein Code wäre also besser, wenn er nur aus
~~~php
$user = new User ($_GET['user_id']);
bestünde.
Alternativ kannst du natürlich entweder den Schlüssel in $_SESSION oder in $_GET umbenennen, um den Namenskonflikt aufzulösen.
- Sven Rautenberg
Hallo!
Danke für die genauen Ausführungen. Jetzt ist mir vieles klarer.
Dein Code wäre also besser, wenn er nur aus
$user = new User ($_GET['user_id']);
> bestünde.
Ich tippe $user\_id aber leicher als $\_GET['user\_id']. :-)
> Alternativ kannst du natürlich entweder den Schlüssel in $\_SESSION oder in $\_GET umbenennen, um den Namenskonflikt aufzulösen.
Kann ich machen. Danke für die Hilfe!
mfg
frafu
Moin!
Dein Code wäre also besser, wenn er nur aus
$user = new User ($_GET['user_id']);
> > bestünde.
>
> Ich tippe $user\_id aber leicher als $\_GET['user\_id']. :-)
Daran gewöhnst du dich. :) Abgesehen davon siehst du bei jedem eingebauten Zugriff auf $\_GET auch sofort, dass es sich um eventuell als gefährlich zu betrachtende Benutzerdaten handelt. Steht da nur $user\_id, bleibt diese Tatsache eher verborgen.
Und nicht zuletzt: $\_GET steht dir auch in Funktionen und Klassen direkt zur Verfügung, während du $user\_id dort erstmal verfügbar machen mußt.
- Sven Rautenberg
--
My sssignature, my preciousssss!
Hallo,
... was wohin transportiert wird, hängt davon ab, wie die Session gestartet wird. Wenn man die Session mit session_register() startet, wird die Script-Variable in die Session-Variable geschrieben und der Sessionmechanismus gestartet.
Wenn man mit session_start() startet, wird der Sessionmechanismus gestartet, und es funktioniert so, wie Du es beschrieben hast.
LG
Chris
Moin!
... was wohin transportiert wird, hängt davon ab, wie die Session gestartet wird. Wenn man die Session mit session_register() startet, wird die Script-Variable in die Session-Variable geschrieben und der Sessionmechanismus gestartet.
Session_register startet die Session nur, wenn das nicht bereits vorher getan wurde - was man eigentlich besser tun sollte, denn wenn ein Skript sonst keine Sessionvariable registriert, wird die Session ja nicht gestartet, von der Problematik des "Headers already sent" ganz abgesehen.
Außerdem soll man session_register() nicht mehr verwenden.
Wenn man mit session_start() startet, wird der Sessionmechanismus gestartet, und es funktioniert so, wie Du es beschrieben hast.
Ich habe sowieso nur beschrieben, wie konkret in diesem Problemfall der Mechanismus läuft. Die Abwesenheit von session_register() macht es obsolet, diesen Fall zu betrachten. :)
- Sven Rautenberg