Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Zagnieżdżanie obiektów
Forum PHP.pl > Forum > Przedszkole
Misiur66
Witajcie smile.gif

Zacząłem od dziś robić projekty za pomocą smarty i OOP w PHP. No i wszystko pięknie, zrobiłem sobie klasę służącą do komunikacji z bazą mysql, i przeszedłem do zrobienia obsługi formularza (rzecz jasna obiektowo). Jedyny szkopuł tkwi w tym że nie da się zagnieżdżać obiektów. Znaczy, nie tak jak sobie wyobrażałem.

Kod
include('db.php');
class registration
{
    private $nick;
    private $pass;
    private $repass;
    private $mail;
    private $ip;
    public $errors = array();
    private $db = new db;
}


To oczywiście nie zadziałało. Pytanie - jak zrobić żeby zadziałało?
Googlałem pół dnia po polskich i angielskich stronach, ale zazwyczaj podawali kto robi błąd w myśleniu. Może i Wy mi tak pomożecie - nie wiem smile.gif
A więc proszę o pomoc.
#luq
Dzieje się tak dlatego, że takie przypisanie należy zrobić w konstruktorze.

  1. class A
  2. {
  3.  
  4. }
  5.  
  6. class B
  7. {
  8. private $a = null;
  9.  
  10. public function __construct(){
  11. $this->a = new A();
  12. }
  13. }
  14.  
  15. $oB = new B();


Takie małe uwagi:
- ja bym polecał stosować zamiast include -> require_once
- jest konwencja, że nazwy klas piszemy z dużej literki, a dobrze się trzymać takich reguł.
- proponuje pisać zawsze "()" przy tworzeniu obiektu, nawet jeśli nie wrzucamy nic do konstruktora
- wg. mnie w konstruktorze klasy db powinieneś dawać dane dotyczące połączenia (host, user, pass), no chyba, żeby zrobić tak, że jak się nie podaje to defaultowo z jakiegoś configa leci winksmiley.jpg
Misiur66
Przydatne porady. I jeszcze jest chyba konwencja że te wszystkie zmienne klasy (jak to sie nazywało... metody?) public $cos, dajemy pomiędzy $ a nazwą underscore'a?

No ale mniejsza. Teraz mam kolejny problem. To będzie wielki projekt - 3 językowy. Jak już wspomniałem wcześniej korzystam ze smarty. I przez to nie widzę błędów (chyba).

Klasa DB jest na 100% poprawna

Kod klasy Registration

Kod
<?php
require_once('db.php');
class Registration
{
    private $nick;
    private $pass;
    private $repass;
    private $mail;
    private $ip;
    public $errors = 0;
    private $db = null;
    
    public function __construct()
    {
        $this->db = new Db();
    }
    
    public function check($login, $haslo, $rehaslo, $email, $ip)
    {
        $erra = array();
        $err = 0;
        
        $this->nick = filter_var($login, FILTER_SANITIZE_STRING);
        $this->pass = filter_var($haslo, FILTER_SANITIZE_STRING);
        $this->repass = filter_var($rehaslo, FILTER_SANITIZE_STRING);
        $this->mail = filter_var($email, FILTER_SANITIZE_MAIL);
        $this->ip = $ip;
        
        if(strlen($this->login) < 5)
        {
            $err++;
            $erra[] = $lang["login_short"]."Llen";
        }
        if(strlen($this->pass) < 5)
        {
            $err++;
            $erra[] = $lang["pass_short"]."pass len";
        }
        if($db->rows("SELECT * FROM users WHERE nick = '$this->login'") > 0)
        {
            $err++;
            $erra[] = $lang["login_occupied"];
        }
        if($this->pass != $this->repass)
        {
            $err++;
            $erra[] = $lang["pass_diffrent"]."Yo";
        }
        if(!filter_var($this->mail, FILTER_VALIDATE_EMAIL))
        {
            $err++;
            $erra[] = $lang["mail_wrong"]."Mail";
        }
        else
        {
            if($db->rows("SELECT * FROM users WHERE mail = '$this->mail'") > 0)
            {
                $err++;
                $erra[] = $lang["mail_used"];
            }
        }
        if(!filter_var($this->ip, FILTER_VALIDATE_IP))
        {
            $err++;
            $erra[] = $lang["ip_wrong"]."IP";
        }
        else
        {
            if($db->rows("SELECT * FROM users WHERE ip = '$this->ip'") > 0)
            {
                $err++;
                $erra[] = $lang["ip_used"];
            }
        }
        if($err == 0)
        {
            return true;
        }
        else
        {
            $estr = "";
            for($i=0; $i<$err; $i++)
            {
                $estr .= $erra[$i]."<br />";
            }
            $this->errors = $estr;
            return $this->errors;
        }
    }
    
}

?>


I sposób jej wywołania:

Kod
if(isset($_POST['reg_s']))
    {
        $reg = new Registration();
        $ip = $_SERVER['REMOTE_ADDR'];
        $errors = $reg->check($_POST['reg_n'], $_POST['reg_p'], $_POST['reg_rep'], $_POST['reg_m'], $ip);
        $form_we = $errors.$form;
        $smarty -> assign('reg_cont', $form_we);
    }


W klasie widać np $erra[] = $lang["coś"]."coś". Teraz w ogóle nic nie działa, nie wyświetla się. Tutaj jest to co robię. Język się wybiera i przypisuje się go do ciasteczka. Plik jest poprawnie zaincludowany... a jednak klasa później załadowana nie widzi tych zmiennych. Co zrobić?
#luq
Masz to całkowicie źle zaprojektowane. Postaram Ci się wyjaśnić jak to powinno być napisane, potem może ktoś mądrzejszy ode mnie się wypowie.

Jak dla mnie, to powinieneś wrzucać obiekt Db do obiektu Registration. Można to zrobić oczywiście statycznie dla całej klasy.
  1. Registration::setDb( new Db() )
  2. $foo = new Registration();
  3. // ew.
  4. // $foo = new Registration( new Db() );


Klasa Registration nie powinna filtrować danych! Od tego powinieneś mieć inną klasę (Valid) której wrzucasz tablice z wartościami ($_POST) następnie ustawiasz parametrami na podstawie których ma walidować, coś typu:
  1. $data = array(
  2. 'name' => 'email',
  3. 'type' => 'email'
  4. ),
  5. 'name' => 'login',
  6. 'type' => 'string',
  7. 'min-len' => 3
  8. )
  9. );
  10.  
  11. // powiedzmy ze mamy w $_POST
  12. // ['email'] => 'asdsadsa'
  13. // ['login'] => 'blabla'
  14.  
  15. $valid = new Valid( $_POST, $data );
  16. if( $valid->start() ){ // sprawdzamy czy dane w $_POST są poprawne względem $data
  17. // Odpalamy Registration
  18. }
  19. else{
  20. // rzucamy tablice ze stałymi (define) błędów, które popełniono oraz pola w których to uczyniono do Smarty...
  21. $smarty -> assign( 'valid_err', $valid->getErrors() );
  22. }


Registration powinien zaraz wywalać wyjątek jeśli jest user o danym emailu lub loginie.
Języków używasz po stronie szablonów nie w kodzie PHP, tym bardziej w klasach!

PS:
Cytat
I jeszcze jest chyba konwencja że te wszystkie zmienne klasy (jak to sie nazywało... metody?) public $cos, dajemy pomiędzy $ a nazwą underscore'a?

Metody to są "funkcje klasy". "Zmienne" są nazywane właściwościami (ew. polami). To o czym mówisz stosuje się dla elementów o dostępie prywatnym.
  1. class A
  2. {
  3. private $_foo;
  4. public $bar;
  5.  
  6. private function _setFoo(){
  7. //
  8. }
  9. public function getBarr(){
  10. //
  11. }
  12. }


@edit
Aha, wg. mnie powinieneś mieć klasę Auth(), która odpowiada za rejestracje, logowanie itp. a nie tylko odpowiadającą za rejestracje. Poza tym wywal nazwę tabelek i pól z bazy do jakiegoś configa.
Misiur66
Nie wiem czy można kilka razy wystawiać pomógł, ale Ty mi pomogłeś winksmiley.jpg
To mój 1 dzień i 1 spotkanie z obiektami, więc i tak nie jest tragicznie haha.gif Teraz nie mam błędów (dałem display errors na E_ALL) i wszystko działa. Ale i tak przeprojektuje to jak mówisz.
Tylko nadal nie rozumiem "wrzuć do configa". Mam plik config.php, który ładuje bazę danych, pliki językowe i smarty. Ale nie wiem o co ci konkretnie chodzi.
#luq
Cytat
Tylko nadal nie rozumiem "wrzuć do configa". Mam plik config.php, który ładuje bazę danych, pliki językowe i smarty. Ale nie wiem o co ci konkretnie chodzi.


Configi nie powinny nic ładować. W configach powinieneś mieć definiowane stałe i tylko tyle. Ja mam autorski silnik (taki mały framework) i u mnie klasa Auth() jest modułem i do niego mam config w którym znajdują się takie rzeczy jak:
- opcje solenia haseł
- nazwa tabelki gdzie są upchani userzy
- nazwy kolumn (id, login, hasło, ranga)

i tyle. Dzięki temu mam możliwość zmiany tylko tych stałych i struktury bazy bez edytowania jakiegokolwiek pliku z kodem.

Ogólnie programowanie OOP to całkiem inne podejście do kodu. Ja polecam Ci książkę "PHP5 Zaawansowane Programowania" smile.gif

Cytat
Nie wiem czy można kilka razy wystawiać pomógł, ale Ty mi pomogłeś

Nigdy nie robiłem, i nie zamierzam robić czegoś dla plusów. Oczywiście miło go dostać ale nie o to tu chodzi winksmiley.jpg
Misiur66
Ok, wielkie dzięki za pomoc. 80 zł chyba można poświęcić biggrin.gif Ten projekt jest dosyć wielki (silnik menedżera piłkarskiego i jeszcze jednej podobnej rzeczy) i wcześniej robiłem to samo ale bez obiektów. Dużo będzie takich rzeczy, więc w sumie dobrze będzie mieć configa (gracze, drużyny, mecze, wiadomości).

Jeszcze raz dzięki.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.