NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Registrácia v OOP

V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Dominik Gavrecký:3.7.2015 19:45

Zdravím komunitu,

chcem sa vás všetkých opýtať či z vás niekto nemá spravenú registráciu v OOP a nevadilo bi mu zverejniť kód prípadne mi ho zaslať na študijne účely. Pár dni skúšam vytvoriť čo najlepšiu registráciu v OOP no nejako sa mi to nedarí.

Hľadal som samozrejme aj na internete kde sú už však priveľmi zložité kódy na začiatočníka v OOP alebo zastaralé.

Viz.

<?php
require("db.php");
class Uzivatele{
  function registrace($prezdivka, $email, $heslo){
    $prezdivka = str_replace(" ", "_", $prezdivka);
    if(!empty($prezdivka) AND !empty($email) AND !empty($heslo)){
      $pocet_uzivatelu = mysql_num_rows(mysql_query("SELECT * FROM uzivatele WHERE email='".$email."'"));
      if($pocet_uzivatelu<1){
        $query = "INSERT INTO uzivatele (prezdivka, email, heslo, ip, datum) VALUES ('".mysql_real_escape_string($prezdivka)."', '".mysql_real_escape_string($email)."', '".sha1(md5($heslo))."', '".$_SERVER['REMOTE_ADDR']."', now())";
        if(mysql_query($query)==true){
          print "Úspěšně zaregistrován!";
        }else{
          print "Chyba při registraci!";
        }
      }else{
        print "Tento email je již použit!";
      }
    }else{
      print "Pole nesmí být prázdné!";
    }
  }
}
$uzivatel = new Uzivatele;
$uzivatel->registrace("Nookyn", "[email protected]", "test");
?>
Odpovědět
3.7.2015 19:45
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Adam Ježek
Tvůrce
Avatar
Adam Ježek:3.7.2015 19:59

Zkus se podívat na zdejší tutoriál o RS v OOP, jak je to tam dělané http://www.itnetwork.cz/php/mvc

Nahoru Odpovědět
3.7.2015 19:59
Počkej chvíli, poradím se s křišťálovou koulí.
Avatar
Odpovídá na Adam Ježek
Dominik Gavrecký:3.7.2015 20:03

Tam je to viac komplexné. Ja by som chcel čistý pekný a jednoduchý kód iba pre registráciu. Ale skúšal som sa držať aj miesených tutorialov ale mám stým celkom problémy preto by som chcel nejaký preview code.

Nahoru Odpovědět
3.7.2015 20:03
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Odpovídá na Dominik Gavrecký
Martin Konečný (pavelco1998):3.7.2015 21:17

Jdeš na to špatně - sílu OOP nepoznáš na jednoduché registraci, která v podstatě ani objektově udělat nejde (uděláš procedurální kód ve třídě, nic víc).

Zkus se podívat na architekturu MVC, ta hodně s OOP souvisí, podle toho dokážeš udělat celý web.

Pokud ale budu řešit samotnou registraci, řešeních je několik, napadají mě tyto:

  1. Budeš mít třídu na správu uživatelů (třeba UsersManager), který se bude starat o uživatele obecně (vytvářet, mazat, vracet instance dle ID apod.).

Registrace by mohla vypadat třeba takto.

class User
{

  public $name, $pass, $email;

}

class UsersManager
{

  // spojení s databází se předá nejspíše konstruktorem
  private $db;

  public function addUser($user)
  {
    // zde by teoreticky mohla být validační pravidla, např.
    if (strlen($user->name) < 5) {
      throw new Exception("Jméno musí obsahovat minimálně 5 znaků");
    }

    // předpokládejme chytrý DB wrapper, který umí sestavit INSERT dle pole
    $this->db->insert(array(
      "name" => $user->name,
      "pass" => nejakaHashFunkce($user->password),
      "email" => $user->email
    ));

    // automaticky se vyhodí výjimka, pokud uživatel s takovým jménem nebo mailem v DB existuje (předpokládejme klíč UNIQUE na těch sloupcích)
  }

}


$db = new DBWrapper("login údaje");
if ($_POST) {
  $user = new User();
  $user->name = $_POST["name"];
  $user->pass = $_POST["pass"];
  $user->email = $_POST["email"];

  $usersManager = new UsersManager($db);

  try {
    $usersManager->addUser($user);
  } catch (PDOException $e) {
    echo "takový uživatel již existuje";
  } catch (Exception $e) {
    // nějaká validační chyba
    echo $e->getMessage();
  }
}

Edit: Ještě dodám, že by validační pravidla teoreticky mohla mít i samotná třída User, aby nebyla jen obyčejnou přepravkou na data. Např.

class User
{

  private $name;

  public function setName($name)
  {
    if (strlen($name) < 5) {
      throw new Exception("jméno je moc krátké");
    }

    $this->name = $name;
  }

}
  1. Budeš mít třídu User, která se bude starat i o registraci uživatele. To mi ale nepřijde z pohledu OOP jako čistý návrh, protože by User měl reprezentovat buď existujícího nebo neexistujícího uživatele (ne oboje).

Navíc tento způsob využívá antipatternu ActiveRecord, který neni obvykle dobrý používat.

class User
{

  public $db;
  public $jmeno, $heslo, $email;

  public function save()
  {
    $this->db->insert(array(/* stejně jak v předchozím případě */));
  }

}

$user = new User($db);
$user->name = $_POST["name"];
// atd.
$user->save();
Editováno 3.7.2015 21:22
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
3.7.2015 21:17
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Martin Konečný (pavelco1998):3.7.2015 21:29

Nemůžu svůj příspěvek znovu editovat, proto to napíšu do nového příspěvku.

Díval jsem se teď na tvůj kód a měl by ses podívat na objektový ovladač PDO (který má mimo jiné oproti mysql_* ovladači mnoho výhod).

Nahoru Odpovědět
3.7.2015 21:29
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Dominik Klapuch:3.7.2015 21:35

Je mnoho způsobů, jak daný problém řešit. Mohl by sis vytvořit několik vrstev, kde každá se ti bude starat o něco jiné. Jedna vrstva o validaci, další vsrtva o dotazy, další vrstva ti bude tyto dvě vrsty spojovat a zároveň to bude jediná vrstva s kterou budeš pracovat. Já jsem ti v rychlosti napsal tento kód. Mnohé by šlo určitě změnit a dekomponovat, nicméně pro začátek by ti to snad mohlo stačit.

<?php

interface Registration {
        public function register($username, $email, $password);
}


class SimpleRegistration implements Registration {
        private $cryptable;
        private $registration;

        public function __construct(Cryptable $cryptable, Registration $registration) {
                $this->cryptable = $cryptable;
                $this->registration = $registration;
        }

        public function register($username, $email, $password) {
                if(!$this->isEmail($email))
                        throw new UnexpectedValueException('Toto není platný email');
                $this->registration->register($username, $email, $this->cryptable->crypt($password));
        }

        private function isEmail($email) {
                return filter_var($email, FILTER_VALIDATE_EMAIL); // lepší použít regex
        }
}


class DatabaseRegistration implements Registration {
        private $database;

        public function __construct(Database $database) {
                $this->database = $database;
        }

        public function register($username, $email, $password) {
                if($this->isEmailExists($email))
                        throw new DuplicateException('Tento email již existuje');
                elseif($this->isUsernameExists($usernmae))
                        throw new DuplicateException('Toto jméno již existuje');
                $this->createNewUser($username, $email, $password);
        }

        private function isEmailExists($email) {
                $query = 'SELECT 1 FROM users WHERE email = ?';
                return (bool)$this->database->fetch($query, [$email]);
        }

        private function isUsernameExists($username) {
                $query = 'SELECT 1 FROM users WHERE username = ?';
                return (bool)$this->database->fetch($query, [$username]);
        }

        private function createNewUser($username, $email, $password) {
                $query = 'INSERT INTO users (username, email, password) VALUES (?,?,?)';
                return $this->database->query($query, [$username, $email, $password]);
        }
}

class DuplicateException extends Exception {

}

// Použití
$registration = new SimpleRegistration(new CryptedPassword, new DatabaseRegistration(new PDODatabase));
try {
        $registration->register($_POST['username'], $_POST['email'], $_POST['password']);
        echo 'Jsi úspěšně zaregistrován';
} catch(UnexpectedValueException $ex) {
        echo $ex->getMessage();
} catch(DuplicateException $ex) {
        echo $ex->getMessage();
}
Editováno 3.7.2015 21:38
Nahoru Odpovědět
3.7.2015 21:35
Kód a data patří k sobě.
Avatar
Dominik Gavrecký:3.7.2015 22:13

Ďakujem vám všetkým ... A pavol to nie je môj kód je to ukážka s DZJKPW.

Nahoru Odpovědět
3.7.2015 22:13
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Odpovídá na Dominik Klapuch
Dominik Gavrecký:3.7.2015 22:43

Mohol by si mi prosím ťa vysvetliť tu časť kódu kde používaš Cryptable ... Nerozumiem čo tým Cryptable robíš alebo čo to vlastne je

Nahoru Odpovědět
3.7.2015 22:43
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Odpovídá na Dominik Gavrecký
Dominik Klapuch:3.7.2015 22:57

Je to objekt, který se stará o hashování hesla. Kombinuje password_hash s openssl. Vrací pouze hashovaný string hesla.

Nahoru Odpovědět
3.7.2015 22:57
Kód a data patří k sobě.
Avatar

Člen
Avatar
:3.7.2015 23:03

Jen rada - používej PDO, ne mysql_query. To už je označeno jako deprecated a v PHP 7 už je i vyhozeno.

 
Nahoru Odpovědět
3.7.2015 23:03
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 10 zpráv z 10.