Lukas Oklener: Userbereich

Guten Tag

Ich bin gerade dabei, einen Userbereich in PHP zu erstellen.

Dazu habe ich probeweise zwei Dateien angelegt (start.php und chat.php)

In beiden Dateien steht:

<?php

session_start();

if ($HTTP_POST_VARS[$login]) {
session_register("username");
session_register("passwort");
}
elseif ($HTTP_POST_VARS[$logout]) {
session_destroy();
}

echo "<br><br><br><hr>";
?>

<?php
if (!$username) :
?>
Username: Gast (nicht eingeloggt)<br>
<form action="<?php echo $PHP_SELF ?>" method="post">
<input type="hidden" name="login">
Username: <input type="text" name="username"><br>
Passwort: <input type="text" name="passwort"><br>
<input type="submit" value="Login">
</form>
<?php
else :
?>
Username: <?php echo $username ?> (registriert)
<form action="<?php echo $PHP_SELF ?>" method="post">
<input type="hidden" name="logout">
<input type="submit" value="Logout">
</form>
<?php
endif;
?>

<br>
<a href="chat.php4">Chat</a>

Nur die letzte Zeile (<a href="chat.php">Chat</a>) ist in der Datei chat.php:
<a href="start.php">Start</a>

Wenn ich mich nun auf der Seite start.php einlogge (beliebiger Username und beliebiges Passwort - wird erstmal noch nicht überprüft), dann werden die Daten, wie vorgesehen, an dieselbe Seite (start.php) wieder gesendet und ich bin eingeloggt. Wenn ich nun aber auf der Seite start.php den Link zu chat.php anklicke, dann bin ich auf der Seite chat.php nicht mehr eingeloggt. Die Sessiondaten scheinen irgendwie verloren gegangen zu sein.

Insgesamt soll es möglich sein, sich auf jeder Seite (also bisher nur start.php und chat.php) ein- und auszuloggen.

Was mache ich da bloß falsch?

Lukas Oklener

  1. Hallo Lukas,

    1. mußt Du die Session auf den Seiten, wo Dir die Variablen zur Verfügung stehen sollen, auch erstmal wieder starten: start_session(); (davor darf sonst nix stehen, nada, niente was an den Client ausgegeben wird).

    2. Wenn Du mit if(!$username) prüfst, kann ich durch Aufruf der Datei mit chat.php?username=blabla so tun, als sei ich eingeloggt. Besser Du prüfst, ob die Sessionvariable registriert ist. Entweder: if(session_is_registered($username)) oder neu: if($_SESSION["username"]).

    3. Würde ich die Überprüfung, ob jd. eingeloggt ist, in einem include lösen, das Du dann auf jeder Seite einbinden kannst.

    HTH

    toby

    --
    "Trying is the first step toward failure." - H. Simpson
  2. Hallo!

    Ich bin gerade dabei, einen Userbereich in PHP zu erstellen.

    Dazu habe ich probeweise zwei Dateien angelegt (start.php und chat.php)

    Es ist nicht so eifnahc sich in sowas als au0enstehendewr einzudenken. Daher solltest Du das egentliche Problem isolieren. Dann kannst Du es auch erheblich besser selbst lösen. Beim Debuggen helfen Dir Funktionen wie var_dump(), mit denen Du alle verfügbaren Angaben zu einer Variable bekommst, egal welchen Typs. So ist es z.B. immer sehr interessant var_dump($_SESSION) auszugeben um zu sehen was genau in der Session steht. Genauso ist es interessant var_dump($_POST) oder var_dump($_GET) auszugeben.

    Du solltest Dir immer _so_viel_wie_möglich_ ausgeben! Einfach echo "Meldung blabla" in den verschiedenen Zweigen einer if-Kntroll-Struktur, um zu sehen wo genau Du bei einer If-Abfrage rauskommst.

    Außerdem solltest Du Dir ganz in Ruhe
    http://de3.php.net/manual/de/ref.session.php und
    http://www.dclp-faq.de/ch/ch-version4_session.html

    durchlesen.

    In beiden Dateien steht:

    in beiden? Das darfst Du nur auf der Login-Seite machen.

    <?php

    session_start();

    if ($HTTP_POST_VARS[$login]) {

    was steht in $login?
    gebe mal var_dump($HTTP_POST_VARS) aus um zu sehen was da drin steht.

    und dann, genau an dieser Stelle hier sowas wie:

    echo "if (ligin) hat geklappt!";

    Dann siehst Du an der Ausgabe ob die If-Abfrage wenigstens funktioniert.

    session_register("username");
    session_register("passwort");

    Woher kommen username und passwort? Eine erheblich bessere Schreibweise(steht auch so in den oben verlinkten Artikeln) wäre:

    $_SESSION["username"] = $_POST["username"];

    Wobei hier unbedingt eine Prüfung erfolgen sollte! Aber das war Dir ja bewußt.

    }
    elseif ($HTTP_POST_VARS[$logout]) {

    genau wie oben

    session_destroy();
    }

    echo "<br><br><br><hr>";

    Du solltest Dir in jedem if-Zweig eine Meldung ausgeben lassen, damit Du weißt was genau ausgeführt wird!

    ?>

    <?php
    if (!$username) :

    Diese Schreibweise von Kontrollstrukturen eignet sich IMHO nicht unbedingt für größere Konstrukte.

    Und hier sieht man sehr schön wie gefährlich der unbedarfte Einsatz von globalen Variablen ist:

    ich übergene Deinem Scirpt einfach script.php?username=quatsch und schon bind ich eingeloggt, zumindest wenn Du es hier nicht prüfts da Du davon ausgehst das es sich um eine Session-Variable handelt. Verwende als immer $_SESSION["username"] oder $_POST["username"], je nachdem was Du halt erwartest.

    ?>
    Username: Gast (nicht eingeloggt)<br>
    <form action="<?php echo $PHP_SELF ?>" method="post">
    <input type="hidden" name="login">
    Username: <input type="text" name="username"><br>
    Passwort: <input type="text" name="passwort"><br>
    <input type="submit" value="Login">
    </form>
    <?php
    else :
    ?>
    Username: <?php echo $username ?> (registriert)
    <form action="<?php echo $PHP_SELF ?>" method="post">
    <input type="hidden" name="logout">
    <input type="submit" value="Logout">
    </form>
    <?php
    endif;
    ?>

    <br>
    <a href="chat.php4">Chat</a>

    Nur die letzte Zeile (<a href="chat.php">Chat</a>) ist in der Datei chat.php:
    <a href="start.php">Start</a>

    Wenn ich mich nun auf der Seite start.php einlogge (beliebiger Username und beliebiges Passwort - wird erstmal noch nicht überprüft), dann werden die Daten, wie vorgesehen, an dieselbe Seite (start.php) wieder gesendet und ich bin eingeloggt. Wenn ich nun aber auf der Seite start.php den Link zu chat.php anklicke, dann bin ich auf der Seite chat.php nicht mehr eingeloggt. Die Sessiondaten scheinen irgendwie verloren gegangen zu sein.

    Das ist schwer zu sagen woran das liegt, das kann zig Ursachen haben.
    Zum einen verwendest Du sehr alte Schreibweisen die nicht unbedingt von aktuellen PHP-Versionen unterstützt werden, lies dazu die Links im Manual.
    Es ist auch möglich das die SessionID nicht per Cookie oder URL übergeben wurde, da die php.ini nicht entsprechend eingestellt ist.  Du solltest Dir auf beides Seite die SessionID ausgeben lassen, mit: echo session_id();
    Dass solltst Du Dir $_SESSION ausgeben lassen, um zu sehen was in der Session steht. Und passe die Schreibweisen entsprechend an.(post, get, session). Gebe Dir alles aus was Du Dir ausgeben kannst, udn vereinfache das Problem, versuche vielleicht erstmal einfach nur eine SessionID auf eine andere Seite zu übergeben, undabhängig von den Prüfungen, dem Formular.

    Grüße
    Andreas

    Insgesamt soll es möglich sein, sich auf jeder Seite (also bisher nur start.php und chat.php) ein- und auszuloggen.

    Was mache ich da bloß falsch?

    Lukas Oklener

    1. Danke euch beiden ganz herzlich für eure Hilfe, ich habe es nun zum Laufen gebracht!
      Es lag wohl daran, dass ich if (isset($variable)) anstatt if ($variable) verwenden muss. Aber ich habe nun auch die neueren Schreibweisen wie z.B.
      $_SESSION["username"] = $_POST["username"];
      verwendet.

      Außerdem solltest Du Dir ganz in Ruhe
      http://de3.php.net/manual/de/ref.session.php und
      http://www.dclp-faq.de/ch/ch-version4_session.html

      Da bin ich auf zwei Sachen gestoßen, die mich doch noch interessieren würden:
      -Dort wird bei verschiedenen Beispielen in Formularen action="<?php echo $_SERVER["PHP-SELF"]; ?>". Dies ist bestimmt gegenüber <?php echo $PHP_SELF; ?> die neuere Variante, aber was ist da der Unterschied?
      -Bei den Beispielen benutzen alle immer ein Anführungszeichen, anstatt zwei, also z.B. $_SERVER['PHP_SELF'] und $_POST['username'] anstatt $_SERVER["PHP_SELF"] und $_POST["username"]. Welches ist die offiziellere, bessere, praktischere Variante?

      <?php
      if (!$username) :

      Diese Schreibweise von Kontrollstrukturen eignet sich IMHO nicht unbedingt für größere Konstrukte.

      Aber wie soll ich einen HTML-Einschub innerhalb von IF-Anweisungen dann realisieren?

      Nochmal danke und Gruß,
      Lukas

      1. Hi!

        Da bin ich auf zwei Sachen gestoßen, die mich doch noch interessieren würden:

        Dann lis das doch im Manual nach, solltest Dir mal in Ruhe einen übrblich verschaffen: http://www.php3.de/manual/de/

        -Dort wird bei verschiedenen Beispielen in Formularen action="<?php echo $_SERVER["PHP-SELF"]; ?>". Dies ist bestimmt gegenüber <?php echo $PHP_SELF; ?> die neuere Variante, aber was ist da der Unterschied?

        Leider nur in englisch verfpgbar: http://www.php3.de/manual/en/language.variables.predefined.php

        -Bei den Beispielen benutzen alle immer ein Anführungszeichen, anstatt zwei, also z.B. $_SERVER['PHP_SELF'] und $_POST['username'] anstatt $_SERVER["PHP_SELF"] und $_POST["username"]. Welches ist die offiziellere, bessere, praktischere Variante?

        Hat beudes Vor- und Nachteile: http://www.php3.de/manual/de/language.types.string.php

        Aber wie soll ich einen HTML-Einschub innerhalb von IF-Anweisungen dann realisieren?

        Ich  meinte das mit if() : ?

        Mit if() {} else {} funkioniert das analog.

        Grüße
        Andreas

        1. Danke für die Links, werde ich mir gleich durchlesen!

          Leider bin ich mittlerweile auf das zweite Problem gestoßen. Jetzt versuche ich nämlich, Username und Passwort wirklich zu überprüfen.
          Dazu habe ich mir das ausgedacht:

          function pruef() {
          $pfad = "user.dat";
          $datei = fopen($pfad, "r");
          foreach (fgets($datei,100) as $zeile) {
          $array = explode("&&", $zeile);
          $username = $array[0];
          $passwort = $array[1];
           if (($username=$_POST["username"])&&($passwort=$_POST["passwort"])) {
           $_SESSION["username"] = $_POST["username"];
           $_SESSION["passwort"] = $_POST["passwort"];
           }
           else {
           echo "Login leider nicht erfolgreich";
           }
          }
          fclose($datei);
          }

          Bei jedem Loginversuch gibt er mir jetzt die Fehlermeldung
          Warning: Invalid argument supplied for foreach() in c:\apache\userber\login.php on line 9
          heraus.
          Es muss doch irgendwie möglich sein, die user.dat Zeile für Zeile (Username und Passwort sind pro User jeweils in einer Zeile durch && getrennt gespeichert) durchzugehen und zu überprüfen, ob dort der eingegebene Username vorkommt und mit dem Passwort übereinstimmt. Mit der Zeile
          foreach (fgets($datei,100) as $zeile)
          scheint es wohl noch nicht richtig zu funktionieren, das ist nämlich die Zeile 9.

          Schönen Abend noch,
          Lukas

          1. Hi!

            function pruef() {
            $pfad = "user.dat";
            $datei = fopen($pfad, "r");
            foreach (fgets($datei,100) as $zeile) {

            Hier ist das Problem:
            guck Dir an was fgets zurückgibt,
            http://www.php3.de/manual/de/function.fgets.php
            und was foreach erwartet: http://www.php3.de/manual/de/control-structures.foreach.php

            Und _danach_ guck Dir z.B. die Funktion file() an: http://www.php3.de/manual/de/function.file.php

            Grüße
            Andreas

            1. OK, danke nochmal für die Links!

              Ich habe mir alle drei Seiten durchgelesen und versuchte es nun mit der Funktion file():

              function pruef() {
              $pfad = "user.dat";
              $datei = fopen($pfad, "r");
              $lines = file($datei);
              $lines = trim($lines);
              foreach ($lines as $zeile) {
              $infos = explode("&&", $zeile);
              $username = $infos[0];
              $passwort = $infos[1];
               if (($username=$_POST["username"])&&($passwort=$_POST["passwort"])) {
               $_SESSION["username"] = $_POST["username"];
               $_SESSION["passwort"] = $_POST["passwort"];
               }
               else {
               echo "Login leider nicht erfolgreich";
               }
              }
              }

              Nun gibt er folgende zwei Fehlermeldungen raus:
              Warning: file() expects parameter 1 to be string, resource given in c:\apache\userber\login.php on line 9

              Was hat das nun wieder zu bedeuten?

              Warning: Invalid argument supplied for foreach() in c:\apache\userber\login.php on line 11

              Invalid argument? $lines ist doch jetzt durch die Funktion file() ein Array!?

              Kannst du mir da nochmal weiterhelfen?

              Lukas Oklener

              1. Hi!

                Nun gibt er folgende zwei Fehlermeldungen raus:
                Warning: file() expects parameter 1 to be string, resource given in c:\apache\userber\login.php on line 9

                Logisch! Du übergibst ja auch nicht die richtigen Parameter:

                file ( string filename [, int use_include_path])

                Du übergibst keinen Dateinamen sondern eine Recource (fopen)

                Warning: Invalid argument supplied for foreach() in c:\apache\userber\login.php on line 11

                Folgefehler

                Grüße
                Andreas

        2. Hallo Andreas,

          Leider nur in englisch verfpgbar: http://www.php3.de/manual/en/language.variables.predefined.php

          Wer sagt das?
          http://www.php3.de/manual/de/language.variables.predefined.php

          Grüße aus Darmstadt,
          Benjamin

          1. Hi!

            Leider nur in englisch verfpgbar: http://www.php3.de/manual/en/language.variables.predefined.php

            Wer sagt das?
            http://www.php3.de/manual/de/language.variables.predefined.php

            Vergleich mal beide Seiten, die deutsche ist älter!

            Grüße
            Andreas

            1. Hallo Andreas,

              Vergleich mal beide Seiten, die deutsche ist älter!

              Tatsache, du hast recht (ja, ich habe den Inhalt nicht verglichen ;-)) Allerdings steht bei beiden Seiten "Last updated: Mon, 27 Jan 2003", da kann es leicht passieren, dass man genau das Gegenteil denkt.

              Grüße aus Darmstadt,
              Benjamin

              1. Hi!

                Tatsache, du hast recht (ja, ich habe den Inhalt nicht verglichen ;-)) Allerdings steht bei beiden Seiten "Last updated: Mon, 27 Jan 2003", da kann es leicht passieren, dass man genau das Gegenteil denkt.

                Das ist an einigen Stellen so, so z.B. auch bei require, da stand ne ganze Zeit in deustch eine andere Bedeutung von require als in deutsch! Ist aber inzwischen aktualisiert. Deshalb würde ich immer auch mal die englische Version des Manuals zu rate ziehen, das ist auf alle Fälle am aktuellsten.

                Grüeß
                Andreas