Autor Zpráva
Fastman
Profil
Zdravím,

Půjčil jsem si tenhle kód od uživatele: Alphard - Nejčastější potíže s PHP (FAQ)
A mám zde problém přidat $_SESSION. Stránka správně vypíše Nick (uživatelské jméno), ale jiný SESSION mnou přidané už nefunguje. Například email, který mám taktéž v databázi.
Zde je kód:

1<?php
2$path = "/login/";  // máte-li stránky v rootu, nechte bezezměny, pokud je provozujete v nějakém podadresáři, zadejte jeho jméno
3              // např. stránky mám na moje-domena.cz/adresar/, tak zadám $path = "/adresar/";
4 
5// funkce pro ošetření vstupních dat od uživatele
6// viz http://cz.php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc
7function db_escape($str) 
8
9    return mysql_real_escape_string(@get_magic_quotes_gpc() ? stripslashes($str) : $str);
10
11 
12 
13$db_server    = 'localhost';
14$db_login     = 'xxx';
15$db_password  = 'xxxxxx';
16$db_name      = 'xxxxxxxxx';
17$spojeni      = @MySQL_Connect($db_server ,$db_login, $db_password);
18@MySQL_Select_DB($db_name)or die('<p style="color: #CC0000">Nastala chyba v pripojeni k databazi');   // soubor pripojeni_db.php zajistí připojení k databázi a výběr databáze, se kterou pracujeme
19session_start();  // tohle je nezbytné a je nutné uvést tuto funkci na všech stránkách, kam se přihlášený uživatel dostane
20                  // možnost nastavit automatické spouštění session_start() nechávám stranou
21 
22// zjistíme, co chce uživatel dělat
23if (isset($_SESSION['nick']) && isset($_GET['logout']) && isset($_SESSION['email']))         //*** zde jsem si doplnil SESSION email
24{
25    // uživatel je přihlášen a chce se odhlásit, takže smažeme údaje o přihlášení
26    $_SESSION = array();
27    if (isset($_COOKIE[session_name()]))
28    {
29        setcookie(session_name(), '', time()-42000, '/');
30    }
31    session_unset();
32    session_destroy();
33    // a přesměrujeme na index.php
34    header("location:.$path."index.php]http://".$_SERVER['SERVER_NAME'].$path."index.php", TRUE, 303);
35    exit;
36}
37elseif (isset($_SESSION['nick']))
38{
39 
40    //session_regenerate_id(); // ochrana před session fixation, lze vynechat
41    // uživatel je přihlášen a nechce se odhlásit, zde zobrazíme obsah pro registrované
42    // můžeme využit include apod.
43 
44    // tohle informuje uživatele, že je přihlášen a vypíše odkaz pro odhlášení
45    // můžeme to ale přemístit do includovaného souboru (kam se nám hodí)
46    echo "<p>Přihlášen: $_SESSION[nick] <a href=\".$path."index.php?logout=1\">odhlásit</a></p>\n]http://".$_SERVER['SERVER_NAME'].$path."index.php?logout=1\">odhlásit</a></p>\n";
47    echo "Email: $_SESSION[email] ";  //*** zde se pokouším o výpis SESSION email.
48 
49 
50}  
51 
52else
53{
54    // uzivatel není přihlášen
55    // pokud odeslal přihlašovací údaje, snaží se přihlásit
56    if (isset($_POST['nick']) && isset($_POST['heslo']))
57    {
58        // ošetříme vstupní údaje od uživatele
59        // funkce trim() má význam hlavně u hesla, ořeže bílé znaky (např. mezery) na začátku a konci řetězce
60        $nick = db_escape(trim($_POST['nick']));
61        $heslo = db_escape(trim($_POST['heslo']));
62 
63        // zjistíme, jestli je v databázi daný uživatel a jestli se prokazuje platným heslem
64        // více o ukládání hesel, např. o tzv. solení, najdete na http://php.vrana.cz/ukladani-hesel.php
65        $result = mysql_query("SELECT COUNT(*) FROM uzivatele WHERE nick = '$nick' AND heslo = sha1('$heslo')");
66        
67        if (mysql_result($result, 0))  // předpokládáme, že dotaz proběhl úspěšně, pokud ne, bude stejně vráceno false
68                                       // true (a splnění podmínky) nastane pouze tehdy, když v databázi existuje správná kombinace uživatelského jména a hesla
69        {
70            // uložíme potřebné SESSION proměnné
71            $_SESSION['nick'] = $nick;
72            $_SESSION['email'] = $email; //*** zde jsem tedy uvedl SESSION pro email, jak je psáno v poznámce.
73            $_SESSION['cas_prihlaseni'] = time(); // čas, kdy se uživatel přihlásil, pozor, nejedná se o čas poslední akce, nevím, jestli ho využijete, může být smazán
74            
75            // po přihlášení uživatele přesměrujeme na index.php
76            header ("location:.$path."index.php]http://".$_SERVER['SERVER_NAME'].$path."index.php", TRUE, 303);
77            exit;  // aby bylo pravidlům učiněno zadost, zde stejně končí podmínka a jiná nemůže být splněna
78        }
79        else
80        {
81            // uživatel zadal neplatné přihlašovací údaje
82            // přesměrujeme ho na index.php a zobrazíme chybovou hlášku
83            header ("location:.$path."index.php?incorrect_login=1]http://".$_SERVER['SERVER_NAME'].$path."index.php?incorrect_login=1", TRUE, 303);
84            exit;
85        }
86    }
87    else
88    {
89      // uživatel není přihlášen a ani neodeslal přihlašovací formulář, tak mu ho zobrazíme
90      echo "<div>";
91      if (isset($_GET['incorrect_login']))
92      {
93          echo "<center><p style=\"color: #F00\">Zadali jste neplatné uživatelské jméno nebo heslo</center></p>\n";
94      }
95      // zobrazíme formulář pro přihlášení
96      ?>
97      <center><div class='container2'>
98      <form action="index.php" method="post">
99      <div class="box">
100        Jméno:  <input name="nick" class="input_text"  type="text"><br>
101        Heslo: <input name="heslo"  class="input_text" type="password"><br>
102        <input name="submit" type="submit" class="button"  value="Přihlásit">
103      </form>
104      </div>
105      
106      
107      <?php
108    }
109}
110?>
111 
112   
<?php
$path "/login/";  // máte-li stránky v rootu, nechte bezezměny, pokud je provozujete v nějakém podadresáři, zadejte jeho jméno
              // např. stránky mám na moje-domena.cz/adresar/, tak zadám $path = "/adresar/";
 
// funkce pro ošetření vstupních dat od uživatele
// viz http://cz.php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc
function db_escape($str) 
{ 
    return mysql_real_escape_string(@get_magic_quotes_gpc() ? stripslashes($str) : $str);
} 
 
 
$db_server    'localhost';
$db_login     'xxx';
$db_password  'xxxxxx';
$db_name      'xxxxxxxxx';
$spojeni      = @MySQL_Connect($db_server ,$db_login$db_password);
@MySQL_Select_DB($db_name)or die('<p style="color: #CC0000">Nastala chyba v pripojeni k databazi');   // soubor pripojeni_db.php zajistí připojení k databázi a výběr databáze, se kterou pracujeme
session_start();  // tohle je nezbytné a je nutné uvést tuto funkci na všech stránkách, kam se přihlášený uživatel dostane
                  // možnost nastavit automatické spouštění session_start() nechávám stranou
 
// zjistíme, co chce uživatel dělat
if (isset($_SESSION['nick']) && isset($_GET['logout']) && isset($_SESSION['email']))         //*** zde jsem si doplnil SESSION email
{
    // uživatel je přihlášen a chce se odhlásit, takže smažeme údaje o přihlášení
    $_SESSION array();
    if (isset($_COOKIE[session_name()]))
    {
        setcookie(session_name(), ''time()-42000'/');
    }
    session_unset();
    session_destroy();
    // a přesměrujeme na index.php
    header("location:.$path."index.php]http://".$_SERVER['SERVER_NAME'].$path."index.php", TRUE, 303);
    exit;
}
elseif (isset($_SESSION['nick']))
{
 
    //session_regenerate_id(); // ochrana před session fixation, lze vynechat
    // uživatel je přihlášen a nechce se odhlásit, zde zobrazíme obsah pro registrované
    // můžeme využit include apod.
 
    // tohle informuje uživatele, že je přihlášen a vypíše odkaz pro odhlášení
    // můžeme to ale přemístit do includovaného souboru (kam se nám hodí)
    echo "<p>Přihlášen: $_SESSION[nick] <a href=\".$path."index.php?logout=1\">odhlásit</a></p>\n]http://".$_SERVER['SERVER_NAME'].$path."index.php?logout=1\">odhlásit</a></p>\n";
    echo "Email: $_SESSION[email] ";  //*** zde se pokouším o výpis SESSION email.
 
 
}  
 
else
{
    // uzivatel není přihlášen
    // pokud odeslal přihlašovací údaje, snaží se přihlásit
    if (isset($_POST['nick']) && isset($_POST['heslo']))
    {
        // ošetříme vstupní údaje od uživatele
        // funkce trim() má význam hlavně u hesla, ořeže bílé znaky (např. mezery) na začátku a konci řetězce
        $nick = db_escape(trim($_POST['nick']));
        $heslo = db_escape(trim($_POST['heslo']));
 
        // zjistíme, jestli je v databázi daný uživatel a jestli se prokazuje platným heslem
        // více o ukládání hesel, např. o tzv. solení, najdete na http://php.vrana.cz/ukladani-hesel.php
        $result mysql_query("SELECT COUNT(*) FROM uzivatele WHERE nick = '$nick' AND heslo = sha1('$heslo')");
        
        if (mysql_result($result0))  // předpokládáme, že dotaz proběhl úspěšně, pokud ne, bude stejně vráceno false
                                       // true (a splnění podmínky) nastane pouze tehdy, když v databázi existuje správná kombinace uživatelského jména a hesla
        {
            // uložíme potřebné SESSION proměnné
            $_SESSION['nick'] = $nick;
            $_SESSION['email'] = $email//*** zde jsem tedy uvedl SESSION pro email, jak je psáno v poznámce.
            $_SESSION['cas_prihlaseni'] = time()// čas, kdy se uživatel přihlásil, pozor, nejedná se o čas poslední akce, nevím, jestli ho využijete, může být smazán
            
            // po přihlášení uživatele přesměrujeme na index.php
            header ("location:.$path."index.php]http://".$_SERVER['SERVER_NAME'].$path."index.php", TRUE, 303);
            exit;  // aby bylo pravidlům učiněno zadost, zde stejně končí podmínka a jiná nemůže být splněna
        }
        else
        {
            // uživatel zadal neplatné přihlašovací údaje
            // přesměrujeme ho na index.php a zobrazíme chybovou hlášku
            header ("location:.$path."index.php?incorrect_login=1]http://".$_SERVER['SERVER_NAME'].$path."index.php?incorrect_login=1", TRUE, 303);
            exit;
        }
    }
    else
    {
      // uživatel není přihlášen a ani neodeslal přihlašovací formulář, tak mu ho zobrazíme
      echo "<div>";
      if (isset($_GET['incorrect_login']))
      {
          echo "<center><p style=\"color: #F00\">Zadali jste neplatné uživatelské jméno nebo heslo</center></p>\n";
      }
      // zobrazíme formulář pro přihlášení
      ?>
      <center><div class='container2'>
      <form action="index.php" method="post">
      <div class="box">
        Jméno:  <input name="nick" class="input_text"  type="text"><br>
        Heslo: <input name="heslo"  class="input_text" type="password"><br>
        <input name="submit" type="submit" class="button"  value="Přihlásit">
      </form>
      </div>
      
      
      <?php
    }
}
?>
 
   

Děkuji všem za odpověď. V kódu jsou označené komentáře //*** mnou, aby to bylo jasnější.
Alphard
Profil
Na řádku 72 je $email, která je nedefinovaná. Nemá tam být $result['email']?
Logiku podmínky na 23. řádku se mi nechce moc podrobně zkoumat, ale ten mail se mi tam zdá zbytečný, jako kontrola přihlášenosti dostačuje $_SESSION['nick']. Mimochodem, to mazání cookies jsem před lety napsal dost paranoidně, dneska toto na pehapku naopak nedoporučuji :-), měl to FAQ updatovat.
Fastman
Profil
Děkuji za odpověď Alphard.

Aha, takže řádek 23 má být ověření konkrétních údajů, tak jsem tedy vymazal && isset($_SESSION['email'])
Jak jste myslel ten řádek 72?

Napsal jsem to tedy takhle
1elseif (isset($_SESSION['nick']))
2{
3 
4    //session_regenerate_id(); // ochrana před session fixation, lze vynechat
5    // uživatel je přihlášen a nechce se odhlásit, zde zobrazíme obsah pro registrované
6    // můžeme využit include apod.
7 
8    // tohle informuje uživatele, že je přihlášen a vypíše odkaz pro odhlášení
9    // můžeme to ale přemístit do includovaného souboru (kam se nám hodí)
10    echo "<p>Přihlášen: $_SESSION[nick] <a href=\".$path."index.php?logout=1\">odhlásit</a></p>\n]http://".$_SERVER['SERVER_NAME'].$path."index.php?logout=1\">odhlásit</a></p>\n";
11    echo "Email: $result[email] ";
12    echo "<br>";
13    echo "Email: $_SESSION[email] ";
14    echo "<br>";
15    echo "Email: $email ";
16 
17 
18
elseif (isset($_SESSION['nick']))
{
 
    //session_regenerate_id(); // ochrana před session fixation, lze vynechat
    // uživatel je přihlášen a nechce se odhlásit, zde zobrazíme obsah pro registrované
    // můžeme využit include apod.
 
    // tohle informuje uživatele, že je přihlášen a vypíše odkaz pro odhlášení
    // můžeme to ale přemístit do includovaného souboru (kam se nám hodí)
    echo "<p>Přihlášen: $_SESSION[nick] <a href=\".$path."index.php?logout=1\">odhlásit</a></p>\n]http://".$_SERVER['SERVER_NAME'].$path."index.php?logout=1\">odhlásit</a></p>\n";
    echo "Email: $result[email] ";
    echo "<br>";
    echo "Email: $_SESSION[email] ";
    echo "<br>";
    echo "Email: $email ";
 
 
} 

Ty echo jsem si tam dodal, abych zjistil, jestli jsem někde neudělal chybu.

A uložené SESSION mají být takhle? (Tady jsem to nějak nepochopil).
1// uložíme potřebné SESSION proměnné
2            $_SESSION['nick'] = $nick;
3            $_SESSION['email'] = $result['email'];
4            $_SESSION['cas_prihlaseni'] = time(); // čas, kdy se uživatel přihlásil, pozor, nejedná se o čas poslední akce, nevím, jestli ho využijete, může být smazán
// uložíme potřebné SESSION proměnné
            $_SESSION['nick'] = $nick;
            $_SESSION['email'] = $result['email'];
            $_SESSION['cas_prihlaseni'] = time(); // čas, kdy se uživatel přihlásil, pozor, nejedná se o čas poslední akce, nevím, jestli ho využijete, může být smazán

Potřebuji právě vypsat více věcí z tabulky než jenom nick.

Děkuji Vám za případné další rady a odpovědi.
Alphard
Profil
Fastman:
$_SESSION['email'] = $result['email'];
Tipuji, že by to nějak takhle mohlo být, ale samozřejmě nevidím do vaší databáze. V prvním případě se tam přiřazovala neexistující proměnná, což nemohlo fungovat. Načtená data z databáze jsou v $result, stačí použít správné klíče.
Fastman
Profil
Správné klíče, tím myslíte konkrétně co? Já Vám zde pro ukázku pošlu screen z databáze.



Děkuji za odpověď.
Alphard
Profil
Klíč pole, nebo index pole. V tomto případě vyplývá z názvu sloupce v databázi, takže email. Mělo by to fungovat tak, jak je uvedeno výše.
Fastman
Profil
Děkuji Vám za odpověď.

Bohužel to stále nejde.
Alphard
Profil
Já jsem si nevšiml, že je tam použit mysql_result(), tj. vytáhne se jen jedna hodnota, počet nalezených zánamů. Bude potřeba přepsat ten SQL dotaz, aby vracel celý nalezený řádek, existenci kontrovat pomocí mysql_num_rows() a pak použít mysql_fetch_assoc(), to by už mělo stačit.
Fastman
Profil
Alphard:

Tak tohle už je popravdě vyšší třída znalostí a v té už se bohužel nevyznám. Nejsem až tak daleko v PHP a MySQL. Omlouvám se.

Děkuji Vám za případné doplnění řádku. Myslím si, že pro ostatní by to bylo taky užitečné (více záznamů z databáze).
okolojsoucí
Profil
Fastman:
Tak tohle už je popravdě vyšší třída znalostí a v té už se bohužel nevyznám.
Je třeba se neustále vzdělávat. Musíš kód zkoušet a využívat různé ladící metody var_dump, print_r, atd...
Fastman
Profil
Alphard:
Zdravím,

Nyní jsem to zkusil napsat takhle a stále to nejde. Přidal jsem tam upravený SQL dotaz, jak jste psal

Bude potřeba přepsat ten SQL dotaz, aby vracel celý nalezený řádek, existenci kontrovat pomocí mysql_num_rows() a pak použít mysql_fetch_assoc(), to by už mělo stačit.

1// zjistíme, jestli je v databázi daný uživatel a jestli se prokazuje platným heslem
2        // více o ukládání hesel, např. o tzv. solení, najdete na http://php.vrana.cz/ukladani-hesel.php
3         
4        $result = mysql_query("SELECT * FROM uzivatele WHERE nick = '$nick' AND heslo = sha1('$heslo')", $link);
5        
6        if (mysql_num_rows($result))  // předpokládáme, že dotaz proběhl úspěšně, pokud ne, bude stejně vráceno false
7                                       // true (a splnění podmínky) nastane pouze tehdy, když v databázi existuje správná kombinace uživatelského jména a hesla   
8        
9        {     
10        
11        while ($row = mysql_fetch_assoc($result)) {
12    echo $row["nick"];
13    echo $row["email"];
14    echo $row["userstatus"];
15
16            // uložíme potřebné SESSION proměnné
17            $_SESSION['nick'] = $nick;
18            $_SESSION['email'] = $row["email"];
19            $_SESSION['email'] = $result['email']; 
20            $_SESSION['cas_prihlaseni'] = time(); // čas, kdy se uživatel přihlásil, pozor, nejedná se o čas poslední akce, nevím, jestli ho využijete, může být smazán
21            
// zjistíme, jestli je v databázi daný uživatel a jestli se prokazuje platným heslem
        // více o ukládání hesel, např. o tzv. solení, najdete na http://php.vrana.cz/ukladani-hesel.php
         
        $result mysql_query("SELECT * FROM uzivatele WHERE nick = '$nick' AND heslo = sha1('$heslo')"$link);
        
        if (mysql_num_rows($result))  // předpokládáme, že dotaz proběhl úspěšně, pokud ne, bude stejně vráceno false
                                       // true (a splnění podmínky) nastane pouze tehdy, když v databázi existuje správná kombinace uživatelského jména a hesla   
        
        {     
        
        while ($row mysql_fetch_assoc($result)) {
    echo $row["nick"];
    echo $row["email"];
    echo $row["userstatus"];
} 
            // uložíme potřebné SESSION proměnné
            $_SESSION['nick'] = $nick;
            $_SESSION['email'] = $row["email"];
            $_SESSION['email'] = $result['email']; 
            $_SESSION['cas_prihlaseni'] = time(); // čas, kdy se uživatel přihlásil, pozor, nejedná se o čas poslední akce, nevím, jestli ho využijete, může být smazán
            

Připojení k databázi se změnilo na
$link = mysql_connect("localhost", "uz.jmeno", "heslo");
mysql_select_db("database", $link);
$link mysql_connect("localhost""uz.jmeno""heslo");
mysql_select_db("database"$link);
Alphard
Profil
Fastman [#11]:
Tohle vypadá jako dobrý začátek. V úpravách kódu jste šel podle mého návodu. Doufám, že výpis hodnot na řádku 12 až 14 se zdařil. Zároveň je ale třeba si uvědomit, že v proměnné $row bude po opuštění cyklu false a následné ukládání do sessions selže. Protože ale výsledek může obsahovat maximálně jeden řádek, cyklus while vůbec není potřeba.

1$result = mysql_query("SELECT * FROM uzivatele WHERE nick = '$nick' AND heslo = sha1('$heslo')", $link);
2        
3if (mysql_num_rows($result)) 
4{            
5  $row = mysql_fetch_assoc($result)
6  echo $row["nick"];
7  echo $row["email"];
8  echo $row["userstatus"];
9  
10  // uložíme potřebné SESSION proměnné
11  $_SESSION['nick'] = $nick;
12  $_SESSION['email'] = $row["email"];
13  $_SESSION['cas_prihlaseni'] = time();
14}
$result mysql_query("SELECT * FROM uzivatele WHERE nick = '$nick' AND heslo = sha1('$heslo')"$link);
        
if (mysql_num_rows($result)) 
{            
  $row mysql_fetch_assoc($result)
  echo $row["nick"];
  echo $row["email"];
  echo $row["userstatus"];
  
  // uložíme potřebné SESSION proměnné
  $_SESSION['nick'] = $nick;
  $_SESSION['email'] = $row["email"];
  $_SESSION['cas_prihlaseni'] = time();
}
Fastman
Profil
Alphard:
Bohužel se nevypsal řádek email a jiné, akorát nick. Zároveň jak jste psal, že while není potřeba, tak po smazání while, takže výsledný: $row = mysql_fetch_assoc($result) nefunguje. (nenačte se stránka).


Alphard:
za $row = mysql_fetch_assoc($result) jsem dodal ; a stránka se zobrazuje, ale proměnné bohužel ne.

1{
2 
3    //session_regenerate_id(); // ochrana před session fixation, lze vynechat
4    // uživatel je přihlášen a nechce se odhlásit, zde zobrazíme obsah pro registrované
5    // můžeme využit include apod.
6 
7    // tohle informuje uživatele, že je přihlášen a vypíše odkaz pro odhlášení
8    // můžeme to ale přemístit do includovaného souboru (kam se nám hodí)
9    echo "<p>Přihlášen: $_SESSION[nick] <a href=\".$path."index.php?logout=1\">odhlásit</a></p>\n].$path."index.php?logout=1\">odhlásit</a></p>\n]http://".$_SERVER['SERVER_NAME'].$path."index.php?logout=1\">odhlásit</a></p>\n";
10    echo "Email: $result[email]";  
11 
12 
13}  
{
 
    //session_regenerate_id(); // ochrana před session fixation, lze vynechat
    // uživatel je přihlášen a nechce se odhlásit, zde zobrazíme obsah pro registrované
    // můžeme využit include apod.
 
    // tohle informuje uživatele, že je přihlášen a vypíše odkaz pro odhlášení
    // můžeme to ale přemístit do includovaného souboru (kam se nám hodí)
    echo "<p>Přihlášen: $_SESSION[nick] <a href=\".$path."index.php?logout=1\">odhlásit</a></p>\n].$path."index.php?logout=1\">odhlásit</a></p>\n]http://".$_SERVER['SERVER_NAME'].$path."index.php?logout=1\">odhlásit</a></p>\n";
    echo "Email: $result[email]";  
 
 
}  
Za [email] jsem zkoušel dát $result, $_SESSION, $row. Stále to nevypisovalo uživatelův email z databáze.
Alphard
Profil
Ano, středník tam chyběl.

$result samozřejmě existuje jen na té stránce s dotazem, takže nemá smysl snažit se ji vypisovat na jíné stránce... Začátky mohou být těžké a vedou člověka k lepení a náhodnému zkoušení, ale snažte se aspoň trochu sám vyhodnocovat, co ten kód dělá, kde se berou jednotlivé proměnné apod. Rada [#10] okolojsoucí je užitečná, dejte si někam na začátek print_r($_SESSION);, koukněte se, jestli je uloženo to, co chcete, a podle toho hledejte dál.

Pro mě v této chvíli také není na pohled snadné říct, jaké všechny problémy tam jsou.
Toto vlákno je staré, již dlouho do něj nikdo nepřispíval.

Informace a odkazy zde uváděné už nemusejí být aktuální. Nechcete-li řešit zde uvedenou konkrétní otázku, založte si vlastní vlákno, nepište do tohoto. Vložíte-li sem nyní příspěvek, upoutáte pozornost mnoha lidí a někteří z nich si jen kvůli vám přečtou i všechny předcházející příspěvky. Předpokládáte-li, že váš text skutečně bude hodnotný, stiskněte následující tlačítko:


Běda vám, jestli to bude blábol.

0