Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: czy pisać to obiektowo?
Forum PHP.pl > Forum > PHP > Object-oriented programming
marekc12
Witam!

Uczę się PHP i postanowiłem napisać CMSa.. Już mam dodawanie/edytowanie podstron, menu. Mój CMS wszystko sobie zapisuje w bazie MySql.
Wyczytałem, że lepszym sposobem programowanie jest programowanie obiektowe.

Tylko właśnie nie do końca wiem czy lepiej pisać to obiektowo czy nie... i to jest moje pytanie smile.gif

Np. w PANELU ADMINA w dziale PODSTRONY mam to zrobione tak:

*zapytanie:
  1. SELECT `id`, `status`, `nazwa`, `data_utworzenia`, `data_edycji`, `autor` FROM `podstrony` ORDER BY `id`

*za pomocą:
  1. <?php
  2. while ($wiersz = mysql_fetch_row($idzapytania))
  3. ?>
wyświetlam wszystko w tabeli, USER może sobie zaznaczyć kilka PODSTRON i kliknąć USUŃ.
DOKUMENT SIE PRZELADOWUJE I MAM W ZMIENNYCH POST/GET NUMERY ID PODSTRON DO USUNIECIA
*zapytanie:
  1. DELETE FROM `podstrony` WHERE `id`='.$delete
usuwa podstronę

A jeżeli dobrze zrozumiałem to obiektowo musiałoby to wyglądać jakoś tak:


tworze sobie klasę, w niej zmienne private $id,$status,$nazwa,$data_utworzenia,$data_edycji,$autor. Jako obiekty ładuje do klasy wszystko z MySql - każda podstrona to jeden obiekt. hmm tworze sobie funkcję w klasie która mi będzie wyświetlać tak jak wczesniej po kolei dane... USER zaznacza kilka do usuniecia i teraz zeby usunac dane funkcją np. UsunDane() (ktorą sobie stworze w klasie) to musze najpierw wczytac dane obiekty i potem wywolac fukncje UsunDane().. A normalnie po prostu usuwam obiekty o danym ID bez wczytywania ich.

wiec wychodzi dłużej ;/ Czyli obiektowo czy nie? Moze ja nie rozumiem obiektowoście po prostu jeszcze, moze to sie roi inaczej??
mike
Cytat(marekc12 @ 1.08.2008, 15:51:55 ) *
Moze ja nie rozumiem obiektowoście po prostu jeszcze??
Nie rozumiesz tongue.gif
Poszukaj watków na ten temat, było ich już kilka i nie najmniejszego sensu wałkować tego raz jeszcze.
marekc12
dobra, trochę poczytałem i na początek napisałem klasę do obsługi bazy danych:
  1. <?php
  2. class BazaSql
  3. {
  4. const SQLSERWER = 'localhost';
  5. const SQLUSER = 'user';
  6. const SQLPASS = 'kl234';
  7. const SQLNAME = 'baza';
  8. protected $sql_conn;
  9.  
  10. public static function polacz()
  11. {
  12. $self->sql_conn = mysql_connect(self::SQLSERWER, self::SQLUSER, self::SQLPASS);
  13. mysql_select_db(self::SQLNAME);
  14. }
  15.  
  16. public static function rozlacz()
  17. {
  18. mysql_close($self->sql_conn);
  19. }
  20. }
  21.  
  22. class Zapytanie extends BazaSql 
  23. {
  24. public static function wyslij_zapytanie($tekst_zapytania)
  25. {
  26. $self->idzapytania = mysql_query($tekst_zapytania);
  27. }
  28.  
  29. static public $idzapytania;
  30. }
  31. ?>


W ten sposob przynajmniej teoretycznie zyskałem na bezpieczeństwie, gdyż np. hasło do bazy jest dostępne tylko z wewnątrz klasy BazaSql smile.gif
to są moje naprawdę początki (uczę się od przed wczoraj programowania obiektowego ;D) i napiszie mi co myślicie o tym kodzie?
coś mi się wydaje ze się okaze to jest całkiem nie tak haha.gif
.radex
no nie do końca takie bezpieczniejsze, ponieważ można to uzyskać poprzez

echo BazaSql::SQLPASS;

Niepotrzebnie rozdzielasz zapytanie od bazasql. Oprócz tego jest ok.
marekc12
czyli lepiej chyba nie robić tego jako stałe ale zmienne private, wtedy będzie bezpiecznie.
Rozdzielając to myślałem właśnie o bezpieczeństwie, żeby funkcja "Zapytanie" nie miała dostępu do hasła do bazy. W razie np SqlInjection (przed którym oczywiscie mozna sie zabezpieczać) było by jeszcze bardziej bezpiecznie. Chociaż w razie takiego ataku i tak chyba haker może zrobić wszystko .. więc może i to nie ma sensu.. smile.gif
Shili
Cytat
Rozdzielając to myślałem właśnie o bezpieczeństwie, żeby funkcja "Zapytanie" nie miała dostępu do hasła do bazy. W razie np SqlInjection (przed którym oczywiscie mozna sie zabezpieczać) było by jeszcze bardziej bezpiecznie.
W ataku sql injection hasło jest co najmniej zbędne. "Haker" już jest połączony z bazą, więc w przypadku luki i tak zrobi co chce.

Jeśli zrobisz zmienne private, to klasa Zapytanie już ich nie odziedziczy. Ze swojej strony również proponuję zrobić z niej metodę do klasy BazaSql
marekc12
Cytat(Shili @ 1.08.2008, 22:55:50 ) *
Jeśli zrobisz zmienne private, to klasa Zapytanie już ich nie odziedziczy.


o to właśnie chodziło mi, ale teraz już wiem, że to nie ma sensu smile.gif Połącze bazesql z zapytaniem. Poza tym i tak użyję unset($self->sqlpassword); winksmiley.jpg
dadexix
a nie lepiej poprostu skożystać z jakiejś gotowej klasy/klas do obsługi DB? "u nas w necie tego pełno"
marekc12
Czy uważacie, że opłaca się pisać obiektowo jeżeli to nic nie da oprócz ładniejszego kodu?
No bo ja np. nie widzę innych pozytywnych stron jeżeli chodzi o moją klasę do bazy danych oprócz tego, że funkcje do baz są ładnie zgrupowane w klasę. Tak samo chyba będzie z obsługą podstron w moim CMSie, bo nie wiem czy coś mi da że podstrony będą obiektem smile.gif

Wg was lepiej pisać obiektowo, choćby dla ładniejszego kodu?

Niby jeżeli chodzi o ilość kodu to w sumie na to samo chyba wyjdzie.... no mi się wydaje, że lepiej jednak obiektowo.

EDIT:
przeglądam posta: Temat: PHPOOP Czy to tak moze byc
i tam jest taki kod:
  1. <?php
  2. public function edytuj_podstrone($id, $menu, $tresc) {
  3.  
  4. mysql_query("UPDATE `oop_cms`.`podstrony` SET `menu` = '$menu', `tresc` = '$tresc' WHERE `id` = $id LIMIT 1");
  5.  
  6. }
  7. ?>


Założyłem że to tak ma wyglądać, ale hmmm zaraz się pewnie okaże, że to tak się nie robi, czy tak?? No bo tak to ta obiektowość nic nie daje w tym przypadku bo to samo można napisać za pomocą zwykłej funkcji.
Sedziwoj
Na początku tak się wydaje, że tylko ładniej, jak zaczniesz pojmować o co w tym chodzi, to zaczniesz rozumieć jaka jest w tym siła. Programowanie obiektowe, to nie jest jedna klasa, czy dwie, to wiele współpracujących ze sobą obiektów, ale aby to zrobić użytecznie, ładnie i elastycznie trzeba dużo czasu.
Moim zdaniem powinieneś zainwestować w książkę (choć nie powinno się brać tego co autor pisze jak prawdę, bo czasem mają głupie poglądy), poczytać kod jakiś prostych rzeczy napisanych obiektowo, czy chociażby je wykorzystać. Wtedy zrozumiesz jak to działa, bo samemu dochodząc bez przykładów, to zajmie wieki...
Spróbuj zintegrować swój projekt z Propel, poużywać go, na pewno wiele się dzięki temu nauczysz.

@marekc12

Uważaj na to co znajdziesz w internecie, bo czasem niby mądre osoby, a głupoty piszą.
Powinieneś zacząć od tego co ma ten obiekt robić, jaki ma zakres obowiązków, a potem dopiero wyszczególniać metody i właściwości.

Czyli np. ma łączyć się z bazą i umożliwiać wykonywanie kwerend na niej.

Co jest z interfejsu, wykonywanie kwerend, teraz pytanie jak to komplikować:
- można podzielić na dwa rodzaje, te co zwracają coś (SELECT) i te co nie zwracają (UPDATE/INSERT itp) więc można je rozdzielić, i wtedy np. jedna metoda zwraca tablice rekordów, a druga nic...
czy jakkolwiek, ale wszystkie mysql_*() powinny być w jednej klasie, a inne korzystać tylko z jej interfejsu.
marekc12
  1. <?php
  2. class Podstrony
  3. {
  4. private $podstrony;
  5.  
  6. public function listaPodstron()
  7. {
  8. $this->podstrony = BazaSql::wyslijZapytanie('SELECT `id`, `status`, `nazwa`, `data_utworzenia`, `data_edycji`,
  9. `autor`, `tekst` FROM `podstrony` ORDER BY `id`');
  10. return($this->podstrony);
  11. }
  12.  
  13. public function dodajPodstrone()
  14. {
  15. BazaSql::wyslijZapytanie('INSERT INTO `podstrony` (`id`, `status`, `nazwa`, `data_utworzenia`, `data_edycji`, `autor`, `tekst`)
  16. VALUES ("", 0 ,"Nowa", datetime(), datetime(), "admin", "Dział w budowie...")');
  17. }
  18. }
  19.  
  20. $obiekt = new Podstrony();
  21.  
  22. $idzapytania=$obiekt->listaPodstron();
  23.  
  24. while ($wiersz = mysql_fetch_row($idzapytania))
  25. {
  26. //wyswietlanie wynikow
  27. }
  28. ?>


Czy taki kod jest ok? Oczywiscie jest to tylko zarys;) Ale czy to co jest jest ok?

no i martwi mnie to ze jest tylko 1 obiekt... dlatego nie wiem czy to tak ma być
.radex
Kod
private $podstrony;

    public function listaPodstron()
    {
        $this->podstrony = BazaSql::wyslijZapytanie('SELECT `id`, `status`, `nazwa`, `data_utworzenia`, `data_edycji`,
                `autor`, `tekst` FROM `podstrony` ORDER BY `id`');
        return($this->podstrony);
    }


Bez sensu. Nie można po prostu

Kod
    public function listaPodstron()
    {
        $podstrony = BazaSql::wyslijZapytanie('SELECT `id`, `status`, `nazwa`, `data_utworzenia`, `data_edycji`,
                `autor`, `tekst` FROM `podstrony` ORDER BY `id`');
        return $podstrony;
    }


?
marekc12
hmmm ale to w ogólnie nie wykorzystuje obiektowości.... myślałem, że to się robi jakoś inaczej, ;p
No to w sumie tak jak po staremu smile.gif
Sedziwoj
@marekc12
Widzisz użyte mysql_fetch_row(), a tego nie powinno być poza obiektem. Wydaje mi się, że powinieneś mieć dwie metody, jedna do "INSERT, UPDATE, REPLACE, DELETE" druga do "SELECT, SHOW", dlaczego rozdzielić? Bo inaczej się je obsługuje, w pierwszej możesz zwracać mysql_affected_rows() czy mysql_insert_id(), a w drugiej właśnie wykonać w pętli mysql_fetch_assoc() i zwrócić już tylko tablicę. Rób tak aby zamknąć wszystkie funkcje mysql_*() w tej klasie, abyś w czasie korzystania z niej, nie miał potrzeby ich używania, a jak to zrobić, staraj się jak najwygodniej dla siebie. Chwilę poużywasz, a zapewne wpadniesz na pomysł jak to zrobić lepiej.

Cytat(marekc12 @ 2.08.2008, 11:13:22 ) *
hmmm ale to w ogólnie nie wykorzystuje obiektowości.... myślałem, że to się robi jakoś inaczej, ;p
No to w sumie tak jak po staremu smile.gif


Spokojnie, napiszesz jeden obiekt, potem będziesz mógł dalej rozszerzać. Pamiętaj aby utrzymać tę klasę jak najprostszą, potem możesz napisać co korzysta z niej i rozszerza jej możliwości.
Np. zrobić metodę update() której przekazujesz id,nazwę tabeli i array( 'pole' => 'wartość' ) a ona sama tworzy SQL i robi update.
Na początku zaczyna się od banalnie prostych rzeczy, potem się wchodzi w trudniejsze, tu ważne jest zrozumienie. Dlatego proponowałem, abyś skorzystał z Propel, bo najpierw byś poużywał, zobaczył jak to działa, a potem mógł zerknąć w kod i zobaczyć jak to zrobili.
marekc12
Cytat(Sedziwoj @ 2.08.2008, 11:25:00 ) *
Spokojnie, napiszesz jeden obiekt, potem będziesz mógł dalej rozszerzać. Pamiętaj aby utrzymać tę klasę jak najprostszą, potem możesz napisać co korzysta z niej i rozszerza jej możliwości.
Np. zrobić metodę update() której przekazujesz id,nazwę tabeli i array( 'pole' => 'wartość' ) a ona sama tworzy SQL i robi update.
Na początku zaczyna się od banalnie prostych rzeczy, potem się wchodzi w trudniejsze, tu ważne jest zrozumienie.


chyba zaczynam czaić o co biega snitch.gif
Cysiaczek
Zgadzam się, Propel to najlepszy start dla kogoś, kto chce zobaczyć, jak wygląda obiektowa obsługa baz danych. Nie jest może doskonały, ale jak ktoś go "załapie", to potem samo pójdzie smile.gif
marekc12
No to zainteresuję się Propelem smile.gif

hmmm czyli np. mogę to zrobić tak:
klasa Babcia (metody: PołączenieZBazą, RozłączenieZBazą, WysyłanieZapytaniaPodanegoWParametrze)
klasa Mama (metody: ZapisDoBazy[za pomocą funckcji w "babci": WysyłanieZapytaniaPodanegoWParametrze], OdczytZBazy[tak samo])
klasa Córka_Podstrony (metody: NowaPodstrona[z pomocą ZapisDoBazy w matce], UsunaPodstrone[z pomocą ZapisDoBazy w matce], ListaPodstron[z pomoca funkcji OdczytZBazy])
klasa Córka_Menu (metody: NowePodmenu[z pomocą ZapisDoBazy w matce], UsunMenu[z pomocą ZapisDoBazy w matce], ListaMenu[z pomoca funkcji OdczytZBazy])

oczywiście dziedziczenie: Babcia -> Mama -> Córki ;Dhehe


nie za bardzo zagmatwane? dobrze to wykombinowałem ?
.radex
Cytat(marekc12 @ 2.08.2008, 11:49:00 ) *
No to zainteresuję się Propelem smile.gif

hmmm czyli np. mogę to zrobić tak:
klasa Babcia (metody: PołączenieZBazą, RozłączenieZBazą, WysyłanieZapytaniaPodanegoWParametrze)
klasa Mama (metody: ZapisDoBazy[za pomocą funckcji w "babci": WysyłanieZapytaniaPodanegoWParametrze], OdczytZBazy[tak samo])
klasa Córka_Podstrony (metody: NowaPodstrona[z pomocą ZapisDoBazy w matce], UsunaPodstrone[z pomocą ZapisDoBazy w matce], ListaPodstron[z pomoca funkcji OdczytZBazy])
klasa Córka_Menu (metody: NowePodmenu[z pomocą ZapisDoBazy w matce], UsunMenu[z pomocą ZapisDoBazy w matce], ListaMenu[z pomoca funkcji OdczytZBazy])

oczywiście dziedziczenie: Babcia -> Mama -> Córki ;Dhehe
nie za bardzo zagmatwane? dobrze to wykombinowałem ?


IMO trochę za bardzo zagmatwane. Zainteresuj się wzorcem projektowym MVC winksmiley.jpg
Sedziwoj
marekc12 ja Ci na prawdę dobrze radzę, teraz co powinieneś zrobić, to przerwanie wymyślania, wzięcie Propela i użycie go w paru miejscach, jak to zrobisz, wtedy wróć do wymyślania swoich pomysłów.
marekc12
Cytat(radex_p @ 2.08.2008, 13:39:43 ) *
IMO trochę za bardzo zagmatwane. Zainteresuj się wzorcem projektowym MVC winksmiley.jpg

to MVC jest trochę porypane.. tzn nie do końca czaje o co biega ;d chyba chodzi o to jak będzie zbudowany mój cms.



Ja to chciałem zrobić w ten sposób(i normalnie i w panelu Admina tak samo):


w index.php includuje 2 pliki: skrypty.php i widok.php. Czyli najpierw wykonuje skrypty a pozniej wyswietlam.

np. w skrypty.php laczę sie z bazą, wczytuja sie podstrony do zmiennej, nie ma zadnego echo, nic nie jest wyswietlane.

A w widok.php jest całe body,meta,head i tylko elementy php: echo,if,for które wyswietlaja dane ze zmiennych(np .wczytane podstrony) ze skrpyty.php.




Czy tak jak ja to robie będzie nie poprawnie??

Skąd mozna sciagnać tego Propela??
kwiateusz
z internetu http://propel.phpdb.org/trac/ 1szy wynik z googla...
phpion
Cytat(marekc12 @ 3.08.2008, 14:30:59 ) *
Skąd mozna sciagnać tego Propela??

sciana.gif propel download
marekc12
muszę sobie postawić serwer php,mysql na swoim kompie, tak? i potem to jakos zainstalować? (pracuję na Windowsie)

A jest jakiś prosty cms pisany obiektowo żebym móbł sobie kod zobaczyć i z tego się nauczyć??

i niech ktoś mi jeszcze odpowie na 1 pytanie - 3 posty wyzej.
php1983
Cytat(marekc12 @ 3.08.2008, 14:30:59 ) *
to MVC jest trochę porypane.. tzn nie do końca czaje o co biega ;d chyba chodzi o to jak będzie zbudowany mój cms.

Ja to chciałem zrobić w ten sposób(i normalnie i w panelu Admina tak samo):
[...]Czy tak jak ja to robie będzie nie poprawnie??


Zagubisz dane, bedziesz miał kłopot, żeby zmienić kod i się w nim połapać. Obiekty powstay pierwotnie po to, źeby ułatwić prace z dużymi ilościami kodu i żeby kod był bardziej elsatyczny. Proponnuje taki schemat:
I: Klasa dostępu do danych
II: Klasy szczegółowych zadań --> Base class [ metody połączenia z wyższą i z niższą warstwą ]
III: Przekierowanie rządań/ wyników --> Base...
IV: Klasy Output --> Klasy przegladarki --> Klasy template --> Base...
marekc12
Cytat(php1983 @ 3.08.2008, 18:08:24 ) *
I: Klasa dostępu do danych
II: Klasy szczegółowych zadań --> Base class [ metody połączenia z wyższą i z niższą warstwą ]
III: Przekierowanie rządań/ wyników --> Base...
IV: Klasy Output --> Klasy przegladarki --> Klasy template --> Base...


hmmm nic z tego nie rozumiem smile.gif

Nie myślałem, że programowanie obiektowe jest takie trudne:) chyba napiszę sobie tego CMSa 'tradycyjnym' sposobem..
Cysiaczek
Jest taka zasada, że jeśli nie widzisz zastosowania obiektów to ich nie używasz smile.gif

Pozdrawiam.
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.