Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] co powinna zawierac klasa?
miczops
post
Post #1





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


witam, znalazlem na forum taki temat: Temat: Klasa PHP system artykulow

nie ma tam jednak wytlumaczenia czemu w klasie Article nie moze byc metody deleteArticle ? w takim razie gdzie ona ma byc? jest napisane, ze w Article_Model, ale jakby wtedy miala wygladac klasa Article? jest cos, ze informacje o tytule, tresci itp, ale jakby to mialo wygladac?
Go to the top of the page
+Quote Post
lukaskolista
post
Post #2





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

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


generalnie klasa powinna miec to, czego potrzebujesz do operacji na obiektach tej klasy. Jezeli potrzebujesz miec mozliwosc usuniecia artykulu jako obiektu, to niby czemu nie? Pamietaj, ze kazdy ma nieco inne podejscie do programowania, jednym cos pasuje a innym nie. Juz bardziej akrykul nie powinien miec mozliwosci laczenia sie z baza, polaczenie z baza z reguly (chyba we wszystkich normalnych projektach) jest osobnym obiektem

metody klasy article
create
edit
delete

sa jak najbardziej w porzadku.

Co do modelu: jest to wymysl MVC ktorego w zadnym wypadku nie musisz implementowac.
Go to the top of the page
+Quote Post
bastard13
post
Post #3





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

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


Klasa powinna zawierać wszystko co jest niezbędne do operacji na niej.
Programowanie obiektowe ma to do siebie, że warto (na początku, w trakcie nauki) zadawać sobie pytanie, co klasa musi mieć np. klasa Artykuł?
Pasowałoby, żeby miała wartości (atrybuty) tytuł i tekst. W dobrym zwyczaju jest tworzyć atrybuty jako protected bądź private i dodawać odpowiednie settery i gettery (w zależności od potrzeb).
Artykuł powinno się móc stworzyć, zniszczyć i edytować. To wszystko są metody.
Jednak, tak jak napisał lukaskolista samo połączenie z bazą to już powinna być inna klasa (czasopismo, w którym jest artykuł, to nie jest już część artykułu:)
Oczywiście to tylko bardzo krótki wstęp, ale tak mniej więcej to wygląda.
Go to the top of the page
+Quote Post
miczops
post
Post #4





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


dzieki za odpowiedzi. a jakbym to mial zapisac w tej klasie te atrybuty tytul i tekst? i czy cos takiego jak setter jest potrzebne, jesli bede operowal tylko na danych z bazy?
Go to the top of the page
+Quote Post
bastard13
post
Post #5





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

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


Nic nie jest wymagane, to tylko sugestie.
Klasa Article posłużyła jedynie za przykład:
  1. class Article
  2. {
  3. protected $_title;
  4. protected $_content;
  5.  
  6. public function setContent($content)
  7. {
  8. $this->_content = $content;
  9. return $this;
  10. }
  11. public function getContent()
  12. {
  13. return $this->_content;
  14. }
  15.  
  16. public function setTitle($title)
  17. {
  18. $this->_title= $title;
  19. return $this;
  20. }
  21. public function getTitle()
  22. {
  23. return $this->_title;
  24. }
  25.  
  26. static public function factory()
  27. {
  28. return new self();
  29. }
  30. }


Oczywiście dla pobierania artykułu z bazy danych wygląd i budowa klasy będzie inna, ale myślenie jest podobne.
Go to the top of the page
+Quote Post
miczops
post
Post #6





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


dzieki (IMG:style_emoticons/default/smile.gif)

a mozesz mi jeszcze powiedziec jakie zastosowanie tutaj maja te settery? bo get to wiem, ale dajmy ze mam bloga z artykulami i w jakiej sytuacji moge uzyc setterow? i co robi ta funkcja factory? i czemu wlasciwie np w GetTitle nie ma zrobionego pobierania z bazy?
Go to the top of the page
+Quote Post
bastard13
post
Post #7





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

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


To był tylko przykład.
Nie sugeruj się tym co napisałem, bo to nie jest klasa pobierająca cokolwiek z bazy, tylko klasa pokazująca budowę.
W twoim przypadku wyglądałoby to np. tak:
  1. class Article
  2. {
  3. protected $_title = '';
  4. protected $_content = '';
  5. protected $_id = null;
  6.  
  7. public function __construct($id = null)
  8. {
  9. if ($id !== null)
  10. //jeżeli zostało przekazane id tzn. że trzeba pobrać z bazy, więc tutaj w tym momencie byłoby zapytanie typu:
  11. //select title,id,content from article where id=$id
  12. //oraz przypisanie odpowiednich wartości do odpowiednich parametrów klasy
  13. }
  14.  
  15. public function setContent($content)
  16. {
  17. $this->_content = $content;
  18. return $this;
  19. }
  20. public function getContent()
  21. {
  22. return $this->_content;
  23. }
  24.  
  25. public function setTitle($title)
  26. {
  27. $this->_title= $title;
  28. return $this;
  29. }
  30. public function getTitle()
  31. {
  32. return $this->_title;
  33. }
  34.  
  35. static public function factory($id = null)
  36. {
  37. return new self($id);
  38. }
  39.  
  40. public function save()
  41. {
  42. if($this->_id === null)
  43. //nowy artykuł więc dodajemy do bazy
  44. else
  45. //skoro jest id tzn. że updatujemy rekord w bazie
  46.  
  47. return boolean; //zwracanie true lub false
  48. }
  49.  
  50. public function delete()
  51. {
  52. if($this->_id === null)
  53. return false; //nowy artykuł więc nie ma co usuwać, czyli nie usunięto, zwracamy false
  54. else
  55. //skoro jest id to delete elementu
  56.  
  57. return boolean; //zwracanie true lub false
  58. }
  59.  
  60. }


I teraz masz tak:
update:
  1. //update elementu o id 1, ustawianie title = tytul, content = content
  2. Article::factory(1)
  3. ->setTitle('tytul')
  4. ->setContent('content')
  5. ->save();

usuwanie elementu o id 1
  1. Article::factory(1)->delete();

nowy:
  1. Article::factory()
  2. ->setTitle('tytul')
  3. ->setContent('content')
  4. ->save();


Factory po to, żeby nie trzeba było robić tak:
  1. $article = new Article;
  2. $article->setTitle('tytul')
  3. ->setContent('content')
  4. ->save();


Jest to jeden z wzorców projektowania, o których warto poczytać(IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
miczops
post
Post #8





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


o super, wielkie dzieki dobry czlowieku (IMG:style_emoticons/default/smile.gif) a jaki to jest wzorzec? MVC?
jeszcze mam kilka pytan (IMG:style_emoticons/default/tongue.gif) wzialem ta klase i przykladowo zrobilem tak:

  1. class Article
  2. {
  3. protected $_title = '';
  4. protected $_content = '';
  5. protected $_id = null;
  6.  
  7. public function __construct($id = null)
  8. {
  9. if ($id !== null) {
  10. $pdo = $pdo->query(select * from article where id = $id);
  11. return $pdo;
  12. }
  13. }
  14. // construct zawsze sie wykonuje przy odwolaniu do klasy?
  15. public function setContent($content)
  16. {
  17. $this->_content = $content;
  18. return $this;
  19. }
  20. public function getContent()
  21. {
  22. return $this->_content;
  23. }
  24.  
  25. public function setTitle($title)
  26. {
  27. $this->_title= $title;
  28. return $this;
  29. }
  30. public function getTitle()
  31. {
  32. return $this->_title;
  33. }
  34.  
  35. static public function factory($id = null)
  36. {
  37. return new self($id);
  38. }
  39.  
  40. public function save()
  41. {
  42. if($this->_id === null) {
  43. $pdo->prepare(insert into ) itd
  44. /bind value itd
  45.  
  46. else
  47. $pdo->prepare (update itd
  48.  
  49. return boolean; //true zwraca jesli sie wykona, a false jesli nie? tylko skad ta funkcja wie co zrobilo $pdo?
  50. }
  51.  
  52. public function delete()
  53. {
  54. if($this->_id === null)
  55. return false; //nowy artykuł więc nie ma co usuwać, czyli nie usunięto, zwracamy false
  56. else
  57. //skoro jest id to delete elementu
  58.  
  59. return boolean; //zwracanie true lub false
  60. }
  61.  
  62. }


laczenie z baza mam w innej klasie, wiec jak to zrobic w tej? a moze po prostu ta powinna rozszerzac klase np CONNECT i zrobic:
class Article extends Connect ?

i jeszcze


protected $_title = '';
protected $_content = '';
protected $_id = null;

+
public function getContent()
{
return $this->_content;
}

nie do konca kapuje jak to dziala. najpierw je deklarujemy jako protected, czyli sa widoczne tylko w tej klasie, potem jak mamy funkcje ktora zwraca Content to zwracamy _content, ale skad ta klasa wie, ze to akurat opis artykulu?


pozdrawiam i jeszcze raz wielkie dzieki za pomoc
Go to the top of the page
+Quote Post
bastard13
post
Post #9





Grupa: Zarejestrowani
Postów: 664
Pomógł: 169
Dołączył: 8.01.2010
Skąd: Kraków

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


1) To nie MVC:) to po prostu OOP:)
2) Połączenie zrealizuj jako Singleton (kolejny DP:) . Nie rozszerzaj klasy Article o to połączenie, bo przecież połączenie z bazą nie ma nic wspólnego z artykułem.
Możesz to zrealizować np. tak:
  1. class DbConnection
  2. {
  3. protected $_connection;
  4. static protected $_instance = null;
  5. static public function getInstance($connection = null)
  6. {
  7. if(self::$_instance === null)
  8. new self($connection);
  9. return self::$_instance;
  10. }
  11. protected __contstruct($connection)
  12. {
  13. $this->_connection = $connection;
  14. }
  15. public function getConnection()
  16. {
  17. return $this->_connection;
  18. }
  19. }

Teraz, żeby pobrać połączenie z bazą musisz wywołać DbConnection::getInstance()->getConnection() i za każdym razem jest to, to samo połączenie.
Oczywiści najpierw musisz je zainicjalizować, czyli DbConnection::getInstance($connection).
Możesz również nawiązywać połączenie w konstruktorze, wtedy nie będzie potrzebne przekazywanie parametru/parametrów za pierwszym razem.
Jest to oczywiście bardzo luźna podpowiedź, a nie dokładna implementacja, ale powinno to wyglądać podobnie.

3) Wszystkie atrybuty powinny być (zazwyczaj) protected bądź private, a odwołanie do nich powinno odbywać się za pomocą getterów i setterów.
Co do tego skąd klasa wie, że to treść artykułu, to przy pobieraniu danych z bazy musisz ustawić wszystkim atrybutom odpowiednie wartości pobrane z bazy.
Go to the top of the page
+Quote Post
miczops
post
Post #10





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


dzieki, dzieki, ale jeszcze kolejna prosba (IMG:style_emoticons/default/wink.gif) chce uzywac PDO do laczenia, wiec jakby to ustawienie atrybutow mialo wygladac? mam sobie baze no i tam niech bedzie tylko to TITLE i CONTENT, no i jak to teraz polaczyc z tym co mi tam wyzej napisales? (IMG:style_emoticons/default/smile.gif) tak jak ja zaczalem pisac, czy jakos inaczej? bo rozumiem troche jak to dziala, ale jakos nie moge sobie wyobrazic calego dzialania bez tej bazy.

bo robie np tak jak napisales:
  1. 1.
  2. Article::factory()
  3. ->setTitle('tytul')
  4. ->setContent('content')
  5. ->save();


wiec wskakujemy do klasy i tutaj sie wykonuje to __construct i tam jak ten select wlasnie wyglada, bo nie wiem jak polaczyc te atrybuty? no i wchodzimy do settera i tam jest
  1. $this->_title= $title;
  2. return $this;

czyli by wychodzilo, ze tej zmiennej protected _title przypisujemy to co przeslalismy, czyli $title, ale co nam to daje? jakos bez calego polaczenia z baza nie moge tego pojac, bo tu wychodzi, ze zwracamy to samo co wyslalismy (IMG:style_emoticons/default/tongue.gif)

jeszcze raz wielkie dzieki, ze chce Ci sie poswiecac czas na takie cos (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
lukaskolista
post
Post #11





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

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


setTitle() jest po to, zeby ustawic wlasciwosc _title obiektu i pozniej zapisac go do bazy za pomoca save()

przykladowy zapis moze wygladac tak

  1. public function save() {
  2. if (isset($this->_id)) {
  3. mysql_query("UPDATE articles SET title='".$this->_title."' WHERE id = ".(int)$this->_id);
  4. } else {
  5. mysql_query("INSERT INTO articles (title) VALEUS ('".$this->_title."')");
  6. }
Go to the top of the page
+Quote Post
miczops
post
Post #12





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


dzieki wielkie (IMG:style_emoticons/default/smile.gif)

a jak teraz wyglada pobieranie artykulow, zeby je wyswietlic na stronie glownej, a potem zrobic jeszcze linki do wyswietlenia ich?


myslalem nad czym w stylu

  1. public function showIndex(){
  2. $index=(select * from articles);
  3. }


ale Bastard cos wspomnial, ze w contruktorze to by mozna, wiec tak jak pisalem pare postow wczesniej to jest ok? a jak sie potem do tego odwolowac?

dzieki wielkie za pomoc

Ten post edytował miczops 2.04.2011, 10:21:09
Go to the top of the page
+Quote Post
Potter125
post
Post #13





Grupa: Zarejestrowani
Postów: 35
Pomógł: 7
Dołączył: 18.02.2007

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


to już prędzej w klasie musiałbyś zmienić np:
  1. public function __construct($id = null)
  2. {
  3. if ($id !== null) {
  4.  
  5. $pdo = $pdo->query(select * from article where id = $id);
  6.  
  7. } else {
  8.  
  9. $pdo = $pdo->query(select * from article);
  10.  
  11. }
  12.  
  13. return $pdo;
  14.  
  15. }


i w tym wypadku po prostu, jeśli chciałbyś wylistować wszystkie artykuły, to nie wywołujesz save

Ten post edytował Potter125 2.04.2011, 10:35:41
Go to the top of the page
+Quote Post
miczops
post
Post #14





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


dzieki, a jak sie do tego wtedy odwolac, zeby fetchem pobierac?

  1. while($post = Article::factory()->fetch()) {
  2. ?>
  3. <a href=<?php echo $post['id']; ?> > <?php echo $post['title']; ?> </a>
  4. <?php echo $post['content'];
  5. }

?
to id tez pobierze? niestety nie mam teraz jak sprawdzic tego, bede dopiero popoludniu w domu, ale poki co sobie czytam i robie teorie:)


pomoze ktos jeszcze? (IMG:style_emoticons/default/wink.gif) chociazby jakims przykladem
Go to the top of the page
+Quote Post
Crozin
post
Post #15





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

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


Trochę popsuję zabawę... (IMG:style_emoticons/default/wink.gif) Na początek spróbuj zapomnieć o tym co przeczytałeś powyżej, bo ilość fatalnych praktyk czy zapisów wręcz wypaczających podstawowe założenia OOP jest tam ogromna.

1. Chyba najbardziej elementarna zasada OOP - [url=http://en.wikipedia.org/wiki/Single_responsibility_principle]zasada pojedynczej odpowiedzialności (swoją drogą już chyba sety raz wrzucam ten link na tym forum). Jeśli to spieprzysz to z góry spieprzyłeś cały projekt. Zastanów się czy widziałeś kiedyś artykuł (kartkę papieru z tekstem) który jest w stanie sam się utworzyć, sam się zniszczyć i do tego prezentować sobą jakieś informacje? Ja nie, Ty pewnie też. Wszystko dlatego, że artykuł jedyne co robi to reprezentuje jakąś informację, natomiast za jego tworzenie odpowiedzialna jest drukarka, która wykorzystuje czyste (nie wypełnione informacjami) kartki. Nawet niszczenie to często zadanie innej maszyny - niszczarki albo Twoich rąk. Tak samo jest tutaj. Article jedyne co robi to reprezentuje dane. Jakiś ArticleManager odpowiedzialny jest za utrwalanie i usuwanie owych artykułów ze źródła (np. bazy danych). Możesz mieć jeszcze osobny obiekt ArticleRepository odpowiedzalny jedynie za zwracanie danych ze źródła.

2. OOP to jak sama nazwa wskazuje programowanie obiektowe, a klasa jest w nim jedynie złem koniecznym i w miarę możliwości powinieneś unikać wszystkiego co jest z nią bezpośrednio związane. Dotyczy to m.in. właściwości i metod statycznych, z których prawdę mówiąc nie trzeba zbyt często korzystać. Na pewno nie dla czegoś takiego jak Article::factory() co jest jedynie obejściem ułomności PHP (który nie wspiera [tutaj nazwa czegoś takiego: new Article()->setTitle('abc') ale wypadło mi to z głowy]) w dodatku robi to jeszcze w brzydki sposób bo sugeruje, że metoda ta jest fabryką (google: factory pattern) którą nie jest.

3. Singleton to struktura mająca zapewnić istnienie co najwyżej jednego obiektu danej klasy, a nie obejście problemu komunikowania się różnych obiektów. Swoją drogą przecież połączenie z bazą danych to wręcz książkowy przykład gdzie tworzy się 1, 2, 3 obiekty danej klasy.

4. Swoją drogą to co tutaj robisz to nic innego jak ORM. I na tym etapie swojej zabawy z OOP daruj sobie pisanie własnego - nie masz po prostu możliwości zrobienia tego chociażby w miarę dobrze, a jest to w przypadku aplikacji webowych jeden z filarów aplikacji. Słaby ORM będzie Cie prześladować do końca... W PHP nie masz zbyt dużego wyboru. Osobiście proponuję Doctrine2 - trochę mu nadal brakuje, ale jako jeden z nielicznych obrał dobrą, sprawdzoną już gdzie indziej architekturę.

5. PHP ma co prawda bardzo słabo rozpowszechnione i jeszcze niezbyt dobrze ugruntowane konwencje pisania kodu, ale jakieś tam ma, więc się do nich stosuj. Czyli wywal te "_" sprzed nazw właściwości niepublicznych.

6. Tutaj w każdym przypadku powinieneś dla właściwości wykorzystać modyfikator private. Pamiętaj o tym, że protected jednak wchodzi w pewnym stopniu w publiczny interfejs obiektu. Każdy może przecież rozszerzyć Twoją klasę o swoją, która będzie miała dostęp do tych składowych, a raczej nie powinna - od tego są gettery / settery tutaj.
Go to the top of the page
+Quote Post
miczops
post
Post #16





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 1.04.2011

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


dzieki za wyklad (IMG:style_emoticons/default/smile.gif)

a z czego konkretnie sie polecasz uczyc? bo jak szukalem po googlach to roznie znajdowalo i teraz nie wiem o co sie zaczepic. najlepszy bylby jakis prosty kurs w przykladach, ale nie takie jak na wikibooks, bo ciezko to zrozumiec, a potem zastosowac w swoim projekcie
Go to the top of the page
+Quote Post

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: 25.09.2025 - 01:48