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:

<?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($result, 0))  // 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
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).
// 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.

// 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);
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.

$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.

{

    //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.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: