IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
pgarsky
Člen
Avatar
pgarsky:2.9.2016 23:00

Ahoj, mám takový problém. Chtěl bych na své stránce možnost změnit si heslo, avšak ve scriptu se vyskytla chyba.
Chyba:

Warning: PDOStatement::e­xecute(): SQLSTATE[HY000]: General error: 2031 in C:\Users\Pavel\Des­ktopyprojekt\\u­cet\Db.php on line 61
Používám wrapper tady z itnetwork sekce PHP tutoriálů NERS.
Můj vymyšlený kód je takovýto:
HTML:

<form method="post">
               <h2>Změna hesla: </h2>
               <p>Staré heslo: </p>
               <input name="stare_heslo" type="password">
               <p>Nové heslo: </p>
               <input name="nove_heslo" type="password">
               <p>Nové heslo znovu: </p>
               <input name="nove_heslo_znovu" type="password"><br />
               <input type="submit" value="Změnit">
           </form>

PHP:

if ($_POST)
{
    if ($_POST['stare_heslo'] = Db::query('SELECT id FROM uzivatele WHERE jmeno=?') && $_POST['nove_heslo'] = $_POST['nove_heslo_znovu'])
    {
        Db::query('
        UPDATE SHA1(heslo)
        FROM uzivatele
        WHERE id=?
        ', $_POST['nove_heslo'] . "123456789");
        echo('<p style="text-align: center; font-size: 25px;">Heslo bylo úspašně změněno.</p>');
    }
    else
        echo('<p style="text-align: center; font-size: 25px;">Heslo se nepodařilo změnit, zkuste to znovu.</p>');
}

Pomůžete mi tuto chybu opravit?

Odpovědět
2.9.2016 23:00
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
pgarsky
Člen
Avatar
pgarsky:2.9.2016 23:03

Pokud možno, ještě vysvětlit chybu v mém kódu.

Nahoru Odpovědět
2.9.2016 23:03
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
Odpovídá na pgarsky
Josef Kuchař - Pepa489:2.9.2016 23:17

U řádku na kterém je

Db::query('SELECT id FROM uzivatele WHERE jmeno=?')

nedosazuješ za otazník hodnotu. ;)

Nahoru Odpovědět
2.9.2016 23:17
2x piš, jednou debuguj
Avatar
Michal
Člen
Avatar
Michal:2.9.2016 23:18

Podle mě je tam chyb hned několik:

1:

Db::query('SELECT id FROM uzivatele WHERE jmeno=?') // Chybí parametr, který se dosadí za otazník

Db::query('SELECT id FROM uzivatele WHERE jmeno=?', [$jmeno]) // Takto by mohla vypadat oprava

2:

$_POST['nove_heslo'] = $_POST['nove_heslo_znovu'] // Pokud se ptáš na shodu, je nutné použít dvě nebo tři rovnítka

$_POST['nove_heslo'] === $_POST['nove_heslo_znovu'] // Takto by mohla vypadat oprava

3:

Db::query('
        UPDATE SHA1(heslo)
        FROM uzivatele
        WHERE id=?
        ', $_POST['nove_heslo'] . "123456789"); // Nejsem si jist, ale myslím, že ve wrapperu z této sítě je nutno dávat parametry do pole

Db::query('
        UPDATE SHA1(heslo)
        FROM uzivatele
        WHERE id=?
        ', [$_POST['nove_heslo'] . "123456789"]); // Takto by mohla vypadat oprava
Editováno 2.9.2016 23:20
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
2.9.2016 23:18
Avatar
00
Člen
Avatar
00:3.9.2016 11:09
UPDATE xxx SET xxx

a ne

UPDATE xxx FROM xxx
 
Nahoru Odpovědět
3.9.2016 11:09
Avatar
Odpovídá na pgarsky
Martin Štěpánek :3.9.2016 11:33
if ($_POST['stare_heslo'] = Db::query('SELECT id FROM uzivatele WHERE jmeno=?')

ještě kontroluješ jestli se staré heslo rovná id uživatele ;-)

Nahoru Odpovědět
3.9.2016 11:33
Všechno jde naprogramovat, chce to jen čas a chuť...
Avatar
pgarsky
Člen
Avatar
Odpovídá na Martin Štěpánek
pgarsky:3.9.2016 11:54

To je podlě mě blbost, staré heslo se nemůže rovnat id, protože pak by to bylo třeba 123456 = 1. Ne ?

Nahoru Odpovědět
3.9.2016 11:54
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
Odpovídá na pgarsky
Martin Konečný (pavelco1998):3.9.2016 12:09

jo, ale takhle to tam máš ty :D
když s tím v podstatě začínáš, tak to dělej pomalu a sleduj, jaká metoda má jaké návratové hodnoty. Sice neznám místní DB wrapper, ale je mi jasný, že metoda Db::query() ti nebude vracet jeden konkrétní výsledek jednoho sloupce.
Ty potřebuješ zjistit, jestli se staré heslo shoduje s tím v databázi. K tomu máš dvě možnosti:

  1. vytáhnout si heslo z DB podle uživatele. To pak porovnáš v PHP s heslem zadaným ve formuláři To hledej podle jeho ID, ne podle jména - máš zaručený, že díky PK (primární klíč) to ID bude vždycky unikátní a navíc se podle něj hledá rychleji.
  2. poslat dotaz do DB, kde do WHERE zadáš ID uživatele a heslo. Pokud se vrátí jeden záznam, tak se heslo shoduje. Pokud se vrátí nula záznamů, heslo bylo zadaný špatně. Tenhle způsob ale v podstatě nebudeš moct použít, pokud hashuješ způsobem, který DB neumí. Být tebou bych proto zvolil možnost a).

A mimo to, rovnítko v PHP můžeš použít na tři způsoby

$a = 10;  // přiřazení hodnoty, tady bude výsledek vždycky TRUE! tohle když použiješ v podmínce, tak ti vždycky projde

$a == 10;  // porovná proměnnou s číslem 10, při tom nezáleží na datovém typu ($a může být 10 jako číslo i 10 jako řetězec)

$a === 10;  // porovná proměnnou s číslem deset a zároven udělá shodu datových typů. Pokud $a bude řetězec  ($a = "10"), tak výsledek bude FALSE
Nahoru Odpovědět
3.9.2016 12:09
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
00
Člen
Avatar
Odpovídá na Martin Konečný (pavelco1998)
00:3.9.2016 12:42
($a = FALSE) == FALSE
// ALE
($a = TRUE) == TRUE
// !!!
 
Nahoru Odpovědět
3.9.2016 12:42
Avatar
Odpovídá na 00
Martin Konečný (pavelco1998):3.9.2016 12:55

zajímavé, beru zpět. Nicméně házet do podmínky jedno rovnítko je sebevražda sama o sobě

Nahoru Odpovědět
3.9.2016 12:55
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
pgarsky
Člen
Avatar
Odpovídá na Martin Konečný (pavelco1998)
pgarsky:3.9.2016 13:08

takže jak by podle tebe měl vypadat kód ?

Nahoru Odpovědět
3.9.2016 13:08
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
Odpovídá na pgarsky
Martin Konečný (pavelco1998):3.9.2016 13:40

Neznám ten DB wrapper, ale asi něco takovýho

$vysledek = DB::query("
        SELECT heslo
        FROM uzivatel
        WHERE id = ?
", array($_SESSION["uzivatel_id"]));

$data = $vysledek->fetch();
$stareHeslo = nejakaHashFunkce($_POST["stare_heslo"]);
if ($stareHeslo === $data["heslo"]) {
        // OK
}
Editováno 3.9.2016 13:40
Nahoru Odpovědět
3.9.2016 13:40
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
pgarsky
Člen
Avatar
Nahoru Odpovědět
3.9.2016 14:07
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
00
Člen
Avatar
Odpovídá na Martin Konečný (pavelco1998)
00:3.9.2016 19:19

Přiřazování vrací přiřazovanou hodnotu :-)

 
Nahoru Odpovědět
3.9.2016 19:19
Avatar
Odpovídá na 00
Martin Konečný (pavelco1998):3.9.2016 20:16

A to jsem myslel, že to vrací výsledek "operace". Nicméně se to do podmínky přetypuje na bool, což ve většině případů znamená TRUE a začátečník na tom hezky narazí, pokud nebude přesně vědět, co dělá :D
Každopádně díky za upozornění

Nahoru Odpovědět
3.9.2016 20:16
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
pgarsky
Člen
Avatar
Nahoru Odpovědět
3.9.2016 20:21
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
Odpovídá na pgarsky
Martin Konečný (pavelco1998):3.9.2016 20:30

To je hezký, ale takhle ti nemá kdo jak poradit. Co zkusit třeba napsat, proč to nefunguje (chybové hlášení, co to má dělat a co to dělá, ...)? Jinak jsem psal, že ten DB wrapper neznám, jen jsem ti nastínil, jak by to mohlo vypadat.

Nahoru Odpovědět
3.9.2016 20:30
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
FiftypiSoftware
Tvůrce
Avatar
Odpovídá na Martin Konečný (pavelco1998)
FiftypiSoftware:5.9.2016 17:27

Já si ještě našel na w3shools.com postupy, jakými to dělat bez tohoto wrapperu.

 
Nahoru Odpovědět
5.9.2016 17:27
Avatar
Odpovídá na FiftypiSoftware
Martin Konečný (pavelco1998):5.9.2016 17:41

díky za informaci :D Pokud používáš PDO, je to OK. Já používám primárně Doctrine 2, případně Nette\Database (pokud fakt musim a neni jiná možnost), s ničím jiným zkušenosti nemám

Nahoru Odpovědět
5.9.2016 17:41
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
FiftypiSoftware
Tvůrce
Avatar
Odpovídá na Martin Konečný (pavelco1998)
FiftypiSoftware:5.9.2016 17:58

No já používám zatím jen mysqli, ale k PDO se taky dostanu. Jinak teď používám databáze na Virt. PC s Linuxem.

 
Nahoru Odpovědět
5.9.2016 17:58
Avatar
Odpovídá na FiftypiSoftware
Martin Konečný (pavelco1998):5.9.2016 18:10

mysqli je skoro to samý co PDO. Doporučuji PDO

Nahoru Odpovědět
5.9.2016 18:10
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na pgarsky
Neaktivní uživatel:9.9.2016 0:23

Princip je asi takový, že při předání hodnot z formuláře se ověří shodnost otisku zadaného starého hesla s otiskem uloženým v databázi u konkrétního uživatele (přihlášeného) a shodnost obou zadání nového hesla. Pokud podmínka projde dojde k aktualizaci uloženého otisku hesla v databázi otiskem nového hesla.
Kód si musíš přizpůsobit svým potřebám, nastavením a dalším věcem.

if ($_POST)
{
    if (sha1($_POST['stare_heslo']) == Db::query('SELECT heslo FROM uzivatele WHERE id=?', $_SESSION['uzivatel_id'] && $_POST['nove_heslo'] == $_POST['nove_heslo_znovu'])
    {
        Db::query('
        UPDATE uzivatele
        SET heslo=sha1(?)
        WHERE id=?
        ', $_POST['nove_heslo'], $_SESSION['uzivatel_id']);
        echo('<p style="text-align: center; font-size: 25px;">Heslo bylo úspěšně změněno.</p>');
    }
    else
        echo('<p style="text-align: center; font-size: 25px;">Heslo se nepodařilo změnit, zkuste to znovu.</p>');
}
Nahoru Odpovědět
9.9.2016 0:23
Neaktivní uživatelský účet
Avatar
Jan Lupčík
Tvůrce
Avatar
Odpovídá na Neaktivní uživatel
Jan Lupčík:9.9.2016 6:40

Jenom takové dvě menší poznámky. :)

  1. Z hlediska pohodlnosti pro uživatele bych doporučoval mít dvě podmínky. Nejdřív ověřit staré heslo a dát mu zprávu o tom, že je špatně a pak ověřovat, zda opakování nového hesla je správně a dát mu o tom zprávu.
  2. V místní třídě s databází se musí ty parametry pro dotaz předávat v poli.
Editováno 9.9.2016 6:41
Nahoru Odpovědět
9.9.2016 6:40
TruckersMP vývojář
Avatar
pgarsky
Člen
Avatar
Odpovídá na Jan Lupčík
pgarsky:9.9.2016 14:10

No, já zatím neumím odesílat maily s těmahle informace. Tak se tě rovnou ptám, jak na to a taky bych potřeboval vědět, jak v emailu odřádkovat nový řádek.

Nahoru Odpovědět
9.9.2016 14:10
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
Odpovídá na Jan Lupčík
Neaktivní uživatel:9.9.2016 15:58

1. vycházel sem z původního kódu tazatele, abych mu nastínil způsob jakým má nad tím uvažovat, nicméně:

if ($_POST)
{
    if (sha1($_POST['stare_heslo']) == Db::query('SELECT heslo FROM uzivatele WHERE id=?', $_SESSION['uzivatel_id'])
    {
                if($_POST['nove_heslo'] == $_POST['nove_heslo_znovu'])
                {
                        Db::query('UPDATE uzivatele SET heslo = sha1(?) WHERE id = ?', $_POST['nove_heslo'], $_SESSION['uzivatel_id']);
                        $zprava = 'Heslo bylo úspěšně změněno.';
                }
                else{$zprava = 'Zadání nového hesla se neshodují.';}
    }
        else {$zprava = 'Špatně zadané původní heslo.';}
}
if (isset($zprava)){echo('<p>' . $zprava . '</p>');}

2. vycházím opět z původního kódu v tutorialu, nějak víc sem nezkoumal ani wrapper ani nic dalšího. Případná oprava je už jen drobnost.

Editováno 9.9.2016 15:59
Nahoru Odpovědět
9.9.2016 15:58
Neaktivní uživatelský účet
Avatar
Odpovídá na pgarsky
Neaktivní uživatel:9.9.2016 16:18

Maily obsahující heslo ani neposílej.

Odřádkování v mailu provedeš podle toho v jakém typu (dáno hlavičkou content-type) to odesíláš.
Pokud posíláš jako prostý text (content-type: text/plain) tak odřádkuješ pomocí

\n

, pokud to posíláš jako formátovaný html (content-type: text/html) tak musíš používat tag

<br>
Nahoru Odpovědět
9.9.2016 16:18
Neaktivní uživatelský účet
Avatar
pgarsky
Člen
Avatar
Odpovídá na Neaktivní uživatel
pgarsky:9.9.2016 21:10

No jo, ale jak to heslo potom říct tomu uživateli ?

Nahoru Odpovědět
9.9.2016 21:10
Pokud ti něco jde těžko, znamená to, že jdeš tou správnou cestou...
Avatar
Odpovídá na pgarsky
Neaktivní uživatel:9.9.2016 22:56

Ten uživatel to heslo napíše. Tak nějak se předpokládá, že uživatel ví, co za heslo napsal.

Nahoru Odpovědět
9.9.2016 22:56
Neaktivní uživatelský účet
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 28 zpráv z 28.