Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [OOP] Używanie atrybutów jednej klasy w drugiej
Still
post 12.10.2010, 21:45:19
Post #1





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 12.10.2010

Ostrzeżenie: (10%)
X----


Witam,
Programuję od jakiegoś roku, ale dopiero od około miesiąca zająłem się OOP i PDO. Mam problem z używaniem atrybutów jednej klasy w drugiej. Konkretniej:

klasa users, ma konstruktor iż pobiera z bazy danych na podstawie cookies (jeżeli są) informacje o użytkowniku takie jak login, adres avatara itp i zapisuje je do swoich atrybutów.

druga klasa wyświetlająca stronę, nazywa się strona. jest w niej funkcja jak wyświetl_początek() i wyświetla ona kod html z logiem, menu. jest też wyswietl_koniec() gdzie rysowana jest stopka.

potrzeba mi użyć w wyświetl_początek() tych pobranych z bazy danych informacji o użytkowniku. jak to rozwiązać?

Fragmenty kodu o jakie się rozchodzi:
  1. class Users
  2. {
  3. private $zalogowany;
  4.  
  5. public function __construct()
  6. {
  7. $this->sprawdz_zalogowanie();
  8. }
  9.  
  10.  
  11. public function sprawdz_zalogowanie()
  12. {
  13. try
  14. {
  15. if( isset($_COOKIE['userid']) && isset($_COOKIE['pass']) )
  16. {
  17. // przygotowanie szkieletu zapytania
  18. $stmt = MySQLDriver::$pdo -> prepare('SELECT * FROM `users` WHERE `id` = :id AND `haslo` = :pass LIMIT 1');
  19.  
  20. $stmt -> bindValue(':id', intval($_COOKIE['userid']), PDO::PARAM_INT);
  21. $stmt -> bindValue(':pass', $_COOKIE['pass'], PDO::PARAM_STR);
  22.  
  23. // wykonanie zapytania
  24. $stmt -> execute();
  25.  
  26. // jeżeli zwróci kogoś z takim id i hasłem
  27. if ($row = $stmt -> fetch(PDO::FETCH_ASSOC))
  28. {
  29. foreach ($row as $k => $v)
  30. {
  31. $this->$k = $v;
  32. }
  33. $stmt -> closeCursor();
  34.  
  35. $this->zalogowany = TRUE;
  36. }
  37. else
  38. {
  39. $this->zalogowany = FALSE;
  40. }
  41. }
  42. else {
  43. $this->zalogowany = FALSE;
  44. }
  45. }
  46. catch(PDOException $e)
  47. {
  48. echo 'Wystapil blad biblioteki PDO: ' . $e->getMessage();
  49. }
  50. }
  51. }


  1. class Strona
  2. {
  3. public $tytul_strony;
  4. public $keywords;
  5.  
  6. public function __construct()
  7. {
  8. MySQLDriver::connect();
  9. }
  10.  
  11. public function wyswietl_poczatek($user)
  12. {
  13. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n".'<html xmlns="http://www.w3.org/1999/xhtml">'."\n";
  14. $this->wyswietl_head();
  15.  
  16. echo "<body>\n";
  17. ?>
  18. <div id="top">
  19. <a href="index.php"><img src="images/logo.png" width="445" height="160" alt="" /></a>
  20. <div id="logowanie">
  21. <img src="images/avatars/0.gif" hspace="10" style="float:left" alt="" />
  22. <span style="font-size:10px">Jesteś zalogowany jako:</span><br />
  23. <b><?php echo 'Gość'; ?></b>
  24. <span style="font-size:10px"><br /> Przejdź do profilu <br /> Wyloguj</span>
  25. </div>
  26. </div>
  27. <?php
  28. $this->wyswietl_topmenu();
  29. ?>
  30. <!-- treść główna serwisu -->
  31. <table width="1060" border="1" cellpadding="0" cellspacing="0" align="center">
  32. <tr>
  33. <td width="500" rowspan="2" valign="top" align="left">
  34. <!-- lewa główna kolumna -->
  35.  
  36. <!-- wyszukiwarka -->
  37. <?php $this->wyswietl_wyszukiwarka(); ?>
  38. <!-- / wyszukiwarka -->
  39. <?php
  40. }
  41. }


  1. class MySQLDriver
  2. {
  3. public static $pdo;
  4.  
  5. // Nawiązanie połączenia z bazą danych.
  6. public static function connect()
  7. {
  8. self::$pdo = new PDO('mysql:host=localhost;dbname=baza', 'root', '', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
  9. self::$pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  10. }
  11. }


index.php
  1. // załadowanie class
  2. include_once('../classes/mysqldriver.php');
  3. include_once('../classes/users.php');
  4. include_once('../classes/strona.php');
  5.  
  6. // tworzenie obiektów
  7. $strona = new Strona();
  8. $user = new Users();
  9.  
  10. $strona->wyswietl_poczatek();
  11.  
  12. //tutaj tresc danego dzialu
  13.  
  14. $strona->wyswietl_koniec();


Dziękuję za jakąkolwiek pomoc. Pozdrawiam.

PS. Ogólnie to dobrze zrobiłem tą obsługę bazy danych? W tym wypadku wykorzystałem static, ale nie chcę tego nadużywać.

Ten post edytował Still 12.10.2010, 21:49:56
Go to the top of the page
+Quote Post
Pilsener
post 12.10.2010, 22:33:15
Post #2





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


W przypadku takiego kodu ciężko coś doradzić, bo nie wiadomo nawet od czego zacząć winksmiley.jpg Jak masz tak pisać obiektowo, to lepiej już rób to strukturalnie - dobry kod strukturalny jest o niebo lepszy od kiepskiego obiektowego.

Znasz jakieś wzorce projektowe? U Ciebie wszystko w jednym, baza, model danych, jakiś pseudo-widok czy obsługa szablonów, dlatego moje rady są dwie:

1. Zapoznaj się z wzorcami
2. Popatrz, jak robią to popularne frameworki
3. Liźnij trochę teorii (choćby jeśli chodzi o nazewnictwo)
Go to the top of the page
+Quote Post
Crozin
post 13.10.2010, 09:06:53
Post #3





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Na początek: nie patrz na tym etapie na żadne frameworki. Wzorce również możesz sobie darować bo one nie uczą niczego - pokazują tylko jak rozwiązać pewne popularne problemy: po co Ci rozwiązania problemów, których jeszcze nie masz? smile.gif

1. Tak długo jak to tylko możliwe nie uzależniaj obiektu od danych z zewnątrz (chodzi tu o użycie ciasteczek bezpośrednio w klasie czy konstrukcji typu MySQLDriver::$pdo). To tylko problemy i ogromna utrata elastyczności, w zamian dająca Ci 10 linijek zaoszczędzonego kodu - nie warte. Wymagane zależności (inne obiekty, wymagane do prawidłowego funkcjonowania obiektu: tutaj $pdo) przekaż w konstruktorze, a wymagane dane do działania jakiś metod jako ich argumenty:
  1. class User {
  2. protected $pdo;
  3.  
  4. public function __construct(PDO $pdo) {
  5. $this->pdo = $pdo;
  6. }
  7.  
  8. public function signin($username, $password) {
  9. // ...
  10. $this->pdo->prepare(....);
  11. // ...
  12. }
  1. # index.php
  2.  
  3. $pdo = new PDO(...);
  4. $pdo->setAttribute(...);
  5.  
  6. $user = new User($pdo);
  7.  
  8. if (isset($_COOKIE...)) {
  9. $user->signin($_COOKIE...);
  10. }

2. Unikaj nie potrzebnych klas. Tutaj MySQLDriver nie robi kompletnie nic pożytecznego - po co ona? Utrudnia tylko korzystanie z kodu.
3. Dbaj o obsługę błędów. Takie:
  1. catch(PDOException $e)
  2. {
  3. echo 'Wystapil blad biblioteki PDO: ' . $e->getMessage();
  4. }
Jest nic nie warte. Jedynie utrudnia korzystanie z aplikacji. Takim blokiem catch, który wywala po prostu treść wyjątku można objąć cały skrypt (bo w końcu trzeba zrobić coś z wyjątkami, z którymi nie potrafimy sobie inaczej poradzić).
  1. try {
  2. // cały skrypt strony
  3. } catch (Exception $e) {
  4. var_dump($e); // gdy strona jest już gotowa do działania na prawdziwym serwerze zamieniamy to na:
  5. // zapisanie błędu do logów
  6. // die('Coś poszło nie tak. Spróbuj ponownie za chwilę');
  7. }
Jeżeli jakiegoś wyjątku nie jesteśmy w stanie obsłużyć - nie robimy tego. Być może jakiś "wyższy" (w hierarchii) blok try {} catch {} będzie w stanie to zrobić. Jeżeli nie to może kolejny. Jeżeli nadal nie, to dotrze to do tego obejmującego całą stronę i wywali się na ekran.
4. Daruj sobie póki co jakiekolwiek klasy do wyświetlania strony. Można takie tworzyć, ale muszą być one naprawdę potężne (pod względem skomplikowania). Używaj póki co typowych szablonów.
5. Popracuj nad nazewnictwem.
Go to the top of the page
+Quote Post
Still
post 13.10.2010, 10:15:59
Post #4





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 12.10.2010

Ostrzeżenie: (10%)
X----


Cytat(Pilsener @ 12.10.2010, 23:33:15 ) *
W przypadku takiego kodu ciężko coś doradzić, bo nie wiadomo nawet od czego zacząć winksmiley.jpg Jak masz tak pisać obiektowo, to lepiej już rób to strukturalnie - dobry kod strukturalny jest o niebo lepszy od kiepskiego obiektowego.

Znasz jakieś wzorce projektowe? U Ciebie wszystko w jednym, baza, model danych, jakiś pseudo-widok czy obsługa szablonów, dlatego moje rady są dwie:

1. Zapoznaj się z wzorcami
2. Popatrz, jak robią to popularne frameworki
3. Liźnij trochę teorii (choćby jeśli chodzi o nazewnictwo)

Zgadzam się z tym, dlatego przychodzę tu na forum o radę, bo jednak wolę się rozwijać i opanować te pisanie obiektowo niż cały czas siedzieć w strukturalnym. smile.gif
Przeczytałem dzisiaj o wzorach projektowych w książce "Programowanie obiektowe w PHP5" Hasina Hayder, ale nic użytecznego z tego nie wyciągnąłem...


Cytat(Crozin @ 13.10.2010, 10:06:53 ) *
Na początek: nie patrz na tym etapie na żadne frameworki. Wzorce również możesz sobie darować bo one nie uczą niczego - pokazują tylko jak rozwiązać pewne popularne problemy: po co Ci rozwiązania problemów, których jeszcze nie masz? smile.gif

1. Tak długo jak to tylko możliwe nie uzależniaj obiektu od danych z zewnątrz (chodzi tu o użycie ciasteczek bezpośrednio w klasie czy konstrukcji typu MySQLDriver::$pdo). To tylko problemy i ogromna utrata elastyczności, w zamian dająca Ci 10 linijek zaoszczędzonego kodu - nie warte. Wymagane zależności (inne obiekty, wymagane do prawidłowego funkcjonowania obiektu: tutaj $pdo) przekaż w konstruktorze, a wymagane dane do działania jakiś metod jako ich argumenty:

Dobra rady, dzięki smile.gif

Cytat(Crozin @ 13.10.2010, 10:06:53 ) *
2. Unikaj nie potrzebnych klas. Tutaj MySQLDriver nie robi kompletnie nic pożytecznego - po co ona? Utrudnia tylko korzystanie z kodu.

W takim razie na każdej podstronie na początku dawać includem jakiś plik, który będzie mi wykonywał "$pdo = new PDO(...); $pdo->setAttribute(...);" ?

Cytat(Crozin @ 13.10.2010, 10:06:53 ) *
4. Daruj sobie póki co jakiekolwiek klasy do wyświetlania strony. Można takie tworzyć, ale muszą być one naprawdę potężne (pod względem skomplikowania). Używaj póki co typowych szablonów.

Mógłbyś rozwinąć swoją myśl "typowych szablonów" ? Stworzyłem już layout strony, pociąłem go i wklepałem w xHTML i CSS. Skoro nie tak mam go zaimplementować, to jak? smile.gif

Jeżeli chodzi o funkcję sprawdz_zalogowanie(), to zostaje ona wywołana za każdym razem ładowania strony. Chodzi o to, aby sprawdzić czy cookies jakie użytkownik ma w przeglądarce, służą zalogowaniu do serwisu. Zakładamy że wypełnił on już formularz logowania i ciasteczka już sobie tam leżą. Uważam, że takie sprawdzenie trzeba wykonać za każdym razem ładowania strony. Chyba w tym wypadku nie przeszkadza to iż sprawdzenie czy istnieją leży po stronie metody za to odpowiedzialnej? Bo jeżeli ich nie ma to po prostu wrzuca false i tyle smile.gif Pozdrawiam.

Ten post edytował Still 13.10.2010, 10:26:07
Go to the top of the page
+Quote Post
Crozin
post 13.10.2010, 13:27:31
Post #5





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Cytat
Mógłbyś rozwinąć swoją myśl "typowych szablonów" ? Stworzyłem już layout strony, pociąłem go i wklepałem w xHTML i CSS. Skoro nie tak mam go zaimplementować, to jak?
Ot, zwykły plik z szablonem:
  1. <body>
  2. <h1>Witaj <?php echo $username ?></h1>
  3. </body>
I coś co pozwoli na chociażby najprostsze operacje na tym:
  1. function abc($template, array $vars = array()) {
  2. extract($vars);
  3. include($template);
  4. }


Cytat
W takim razie na każdej podstronie na początku dawać includem jakiś plik, który będzie mi wykonywał "$pdo = new PDO(...); $pdo->setAttribute(...);" ?
Możesz to zrobić tak, możesz też mieć jeden plik (googleaj za: Front Controller) do którego będzie kierowany cały ruch strony, a on już sobie wczyta podpowiednie podstrony.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 13.06.2025 - 09:02