Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Początki z obiektowym PHP
marcinpruciak
post
Post #1





Grupa: Zarejestrowani
Postów: 161
Pomógł: 9
Dołączył: 14.07.2008

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


Dopiero zacząłem przygodę z obiektowym PHP. Uczyłem się z książki 'Zaawansowane tworzenie stron www PHP5 Szybki start'.

Udało mi się wykombinować taki kod:

http://www.wklej.com.pl/show.php?what=20080812201428

Ma to służyć jako miniCMS, to są klasy do zarządzania podstronami.

Chciałbym się zapytać czy to jest wogóle obiektowo, bo mi się wydaje że to są zwykłe funkcje pogrupowane w klasy. 

Nie wiem czy rozumiem ideę obiektowego programowania.
Go to the top of the page
+Quote Post
wlamywacz
post
Post #2





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

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


Niestety jest to tylko kod strukturalny zamknięty w klasach i funkcjach.
Go to the top of the page
+Quote Post
dyniaq
post
Post #3





Grupa: Zarejestrowani
Postów: 34
Pomógł: 4
Dołączył: 31.07.2006
Skąd: Oława

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


No trochę lipa. Utwórz np klasę podstrona i w niej metody, źle to IMO podzieliłeś. I stwórz klasę baza a nie polacz
Go to the top of the page
+Quote Post
marcinpruciak
post
Post #4





Grupa: Zarejestrowani
Postów: 161
Pomógł: 9
Dołączył: 14.07.2008

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


Zmieniłem to w jedną klasę podstrony. 

Nie widzę innej możliwości rozwiązania tego. Według mnie jest wszystko dobrze. Jedna klasa pobiera dane, druga je wyświetla. O to chyba w tym chodzi, nie?
Go to the top of the page
+Quote Post
ayeo
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 1 202
Pomógł: 117
Dołączył: 13.04.2007
Skąd: 127.0.0.1

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


Tak jak ktoś wyżej napisał, myślisz funkcjonalnie. Obiekt to nie zbiór funkcji. Obiekt reprezentuje jakąś konkretną "rzecz".

Pozdrawiam!
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #6





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Nie, niestety nie chodzi o to. Przynajmniej nie wprost. Obiekty są po to, aby reprezentowały jakieś rzeczy. W przypadku strony www, może to być obiekt Page (zawsze używaj nazw angielskich - to bardzo ważne), który posiada właściwości i operacje. Nie jest jednak reprezentacją dokumentu HTML, tylko danych, które ta stronę tworzą (wpisy w bazie danych lub w pliku tekstowym). Poczytaj więcej, w bardziej specjalistycznych książkach (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Pozdrawiam.
Go to the top of the page
+Quote Post
qBK
post
Post #7





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 9.01.2007
Skąd: Wrocław

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


W sumie nie wiem czy rozpoczęcie nauki programowania obiektowego od PHP to najlepsze rozwiązanie. Ja OOP nauczyłem się na C++ i Tobie też to polecam, chociaż na początku może być trudno, ale nie ma nic za darmo (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Poza tym C++ to kanon, który co prawda bywa czasem trochę upierdliwy, bo wszystko musi się zgadzać i jest mniej elastyczne niż nowsze języki, ale to uczy porządnego programowania.
Bazując na swoim przykładzie, polecam naukę podstaw C++, potem wskaźników i wtedy programowanie obiektowe w C++.

Jeszcze odnośnie Twojego kodu, to zrobiłeś zbiór funkcji, jak poprzednicy pisali; klasy charakteryzują się tym, że obiekty z nich utworzone posiadają 1) zmienne i 2) metody (funkcje) i jedno i drugie jest w równym stopniu ważne, więc tworzenie klas tylko ze zmiennymi albo tylko z funkcjami niewiele nam daje, dopiero połączenie obu pozwala wykorzystać masę funkcjonalności.

Tworzysz klasę i później możesz stworzyć wiele obiektów, które są niezależne od siebie, mają inne dane (zmienne), ale korzystają z tych samych metod.

Trywialny przykład:
  1. <?php
  2. class Prostokat
  3. {
  4. var $szerokosc;
  5. var $wysokosc;
  6.  
  7. public function pole()
  8. {
  9. return $this->szerokosc * $this->wysokosc;
  10. }
  11. }
  12.  
  13. $p1 = new Prostokat;
  14. $p1->szerokosc = 20;
  15. $p1->wysokosc = 10;
  16. echo $p1->pole(); //200
  17.  
  18. $p2 = new Prostokat;
  19. $p2->szerokosc = 65;
  20. $p2->wysokosc = 2;
  21. echo $p2->pole(); // 130
  22. ?>


Coś bardziej zbliżonego do Twojego kodu - obiekt 'Tabela':
  1. <?php
  2. class Tabela
  3. {
  4. var $dane;
  5.  
  6. public function __construct()
  7. {
  8. $this->dane = array();
  9. }
  10. public function addRow($text)
  11. {
  12. $this->dane[] = $text;
  13. }
  14. public function display()
  15. {
  16. echo '<table>';
  17. foreach($this->dane as $row)
  18. {
  19. echo '<tr><td>'.$row.'</td></tr>';
  20. }
  21. echo '</table>';
  22. }
  23. }
  24.  
  25. $produkty = new Tabela;
  26. $produkty->addRow('margaryna');
  27. $produkty->addRow('masło');
  28. $produkty->addRow('chleb');
  29. $produkty->display();
  30. ?>

Oczywiście to też przykład trywialny, jedynie obudowanie zwykłego arraya, ale niewiele zmieniając można już poprawić trochę jakość zwyczajnej tablicy, np. walidować dane wejściowe, czyli w funkcji addRow sprawdzać czy $text jest taki jak nam odpowiada, czy nie jest za długi etc. etc.
Go to the top of the page
+Quote Post
Crozin
post
Post #8





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

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


@qBK w PHP5 nie ma var, jest private, protected, public (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
marcinpruciak
post
Post #9





Grupa: Zarejestrowani
Postów: 161
Pomógł: 9
Dołączył: 14.07.2008

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


Pomęczyłem się pół dnia i trochę już łapię. Zrobiłem to tak aby jak najwięcej kodu móc wykorzystać w przyszłości.

Klasa:

http://www.wklej.com.pl/show.php?what=20080813115015

Wykorzystanie klasy:

http://www.wklej.com.pl/show.php?what=20080813115116

Wg tego zrobie potem zarządzanie newsami, menu itd, wszystko tą samą klasą.

Chciałem jeszcze przenieść zapytanie do klasy jakoś, ale nie wiem zabardzo jak i czy warto.
Go to the top of the page
+Quote Post
Shili
post
Post #10





Grupa: Zarejestrowani
Postów: 1 085
Pomógł: 231
Dołączył: 12.05.2008

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


Jak już się uczysz, to nabieraj od podstaw sensownych przyzwyczajeń - rozdzielaj kod php od html w tym przypadku, w bardziej ogólnym zainteresuj się wzorcem MVC.

Zarządzanie wszystkim tą samą klasą?
Co ma wspólnego menu z newsami? Na zdrowy "chłopski" rozum są to dwa różne obiekty, np do jednego są komentarze, do drugiego ni hu hu, jedno i drugie jest inne. Zapoznaj się z dziedziczeniem, interfejsami (możesz sobie zrobić ogólną klasę (lub interface), faktycznie, ale potem ją implementować, czy rozszerzać do swoich potrzeb nie zawierając w nich zupełnie niepotrzebnych metod czy własności).

Ten post edytował Shili 13.08.2008, 15:50:54
Go to the top of the page
+Quote Post
qBK
post
Post #11





Grupa: Zarejestrowani
Postów: 17
Pomógł: 0
Dołączył: 9.01.2007
Skąd: Wrocław

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


Cytat(Crozin @ 13.08.2008, 14:40:46 ) *
@qBK w PHP5 nie ma var, jest private, protected, public (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Hah, coś mi od początku to var nie pasowało do PHP-a, ale wszystko działało więc się nie zorientowałem (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Przeglądałem pewnie jakiś stary kod i mi się zakorzeniło w głowie. A modyfikatorów nie używałem bo kod private var $x krzaczył mi się i nie wiedziałem o co chodzi (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) Dzięki za zwrócenie uwagi.

edit
@marcinpruciak:
Jeśli zrobiłeś już klasę Baza, to dodaj na przykład w niej metodę 'query' albo 'execute'

  1. <?php
  2. class Baza
  3. {
  4. ...
  5. public function query($q)
  6. {
  7. return mysqli_query($this->polacz, $q);
  8. }
  9. }
  10. ?>


i zamiast wywoływać
$r=mysqli_query($baza->polacz, $q);
możesz pisać
$r=$Baza->query($q)

Jest trochę krócej i później powiedzmy przechodząc z MySQL na PostgreSQL nie będziesz musiał każdego mysqli_query zamieniać na pg_query.

Ten post edytował qBK 13.08.2008, 19:57:45
Go to the top of the page
+Quote Post
Crozin
post
Post #12





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

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


Nie private var $abc, a private $abc (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
marcinpruciak
post
Post #13





Grupa: Zarejestrowani
Postów: 161
Pomógł: 9
Dołączył: 14.07.2008

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


Trochę pomyślałem, pokombinowałem i mam. Nie jest to MVC, bo gubię się przy oddzielnych trzech klasach, ale jest oddzielony widok od logiki.

  1. <?php
  2. class Publikuj
  3. {
  4. public $pub;
  5. public $new_pub;
  6. public $id;
  7.  
  8. public function pobierz_id_pub($id, $pub)
  9. {
  10.     $this->id = $id;
  11.     $this->pub = $pub;
  12. }
  13.  
  14. public function pokaz_pub()
  15. {
  16.     if($this->pub==Y) {
  17.         echo 'id.'&pub=N&#092;">TAK';
  18.     } else {
  19.         echo 'id.'&pub=Y&#092;">NIE';
  20.     }
  21. }
  22.  
  23. public function oblicz()
  24. {
  25.     if($_GET['pub']==N) {
  26.         $this->new_pub='N';
  27.     } else {
  28.         $this->new_pub='Y';
  29.     }
  30. }
  31.  
  32. public function zastosuj()
  33. {
  34.     $baza=new Baza;
  35.     if($_GET['pub']) {
  36.         $q=&#092;"UPDATE pages SET publikuj='$this->new_pub' WHERE id=\".$_GET['id'].\"\";
  37.         $r=$baza->query($q);
  38.     }
  39. }
  40.  
  41. public function przekierowanie()
  42. {
  43.         header(&#092;"Locatio: ./pages.php\");
  44. }
  45. }
  46. ?>


I użycie tej klasy w innej klasie: (muszę to jeszcze ulepszyć)

  1. <?php
  2. class Page
  3. {
  4. public $tablica;
  5. public $r;
  6.  
  7. public function query()
  8. {
  9.     $baza= new Baza;
  10.     $q=&#092;"SELECT * FROM `pages` ORDER BY `id`\";
  11.     $this->r = $baza->query($q);
  12. }
  13.  
  14. public function tworz_tabele()
  15. {    
  16.     $pub= new Publikuj;
  17.  
  18.           while($this->tablica = mysqli_fetch_array($this->r)) {
  19.             echo '
  20.                     '.$this->tablica['id'].'
  21.                     Zaznacz
  22.                     '; $pub->pobierz_id_pub($this->tablica['id'], $this->tablica['publikuj']); $pub->pokaz_pub(); $pub->oblicz(); $pub->zastosuj();
  23.                 echo '
  24.                     '.$this->tablica['tytul'].'
  25.                     Edytuj
  26.                     Usun
  27.                  ';
  28.         }
  29.         echo '';
  30.         $pub->przekierowanie();
  31. }
  32. }
  33. ?>




I co o tym myślicie? Nieźle jak na pierwszy kontakt z obiektowością?
Go to the top of the page
+Quote Post
Kicok
post
Post #14





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

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


Cytat
Nieźle jak na pierwszy kontakt z obiektowością?

Źle. Powinieneś mieć logikę wywołującą widok, a nie widok wywołujący logikę.

Czyli najpierw myślisz co trzeba zrobić (np. na podstawie informacji z $_GET)
Potem wykonujesz te swoje działania ($pub->oblicz(), $pub->zastosuj(), $pub->pobierz_id_pub(), a wyniki zapisuj sobie na boku w jakichś zmiennych)
Na końcu, gdy już jesteś pewien co(i czy w ogóle) chcesz wyświetlić, to wstawiasz sobie te zmienne do HTML'a
Go to the top of the page
+Quote Post
f1xer
post
Post #15





Grupa: Zarejestrowani
Postów: 403
Pomógł: 68
Dołączył: 20.03.2008

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


Abstrahując od twojego problemu, jeżeli chodzi o rozdzielenie logiki to poczytaj o MVC sam niedawno się z tym męczyłem i wydawało mi się to wręcz bez sensowne ale później po przemyśleniu i napisaniu pierwszego skryptu MVC zrozumiałem o co biega tak z biegu podam prosty przykład
  1. <?php
  2. class model
  3. {
  4. public function show_news($name)
  5. {
  6. // metoda modelu pobiera dane ze źródła danych i zwraca je do kontrolera
  7. $news=file_get_contents("plik/".$name.".php");
  8. return $news;
  9. }
  10. }
  11. class view
  12. {
  13. public function show_news($news)
  14. {
  15. // metoda widoku formatuje dane pobrane z modelu i wyświetla w przeglądarce
  16. echo "To jest widok newsa:<br/>zawiera html<br/>";
  17. echo "<p>".$news."</p>"
  18. }
  19. }
  20. class kontroler
  21. {
  22. public function __construct()
  23. {
  24. $model = new model;
  25. $widok= new view;
  26. }
  27. public function doPage()
  28. {
  29. // szkielet kontrolera wywoluje odpowiedni widok z odpowiednimi danymi pobranymi z
     modelu, zarządza żądaniami użytkownika
  30. if (isset($_GET['id']))
  31. {
  32. $widok->show_news($model->show_news($_GET['id']));
  33. }
  34. else
  35. {
  36. $widok->show_news($model->show_news(0));
  37. }
  38. }
  39. $strona=new kontroler;
  40. ?>
  41. <html>
  42. <head>
  43. ......
  44. </head>
  45. <body>
  46. <p>......tutaj stala czesc strony ona zawsze pozostanie taka sama (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) </p>
  47. <div class="tresc">
  48. <?php
  49. $strona->doPage();
  50. ?>
  51. </div>
  52. </body>
  53. </html>


sens powyższego jest żaden, natomiast moim zdaniem dobrze obrazuje idee MVC. Zauważ że dzięki temu, jeżeli np. będziesz chciał dodać obsługę bazy mysql, to zostanie ci do zmiany tylko model, a jeżeli będziesz chciał dać możliwość obejrzenia newsa w pdf to wystarczy dopisać odpowiedni widok.

Ten post edytował f1xer 22.08.2008, 14:21:34
Go to the top of the page
+Quote Post
marcinpruciak
post
Post #16





Grupa: Zarejestrowani
Postów: 161
Pomógł: 9
Dołączył: 14.07.2008

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


Tylko jak poradzić sobie z pętlą? Wszystkie przykłady co widziałem nie miały takiej pętli. To jedyny sposób jaki znam. 

Bo ważniejsze zmienne nie pobieram z geta tylko z tablicy. I te wszystkie funckje też muszą być w pętli. 
Go to the top of the page
+Quote Post
f1xer
post
Post #17





Grupa: Zarejestrowani
Postów: 403
Pomógł: 68
Dołączył: 20.03.2008

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


jeżeli masz jusz dane w tablicy to tą tablicę przekazujesz do widoku a w widoku wyciągasz wszystkie elementy tablicy i dekorujesz html później wyrzucasz do przeglądarki. Generalnie to jest tak w uproszczeniu

Kontroler - przyjmuje zapytanie i podejmuje decyzje co zrobić, jeżeli potrzebne są jakieś dane ze źródła danych (plik,baza,SOAP etc.) to prosi Model o przygotowanie takich danych.
Model - pobiera dane ze źródła danych i zwraca kontrolerowi (w postaći np. tablicy)
Kontroler dostaje dane i wywołuje odpowiedni widok
Widok - dostaje "surowe" dane i przygotowywuje je do prezentacji (np. dostał tablicę to robi na niek foreach i dla każdego wiersza dodaje tagi html) po czym wyrzuca do przeglądarki.
odnośnie twojego mini CMS (też taki pisze (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) ) to nie potrzeba duzo roboty od frontu model ma np. 1 metode pokaz_strone($id) i wniej wczytujesz z bazy treść strony, widok też ma co najmniej jedną metodę pokaz($strona) dostaje treść strony od modelu i np. wyrzuca to pomiędzy tagami <p></p> a kontroler np. sprawdza czy w $_GET jest podane id jeżeli tak to wywołuje model z tym id a pozniej widok ze zwróconą przez model wartością, jeżeli id nie ma to wczytuje stronę domyślną.

Ten post edytował f1xer 22.08.2008, 17:32:14
Go to the top of the page
+Quote Post
marcinpruciak
post
Post #18





Grupa: Zarejestrowani
Postów: 161
Pomógł: 9
Dołączył: 14.07.2008

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


Zedytowałem to tak:

  1. <?php
  2. class Page
  3. {
  4.  public $tablica;
  5.  public $id;
  6.  public $tytul;
  7.  public $publikuj;
  8.  public $show;
  9.  public $r;
  10.  
  11.  public function query()
  12.  {
  13.   $baza= new Baza;
  14.   $q="SELECT * FROM `pages` ORDER BY `id`";
  15.   $this->r = $baza->query($q);
  16.  }
  17.  
  18.  public function tworz_tablice()
  19.  {
  20.   $this->tablica = mysqli_fetch_assoc($this->r);
  21.   return $this->tablica;
  22.  } 
  23.  
  24.  public function tworz_strone()
  25.  {  
  26.   $pub= new Publikuj;
  27.   $this->query();
  28.   $this->tworz_tablice();
  29.   $this->id = $this->tablica['id'];
  30.   $this->tytul = $this->tablica['tytul'];
  31.   $this->publikuj = $this->tablica['publikuj'];
  32.   $pub->pobierz_id_pub($this->id, $this->publikuj); 
  33.   $pub->oblicz(); 
  34.   $pub->zastosuj();
  35.   $pub->pokaz_pub();
  36.   $this->show = $pub->show;
  37.   $this->widok();
  38.   $pub->przekierowanie();
  39.  }
  40.  
  41.  public function widok()
  42.  { 
  43.   echo '<table border="1">
  44.   <tr>
  45.   <td width="5%">#</td>
  46.   <td width="5%">Zaznacz</td>
  47.   <td width="5%">Publikuj</td>
  48.   <td width="25%">Tytul</td>
  49.   <td width="15%">Edytuj</td>
  50.   <td width="15%">Usun</td>
  51.   </tr>'; 
  52.    
  53.   while($this->tworz_tablice()) {
  54.   echo '<tr>
  55.   <td width="5%">'.$this->id.'</td>
  56.   <td width="5%">Zaznacz</td>
  57.   <td width="5%">'.$this->show.'</td>
  58.   <td width="25%">'.$this->tytul.'</td>
  59.   <td width="15%"><a href="?id='.$this->id.'">Edytuj</a></td>
  60.   <td width="15%">Usun</td>
  61.   </tr>'; 
  62.   }
  63.   echo '</table>';
  64.  }
  65.  }
  66. ?>


Chyba o to chodzi?

Mam tylko jeden problem. Metoda tworząca tablicę z wyników z bazy dodaje do tablicy tylko pierwszy wiersz z bazy? Nigdzie nie widzę błędu? Co jest nie tak?

Ten post edytował marcinpruciak 22.08.2008, 23:48:20
Go to the top of the page
+Quote Post
kbsucha
post
Post #19





Grupa: Zarejestrowani
Postów: 113
Pomógł: 19
Dołączył: 2.08.2007

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


Zobacz w manualu opis funkcji mysql_fetch_assoc(), zwróć uwagę na pętle while w przykładzie.

Pozdr
Go to the top of the page
+Quote Post
marcinpruciak
post
Post #20





Grupa: Zarejestrowani
Postów: 161
Pomógł: 9
Dołączył: 14.07.2008

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


Udało się. Dzięki za sugestię.




Dalej ćwiczę obiektowość, stworzyłem teraz klasę dodawania i edycji stron:
http://wklej.com.pl/show.php?what=20080828234035

Jest to zgodne z obiektowością? Strona działa i ma się dobrze tutaj można zobaczyć jak:

http://195.205.202.32:6893/minicms/index.php?page=pages

Proszę o odpowiedź.

Ten post edytował marcinpruciak 28.08.2008, 22:44:29
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 7.10.2025 - 14:30