Autor | Zpráva | ||
---|---|---|---|
Fastman Profil |
#1 · Zasláno: 5. 4. 2014, 19:16:35
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 |
#2 · Zasláno: 5. 4. 2014, 19:25:15
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 |
#3 · Zasláno: 5. 4. 2014, 19:50:05
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 |
#4 · Zasláno: 5. 4. 2014, 19:54:32
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 |
#5 · Zasláno: 5. 4. 2014, 20:00:55
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 |
#6 · Zasláno: 5. 4. 2014, 20:15:01
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 |
#8 · Zasláno: 5. 4. 2014, 20:48:26
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 |
#10 · Zasláno: 5. 4. 2014, 23:56:08
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 |
#12 · Zasláno: 6. 4. 2014, 03:15:14
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]"; } [email] jsem zkoušel dát $result , $_SESSION , $row . Stále to nevypisovalo uživatelův email z databáze.
|
||
Alphard Profil |
#14 · Zasláno: 6. 4. 2014, 16:31:24
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. |
||
Časová prodleva: 10 let
|
0