Autor Zpráva
XolyCZ
Profil
Ahoj, potřebuju poradit jak to nějak líp poskládat dohromady, aby to fungovalo. Mám udělaný formulář na změnu ůdajů pro uživatele a nefunguje mi to tak jak by mělo. HTML část vypadá takhle:
<?php
    if($hlaska){
    echo("<p>$hlaska</p>");
    }
    ?>
<form method="post" name="nickname_post">
    Změna tvého nickamu<br>
    <input type="text" name="Nickname"/><br>
    Pro potvrzení napiš "1"<br>
    <input type="text" name="Nickname_potvrzeni"/><br>
    <button type="submit"/>Změnit nickname</button>
    </form>
    
    <form method="post" name="jmeno_post">
    Volitelné jméno<br>
    <input type="text" name="Jmeno"/><br>
    Pro potvrzení napiš "2"<br>
    <input type="text" name="Jmeno_potvrzeni"/><br>
    <button type="submit"/>Změnit jméno</button>
    </form>
    
    <form method="post" name="prijmeni_post">
    Volitelné příjmení<br>
    <input type="text" name="prijmeni"/><br>
    Pro potvrzení napiš "3"<br>
    <input type="text" name="Prijmeni_potvrzeni"/><br>
    <button type="submit"/>Změnit příjmení</button>
    </form>
    
    <form method="post" name="email_post">
    Změna tvého emailu<br>
    <input type="text" name="email"/><br>
    Pro potvrzení napiš "4"<br>
    <input type="text" name="Email_potvrzeni"/><br>
    <button type="submit"/>Změnit email</button>
    </form>
    
    <form method="post" name="heslo_post">
    Staré heslo<br>
    <input type="password" name="heslo_stare" autocapitalize="none" autocomplete="off"/><br>
    Nové heslo<br>
    <input type="password" name="heslo" autocapitalize="none" autocomplete="off"/><br>
    <button type="submit"/>Změnit heslo</button>

Php co mi to obsluhuje vypadá takhle:
if($_POST['Nickname_potvrzeni']==1){
        Db::query('
                UPDATE  hraci_online
                SET  Nickname=?
                WHERE Hrac_id=?                    
            ',  $_POST['Nickname'], $_SESSION['Hrac_id_online']);
            $_SESSION['Nickname_online']=$_POST['Nickname'];
            $Nickname_zmena=$_SESSION['Nickname_online'];
            $hlaska="Tvůj nickname byl změněn na <span id='span_edit'>$Nickname_zmena</span>.";
    }
    
    else if($_POST['Jmeno_potvrzeni']==2){
        Db::query('
                UPDATE  hraci_online
                SET  Jmeno=?
                WHERE Hrac_id=?                    
            ',  $_POST['Jmeno'], $_SESSION['Hrac_id_online']);
            $_SESSION['jmeno_online']=$_POST['Jmeno'];
            $Jmeno_zmena=$_SESSION['jmeno_online'];
            $hlaska="Tvé jméno bylo změněno na <span id='span_edit'>$Jmeno_zmena</span>.";
    }
    
    else if($_POST['Prijmeni_potvrzeni']==3){
        
        Db::query('
                UPDATE  hraci_online
                SET  Prijmeni=?
                WHERE Hrac_id=?                    
            ',  $_POST['prijmeni'], $_SESSION['Hrac_id_online']);
            $_SESSION['prijmeni_online']=$_POST['prijmeni'];
            $Prijmeni_zmena=$_SESSION['prijmeni_online'];
            $hlaska="Tvé příjmení bylo změněno na <span id='span_edit'>$Prijmeni_zmena</span>.";
    }
    else if($_POST['Email_potvrzeni']==4){
        
        Db::query('
                UPDATE  hraci_online
                SET  Email=?
                WHERE Hrac_id=?                    
            ',  $_POST['email'], $_SESSION['Hrac_id_online']);
            $_SESSION['email_online']=$_POST['email'];
            $Email_zmena=$_SESSION['email_online'];
            $hlaska="Tvůj email byl změněn na <span id='span_edit'>$Email_zmena</span>. <span>Teď se přihlašuješ pod tímto emailem!</span>";
    }
    
    else if($_SESSION['heslo_online']==$_POST['heslo_stare']){
        $Heslo=password_hash($_POST['heslo'], PASSWORD_DEFAULT);
        Db::query('
                UPDATE  hraci_online
                SET  Heslo=?
                WHERE Hrac_id=?                    
            ',  $Heslo, $_SESSION['Hrac_id_online']);
            $_SESSION['heslo_online']=$_POST['heslo'];
            $hlaska="Tvé heslo bylo změněno.";
    }else{$hlaska='Špatné ověření.';}

Nickname, jméne, příjmení a email vypisuju potom na stránkách v prostředí účtu pomocí tohoto:
<li>Tvé jméno: <span><?= htmlspecialchars($_SESSION['jmeno_online'])?></span></li>
<li>Tvé příjmení: <span><?= htmlspecialchars($_SESSION['prijmeni_online'])?></span></li>
<li>Tvůj email: <span><?= htmlspecialchars($_SESSION['email_online'])?></span></li>

Kvůli tomuto mám v těch podmínkách ještě ty změny těch SESSION proměnných, aby to bylo vidět aktuálně. Heslo potom beru z přihlášení přímo takhle: $_SESSION['heslo_online'] = $_POST['Heslo']; z html
Heslo:<br>
<input type="password" name="Heslo" autocapitalize="none" autocomplete="off"/><br>

Vždycky mi to funguje po podmínku s emailem, když přidám heslo, už to dělá bordel. Asi nebude lehké se v tom zorientovat, ale našel by se někdo, kdo by mi to třeba zjednodušil nebo mi řekl co dělám špatně? Už nevím co dál zkoušet :/ Díky moc.
T-fon
Profil
Dobrý je napsat, jakou chybovou hlášku ti to vypisuje. Nebo co znamená "už to dělá bordel". Pak je snažší ti poradit s odstraněním problému.
XolyCZ
Profil
T-fon:
Chtěl jsem si třeba změnit email a změnilo mi to heslo, nevím na jaké a nevím proč.
T-fon
Profil
No máš to takový hodně divoký... Předělávat komplet to asi nechceš, tak já bych nejdřív vyhodil ty divný potvrzení. Dej si tam třeba skrytej input (hidden), a pak v těch podmínkách dej třeba if(isset($_POST['Nickaneme...
XolyCZ
Profil
T-fon:
Já bych to klidně předělal celé, protože je v tom troch bordel mi příjde :D


Máš namysli takhle jo?
if(isset($_POST['Nickname_potvrzeni'])){
        Db::query('
                UPDATE  hraci_online
                SET  Nickname=?
                WHERE Hrac_id=?                    
            ',  $_POST['Nickname'], $_SESSION['Hrac_id_online']);
            $_SESSION['Nickname_online']=$_POST['Nickname'];
            $Nickname_zmena=$_SESSION['Nickname_online'];
            $hlaska="Tvůj nickname byl změněn na <span id='span_edit'>$Nickname_zmena</span>.";
    }
T-fon
Profil
To je dobře :). Na netu najdeš mraky návodů na podobný věci.
Ale jinak by možná stačilo to co jsem ti radil, já si to vyzkoušel a funguje to OK.

Edit: ano, takhle, a vyhodit ty čísla a použít hidden input.
XolyCZ
Profil
T-fon:
Ještě teda prosím tě, mám v databázi políčko s oprávněním, které ověřuju na webu kvůli zobrazení kolonky v menu. Když je to oprávnění menší, podmínka se nesplní a ta kolonka vidět nejde. Když oprávnění zvětším, tak se splní podmínka a jde vidět kolonka. Když ale zpětně zase snížím to oprávnění, tak jak kdyby to v té SESSION zůstalo a ta podmínka už platí pokaždé co se přihlásí ten dotyčný. Nevíš, čím by to mohlo být? Tohle jde z databáze $_SESSION['opravneni_online'] = $Hrac['opravneni']; a session ukončuju takhle:
if (isset($_GET['odhlasit']))
{
        session_destroy();
        header('Location: index.php?str=uvod');
        exit();
}
Keeehi
Profil
Ono je to potřeba předělat téměř celé. Správně by jsi měl mít jeden formulář, ve kterém budeš mít všechny inputy na změnu všeho. Jako value budou mít aktuální hodnotu. Jediné, co máš trochu dobře je heslo. Tam mají být takto dva inputy bez value. Ty by taky případně mohly být v jiném formuláři ale mohou zůstat se všemi ostatními. Dají se udělat obě varianty. Hodnoty je po odeslání potřeba kontrolovat zda nejsou prázdné (tedy pokud to u něčeho nechceš dovolit) a pro lepší UX pak i inputům přidat atribut required. Ovšem na kontrolu vyplnění je potřeba použít if(empty($_POST['Nickname_potvrzeni'])){. V tom jak tvoříš hlášku máš XSS zranitelnost. Téměř všechny formuláře trpí na CSRF zranitelnost. To se řeší buď tokenem, nebo že pro každou změnu je potřeba zadat aktuální heslo. No a tu kontrolu hesla máš taky špatně. Přece nechceš kontrolovat, že staré a nové heslo se shodují, ale že staré odpovídá hashi v databázi. Taky by to chtělo kontrolovat unikátnost některých polí. Například určitě nebude správně, aby si někdo mohl změnit nick nebo email na něco co už někdo jiný používá.
XolyCZ
Profil
Keeehi:
Znáš nějakou stránku kde to někdo takhle ukazuje?


T-fon:
To políčko v tom menu už jsem si spravil :)
XolyCZ
Profil
Tak jsem teda vymyslel tohle, vypadá to už od pohledu líp, ale pořád to nefunguje, neprovede se asi ani ta první podmínka.
<?php
         if (isset($hlaska))
            echo('<p>' . htmlspecialchars($hlaska) . '</p>');
    ?>
    
    <form method="post" name="Zmena_udaju">
    Změna tvého nickamu<br>
    <input type="text" name="Nickname" value="<?= htmlspecialchars($_SESSION['Nickname_online'])?>" required/><br>
    
    Volitelné jméno<br>
    <input type="text" name="Jmeno" value="<?= htmlspecialchars($_SESSION['Jmeno_online'])?>"/><br>

    Volitelné příjmení<br>
    <input type="text" name="Prijmeni" value="<?= htmlspecialchars($_SESSION['Prijmeni_online'])?>"/><br>

    Změna tvého emailu<br>
    <input type="email" name="Email" value="<?= htmlspecialchars($_SESSION['Email_online'])?>" required/><br>
    
    Heslo pro potvrzení<br>
    <input type="password" name="Heslo" autocapitalize="none" autocomplete="off" required/><br>
    
    <button type="submit"/>Změnit údaje</button>
    </form>

if(isset($_POST['Zmena_udaju'])){
            if(!empty($_POST['Nickname'])){
                if(!empty($_POST['Email'])){
                    if(!empty($_POST['Heslo'])){
                        $Nickname = Db::querySingle('
                        SELECT COUNT(*)
                        FROM hraci_online
                        WHERE Nickname=?
                        LIMIT 1
                        ', $_POST['Nickname']);
                        $Email = Db::querySingle('
                        SELECT COUNT(*)
                        FROM hraci_online
                        WHERE Email=?
                        LIMIT 1
                        ', $_POST['Email']);
                        $Hrac = Db::queryOne('
                        SELECT Heslo
                        FROM hraci_online
                        WHERE Email=?
                        ', $_POST['Email']);
                        if($Nickname){
                            $hlaska="Tento nickname je již použit.";
                        }
                        else if($Email){
                            $hlaska="Tento email je již použit.";
                        }
                        else if(password_verify($_POST['Heslo'], $Hrac['Heslo'])){
                            $Heslo = password_hash($_POST['Heslo'], PASSWORD_DEFAULT);
                            Db::query('
                          UPDATE hraci_online
                          SET Nickname=?, Email=?, Heslo=?, Jmeno=?, Prijmeni=?     
                          WHERE _id=?
                          ', $_POST['Nickname'], $_POST['Email'], $Heslo, $_POST['Jmeno'], $_POST['Prijmeni'], $_POST['Hrac_id_online']);
                            $hlaska="Údaje byly úspěšně aktualizovány.";
                        }
                        else{$hlaska="Špatně zadané heslo.";}
                    }
                    else{$hlaska="Nevyplnil jsi heslo.";}
                }
                else{$hlaska="Nevyplnil jsi email.";}
            }
            else{$hlaska="Nevyplnil jsi nickname.";}
        }
Keeehi
Profil
Neprovede se to proto, že form sice může mít atribut name, ale to není ten samý name jako u inputů. Nemá žádnou hodnotu a taky se neodesílá. Co se všechno odesílá zjistíš elegantně pomocí var_dump($_POST);
XolyCZ
Profil
Keeehi:
Aha. Takže když dám na konec tohle <input type="hidden" name="Zmena_udaju"/>, bude to fungovat. No a jinak už je to dobře z hledisa bezpečnosti a tak?

Musím ale upravit ty podmínky, pokud nezmění email nebo nickname, aby to nehodilo, že už je použitý.
Keeehi
Profil
XolyCZ:
Takže když dám na konec tohle <input type="hidden" name="Zmena_udaju"/>, bude to fungovat.
Tak to je jedna možnost. Druhá je, že to bude input typu submit a vyhodíš ten button. A třetí je, že prostě ověříš, že je v poli klíč jednoho z už existujících inputů. Pokud tam je, tak je jasné, že byl formulář odeslán. Není potřeba na kontrolu odeslání vytvářet nic nového.

No a jinak už je to dobře z hledisa bezpečnosti a tak?
Z hlediska bezpečnosti je to o něco lepší. Doufám, že ta ta databázová vrstva kterou jsi zvolil tě automaticky sama chrání proti SQL injection. To vypisování $hlaska je teď až trochu moc chráněné, protože veškerý obsah této proměnné pochází z důvěryhodného zdroje (od tebe) jelikož do toho nikde nepřidáváš uživatelský vstup. Ničemu to tam ale nevadí. Naopak bude dobré, když to tam zůstane. Pokud budeš někdy v budoucnu hlášky měnit a přidáš tam uživatelský vstup, mohl by jsi to zapomenout ošetřit i ve výpisu.

Je tam teď pár logických chyb. Když z databáze vytahuješ heslo, nemůžeš použít $_POST['Email'] protože pokud bude člověk měnit email, tak ho v té době nemá ještě uložený v databázi, takže to nic nenajde. Musíš použít hodnotu ze session a to buď email, nebo lépe id. A jelikož v tomto formuláři není umožněna změna hesla, pak je zbytečné počítat nový hash toho stejného hesla a updatovat ho v databázi.
XolyCZ
Profil
Dobře tak tohle jsem si vyřešil, teď ale musím dořešit to, když změní email, ověřit ho, jestli není v databázi u jiného uživatele a poslat to. Asi se to celkem ještě rozvine. Teď to mám takhle a chybí tam vlastně to co jsem teď napsal no.

if(isset($_POST['Zmena_udaju'])){
            if(!empty($_POST['Nickname'])){
                if(!empty($_POST['Email'])){
                    if(!empty($_POST['Heslo'])){
                        $Nickname = Db::querySingle('
                        SELECT COUNT(*)
                        FROM hraci_online
                        WHERE Nickname=?
                        LIMIT 1
                        ', $_POST['Nickname']);
                        $Email = Db::querySingle('
                        SELECT COUNT(*)
                        FROM hraci_online
                        WHERE Email=?
                        LIMIT 1
                        ', $_POST['Email']);
                        $Hrac = Db::queryOne('
                        SELECT Heslo
                        FROM hraci_online
                        WHERE Hrac_id=?
                        ', $_SESSION['Hrac_id_online']);
                        if($_POST['Nickname']==$_SESSION['Nickname_online']){
                            if($_POST['Email']==$_SESSION['Email_online']){
                                if(password_verify($_POST['Heslo'], $Hrac['Heslo'])){
                                    Db::query('
                                    UPDATE hraci_online
                                    SET Nickname=?, Email=?, Jmeno=?, Prijmeni=?     
                                    WHERE Hrac_id=?
                                    ', $_POST['Nickname'], $_POST['Email'], $_POST['Jmeno'], $_POST['Prijmeni'], $_SESSION['Hrac_id_online']);
                                    $hlaska="Údaje byly úspěšně aktualizovány.";
                                }
                                else{$hlaska="Špatně zadané heslo.";}
                            }
                            else if($Email){
                                $hlaska="Tento email je již použit.";
                            }
                        }
                        else if($Nickname){
                            $hlaska="Tento nickname je již použit.";
                        }
                    }
                    else{$hlaska="Nevyplnil jsi heslo.";}
                }
                else{$hlaska="Nevyplnil jsi email.";}
            }
            else{$hlaska="Nevyplnil jsi nickname.";}
        }
Keeehi
Profil
Tohle je hrozný spaghetti code. Já normálně používám nějaký framework a OOP a celé by se to tam řešilo koncepčně úplně jinak, ale pokud bychom tvůj kód uzavřeli alespoň do nějaké funkce, bude to alespoň trochu přehlednější. I když ideál to nebude, jelikož funkce by neměly být extra dlouhé ale zlepšení to bude a bude to pro tebe i pochopitelné. Jelikož se snažíš, tak tady máš kód jak bych to udělal já, kdybych měl dodělat jen tuto část projektu a nemohl to celé překopat.

<?php
function changePlayersDetails(&$message) {
    if (empty($_POST['nick'])) {
        $message = 'Nevyplnil jsi nick.<br>';
    }

    if (empty($_POST['email'])) {
        $message .= 'Nevyplnil jsi email.<br>';
    }

    if (empty($_POST['current_password'])) {
        $message .= 'Nevyplnil jsi aktuální heslo pro potvrzení změny.<br>';
    }
    
    if (!empty($message)) {
        return false;
    }
    
    
    $nick = Db::querySingle(
        'SELECT COUNT(*) FROM hraci_online WHERE Nickname=? LIMIT 1',
        $_POST['nick']
    );
    
    $email = Db::querySingle(
        'SELECT COUNT(*) FROM hraci_online WHERE Email=? LIMIT 1 ',
        $_POST['email']
    );

    if ($nick > 0 && $_POST['nick'] !== $_SESSION['Nickname_online']) {
        $message = 'Nick '.htmlspecialchars($_POST['nick'], ENT_QUOTES).' je již použit.<br>';
    }
    
    if ($email > 0 && $_POST['email'] !== $_SESSION['Email_online']) {
        $message .= 'Email '.htmlspecialchars($_POST['email'], ENT_QUOTES).' je již použit.<br>';
    }

    if (!empty($message)) {
        return false;
    }
    

    $password = Db::querySingle(
        'SELECT Heslo FROM hraci_online WHERE Hrac_id=? LIMIT 1',
        $_SESSION['Hrac_id_online']
    );

    if(!password_verify($_POST['current_password'], $password)) {
        $message = 'Špatně zadané aktuální heslo.<br>';
        return false;
    }
    
    
    Db::query(
        'UPDATE hraci_online SET Nickname=?, Email=?, Jmeno=?, Prijmeni=?, Heslo=? WHERE Hrac_id=?',
        $_POST['nick'],
        $_POST['email'],
        $_POST['firstname'],
        $_POST['lastname'], 
        empty($_POST['password']) ? $password : password_hash($_POST['password'], PASSWORD_DEFAULT),
        $_SESSION['Hrac_id_online']
    );
                
    $message = "Údaje byly úspěšně aktualizovány.<br>";
    return true;
}

if (isset($_POST['nick'])) {
    $message = '';
    $status  = changePersonsDetails($message);
    echo '<p class="' . ($status ? "success" : "error") . '">' . $message . '</p>';
}
?>

<form method="post">
    Nick *<br>
    <input type="text" name="nick" value="<?= htmlspecialchars($_POST['nick'] ?? $_SESSION['Nickname_online'], ENT_QUOTES)?>" required/><br>

    Email *<br>
    <input type="email" name="email" value="<?= htmlspecialchars($_POST['email'] ?? $_SESSION['Email_online'], ENT_QUOTES)?>" required/><br>

    Jméno<br>
    <input type="text" name="firstname" value="<?= htmlspecialchars($_POST['firstname'] ?? $_SESSION['Jmeno_online'], ENT_QUOTES)?>"/><br>

    Příjmení<br>
    <input type="text" name="lastname" value="<?= htmlspecialchars($_POST['lastname'] ?? $_SESSION['Prijmeni_online'], ENT_QUOTES)?>"/><br>

    Nové heslo <small>Vyplň jen v případě změny</small><br>
    <input type="password" name="password" autocapitalize="none" autocomplete="off"/><br>
    
    Aktuální heslo * <small>Pro potvrzení změn</small><br>
    <input type="password" name="current_password" autocapitalize="none" autocomplete="off" required/><br>

    <button type="submit">Změnit údaje</button>
</form>

Jo a tu třídu Db jsi vzal odkud? Jsi si jistý, že je bezpečná nebo že ji bezpečně používáš?
XolyCZ
Profil
Noo tak tohle je trošku jinačí kód :D Mi by asi ten výsledný update té databáze vyšel 3x, když jsem nad tím tak přemýšlel, takže mě taky napadlo to hodit jako funkci a potom ji jenom volat, ale ty jsi přišel s trošku profesionálnějším způsobem. Vidím v tom nějakou logiku, jenomže tím, že ten jazyk prostě tak neznám, tak to nevymyslím takhle z fleku, nenapadně mě to. Je to sice nějak podobné Céčku, ale tam toho zase taky tak hodně neznám, spíš právě ty podmínky a tak. Trošku fantazie by to chtělo :D. Díky moc, vyzkouším to.

Ta Db třída je od kluků z www.itnetwork.cz/php a jestli jsem to dobře četl, tak je to právě bezpečné tím, že se ty hodnoty nezadávají přímo, ale zvlášť a ty se pak doplní místo těch otazníků. Můžu ti tady hodit ten jejich kód.

class Db
{
    /**
     * @var PDO Databázové spojení
     */
    private static $connection;

    /**
     * @var array Výchozí nastavení ovladače
     */
    private static $options = array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
        PDO::ATTR_EMULATE_PREPARES => false,
    );

    /**
     * Připojí se k databázi pomocí daných údajů
     * @param string $host Název hostitele
     * @param string $database Název databáze
     * @param string $user Uživatelské jméno
     * @param string $password Heslo
     */
    public static function connect($host, $database, $user, $password)
    {
        if (!isset(self::$connection)) {
            $dsn = "mysql:host=$host;dbname=$database";
            self::$connection = new PDO($dsn, $user, $password, self::$options);
        }
    }

    /**
     * Spustí dotaz a vrátí PDO statement
     * @param array $params Pole, kde je prvním prvkem dotaz a dalšími jsou parametry
     * @return \PDOStatement PDO statement
     */
    private static function executeStatement($params)
    {
        $query = array_shift($params);
        $statement = self::$connection->prepare($query);
        $statement->execute($params);
        return $statement;
    }

    /**
     * Spustí dotaz a vrátí počet ovlivněných řádků. Dále se předá libovolný počet dalších parametrů.
     * @param string $query Dotaz
     * @return int Počet ovlivněných řádků
     */
    public static function query($query) {
        $statement = self::executeStatement(func_get_args());
        return $statement->rowCount();
    }

    /**
     * Spustí dotaz a vrátí z něj první sloupec prvního řádku. Dále se předá libovolný počet dalších parametrů.
     * @param string $query Dotaz
     * @return mixed Hodnota prvního sloupce z prvního řádku
     */
    public static function querySingle($query) {
        $statement = self::executeStatement(func_get_args());
        $data = $statement->fetch();
        return $data[0];
    }

    /**
     * Spustí dotaz a vrátí z něj první řádek. Dále se předá libovolný počet dalších parametrů.
     * @param string $query Dotaz
     * @return mixed Pole výsledků nebo false při neúspěchu
     */
    public static function queryOne($query) {
        $statement = self::executeStatement(func_get_args());
        return $statement->fetch(PDO::FETCH_ASSOC);
    }

    /**
     * Spustí dotaz a vrátí všechny jeho řádky jako pole asociativních polí. Dále se předá libovolný počet dalších parametrů.
     * @param string $query Dotaz
     * @return mixed Pole řádků enbo false při neúspěchu
     */
    public static function queryAll($query) {
        $statement = self::executeStatement(func_get_args());
        return $statement->fetchAll(PDO::FETCH_ASSOC);
    }

    /**
     * Umožňuje snadné vložení záznamu do databáze pomocí asociativního pole
     * @param string $table Název tabulky
     * @param array $data Asociativní pole, kde jsou klíče sloupce a hodnoty hodnoty
     * @return int Počet ovlivněných řádků
     */
    public static function insert($table, $data) {
        $keys = array_keys($data);
        self::checkIdentifiers(array($table) + $keys);
        $query = "
            INSERT INTO `$table` (`" . implode('`, `', $keys) . "`)
            VALUES (" . str_repeat('?,', count($data) - 1) . "?)
        ";
        $params = array_merge(array($query), array_values($data));
        $statement = self::executeStatement($params);
        return $statement->rowCount();
    }

    /**
     * Umožňuje snadnou modifikaci záznamu v databázi pomocí asociativního pole
     * @param string $table Název tabulky
     * @param array $data Asociativní pole, kde jsou klíče sloupce a hodnoty hodnoty
     * @param string $condition Řetězec s SQL podmínkou (WHERE)
     * @return mixed
     */
    public static function update($table, $data, $condition) {
        $keys = array_keys($data);
        self::checkIdentifiers(array($table) + $keys);
        $query = "
            UPDATE `$table` SET `".
            implode('` = ?, `', array_keys($data)) . "` = ?
            $condition
        ";
        $params = array_merge(array($query), array_values($data), array_slice(func_get_args(), 3));
        $statement = self::executeStatement($params);
        return $statement->rowCount();
    }

    /**
     * Vrátí poslední ID posledního záznamu vloženého pomocí INSERT
     * @return mixed Id posledního záznamu
     */
    public static function getLastId()
    {
        return self::$connection->lastInsertId();
    }

    /**
     * Ošetří string proti SQL injekci
     * @param string $string Řetězec
     * @return mixed Ošetřený řetězec
     */
    public static function quote($string)
    {
        return self::$connection->quote($string);
    }

    /**
     * Zkontroluje, zda identifikátory odpovídají formátu identifikátorů
     * @param array $identifiers Pole identifikátorů
     * @throws \Exception
     */
    private static function checkIdentifiers($identifiers)
    {
        foreach ($identifiers as $identifier)
        {
            if (!preg_match('/^[a-zA-Z0-9\_\-]+$/u', $identifier))
                throw new Exception('Dangerous identifier in SQL query');
        }
    }
}



Funguje to jak má, akorát tam máš malý překlep, asi protože jsi to psal pozdě v noci. Na tu hlášku nad FORMem voláš špatnou funkci, máš tam changePersonsDetails místo changePlayersDetails.


Keeehi:
Ještě když už jsi mi to teda tak pěkně napsal, co prosím tě znamenají ty "??" a "ENT_QUOTES" v těch inputech? A ještě nechápu úplně tu podmínku co ověřuje, jestli je nebo není použitý ten nickname nebo email.
Keeehi
Profil
To není ani moc o znalosti PHP jako o tom vymyslet, jak to za sebe lépe poskládat. Nic moc nového jsem nepoužil. Jen tu funkci ale to bylo hlavně kvůli tomu, že jsem potřeboval běh programu uprostřed "ukončit" a skočit někam dál na což nejjednodušší a nejčistější řešení je použít funkci. Ale ano, když člověk nějakou chvíli programuje tak už se pravděpodobně s podobnou situací setkal a ví, že spousta zanořených ifů se dá přepsat jako posloupnost jejich negací. To ale není tak úplně závislé na programovacím jazyku.

Co se Db třídy týče, tak to vypadá, že bezpečné to je. Ono i PDO a prepared statements které třída obaluje mohou nést bezpečnostní rizika ale tady to vypadá, že je to napsané správně.

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:

0