Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wstep do programowania obiektowego
Forum PHP.pl > Forum > PHP > Object-oriented programming
Polik
Witam! Wiem, ze macie pewnie dosc takich tematow ale kazdy z nas mial swoje poczatki i kogos o cos pytal smile.gif

Zaczne od tego, ze przeczytalem o programowaniu obiektowym w php dwie ksiazki, kilka przegladnalem. Intensywnie szukalem w necie stron o OOP w php na tym forum tez szukalem jednak nie znalazlem odpowiedzi.

W kazdym tutorialu czy ksiazce pisza co to jest klasa, obiekt jak takie cos stworzyc, co to jest dziedziczenie itp. O tym juz czytalem i raczej zrozumialem. Jednak nigdzie nie ma konkretnych przykladow. Dlatego chcialbym sie Was spytac jakbyscie sie zabrali za takie trywialne zadanie.

Powiedzmy, ze mamy strone gdzie jest formularz o polach imie i naziwsko. Pod spodem maja sie wyswietlic po kolei imiona i nazwiska wszystkich osob ktore sa wpisane w baze danych (taka lista ludzi).

Rozwiazanie widze tak:
mam dwie klasy jedna odpowiedzialna za polaczenie z baza danych i wykonywanie na niej zapytan. Druga ktora rerezentuje osoby. Kiedy wysylam formularz powstaje nowy obiekt "osoba", ktory w konstruktorze przyjmuje argumenty $imie i $nazwisko przekazuje dane drugiemu obiektowi "baza" aby ten wpisal czlowieka do bazy. Ok, udaje sie.

Problem mam z tym, ze nie wiem jak wypisac wszystkich uzytkownikow ktorzy znajduja sie w bazie.
Przeciez jezeli bede chcial np. stworzyc obiekt "osoba" aby wywolac metode getName() (ktora np. zwraca mi imie osoby) to wyswietli sie blad, ze w konstruktorze nie podalem parametrow. No bo w sumie nie wiem do jakies konkternej osoby ten obiekt ma sie odwolac. Mam stworzyc obiekt z byle jakimi argumentmami i podem wywolac getName(), to takie glupie jest. A moze stworzyc jakas nowa klase, ktora wypisze mi tych uzytkownikow? Ale to tez mnie nie przekonuje.

Prosze Was dajcie mi jakas odpowiedz, rozwiazanie.
Bardzo chcialbym to w koncu pojac.

Pozdrawiam!
starach
Eee spaprałeś. Niepotrzebnie odpowiadałeś na postawione pytanie. Też chętnie bym się zorientował jak inni widzą tę sprawę.
W sumie możnaby nawet jakiś minikonkurs zrobić na projektowanie aplikacji. Wyniki mogłyby się nadawać na kilkuset-stronicową książkę.

Ale wracają do tematu. Odpowiedzią na twój problem jest ORM - Object Relational Mapping, czyli na przykład Propel.
Reszta spoczywa na barkach odpowiedniego rozplanowania kontrolerów. Oczywiście zakładając że chcesz używać architektury opierającej się o kontrolery np. najpopularniejszy MVC.
Cysiaczek
Trzymając sie konwencji Propela
  1. <?php
  2. $users=UserPeer::doSelect(new Criteria());
  3. // i już mamy kolekcję obiektów klasy User
  4.  
  5. $user=UserPeer::retrieveByPk(1);
  6. // i już mamy jednego usera
  7. ?>

Klasa UserPeer to fabryka obiektów klasy User

Tak się to robi najczęściej. Oczywiście czasami chcesz obiekt User według np. imienia
Dopisujesz więc metodę
  1. <?php
  2. class UserPeer
  3. {
  4.  public static function getUsersByName($name, $c)
  5.  {
  6.    if !$c : $c=new Critreria() : null;
  7.    $c->add(UserPeer::FIRST_NAME, $name);
  8.    return self::doSelect($c);
  9.  }
  10. }
  11.  
  12. //i używasz
  13. $users=UserPeer::getUsersByName();
  14. ?>


  1. <?php
  2. foreach($users as $user)
  3. {
  4.  print $user->getFirstName().<br />;
  5. }
  6. ?>


Pozdrawiam
karmer
Witam,
dla mnie też to było ciężko pojąć. Ale udało się :-)
Po pierwsze zapomnij na razie o samym kodzie i podejdź do problemu bardziej ogólnie.
Zastanów się jakie obiekty możesz wyodrębnić w ropatrywanym problemie. Pomoże Ci w tym rozpisanie diagramów czynności (UML - bez tego naprawdę ciężko jest projektować OOP)
Zacznij od analizy tego co napisałeś.
  • wyświetlany jest formularz.
  • do formularza wprowadzane są dane, które wysyłane są do skryptu (jaki obiekt będzie je przetwarzał?). W/g mnie może to być obiekt formularz. Będzie wyświetlał formularz, obrabiał przesłane dane, przekazywał je kolejnemu obiektowi np. baza_osob.
  • baza_osob będzie kontenerem dla obiektów typu osoba. Baza_osob może posiadać metodę getwszystkieOsoby() zwracającą tablicę z imionami i nazwiskami wszystkich osób. Tablica taka zwrócona przez tą metodę może być przekazana do obiektu viewOsoby.
  • Zadaniem obiektu viewOsoby jest wyświetlanie wszystkich osób z bazy pod formularzem, lub gdziekolwiek chcesz.
Traktuj obiekty jak zamknięte pudełka. Zastanów się co do takiego pudełka musisz wrzucić aby muc z niego otrzymać porządany wynik. Np.

Obiekt baza_osob
Cel: przechowywanie danych osób i możliwość przekazania ich dowolnemu innemu obiektowi
Parametry wejściowe: dwuelementowa tablica zawierająca imię i nazwisko osoby
Wyjście: wieloelementowa tablica zawierająca imiona i nazwiska wszystkich osób
Zadania do wykonania:
  • pobranie danych wejściowych (2-elementowa tablica)
  • utworzenie nowego obiektu osoba i zapisanie go w prywatnej tablicy
  • powyższy krok - wielokrotnie
  • następnie możliwość wykonania metody getWszystkieOsoby(), która zwróci prywatną tablicę zawierającą dane osób
I tak z każdym obiektem.
Najważniejsze w/g mnie pytania jakie sobie zadawaj podczas projektowania OOP to:
  • który obiekt powinien zająć się daną czynnością lub w obowiązkach którego obiektu jest konieczność zajęcia się danym problemem? (np. sprawdzenie poprawności danych z formularza, wyświetlenie elementu strony www, wysyłanie poczty itp.)
  • dlaczego w/g mnie ten obiekt powinien wykonać tą czynność?
  • jak powinien ją wykonać?
  • czy może wykonać ją sam, czy może skorzystać z usług innego obiektu? (np. połączenie z bazą danych, umieszczanie zmiennych w sesji)
Oczywiście istnieje wiele pułapek czychających podczas takiej analizy (zbyt duża ilość klas, nieodpowiedni podział obowiązków klas) ale takie rzyczy wychodzą podczas praktyki :-)

Oczywiście wszystko powyżej to moje osobiste zdanie na temat projektowania.

Pozdrawiam Wszystkich Serdecznie
Polik
Po przeczytaniu waszych postow nasunelo mi sie kilka pytan.

Pierwsze troche offtopicowo:
Czytalem o MVC i wiem co to jest jednak na razie jeszcze boje sie tego ruszac. A pytanie brzmi: czy mozna napisac aplikacje oparta o model MCV nie korzystajac z frameworka? Jezeli tak, to jaki jest naklad pracy? Czy Wy piszac aplikacje zawsze korzystacie z frameworkow?

A pozostale pytania juz w temacie:
Nie wiem czy dobrze rozumiem ale kod ktory napisal Cysiaczek odnosi sie juz do klas ktore wytowrzylby propel? No bo nie wiem skad jest to odSelect i new Criteria.

Czyli jezeli dobrze rozumiem to praktycznie w kazdej aplikacji ktora korzysta z bazy danych dobrze by bylo korzystac z propela?

Pytania do tego co napisal karmer:
Bardzo fajnie to opisales, duzo wyjasniles, dzieki. Ale oczywiscie mam kilka pytan.
Czytajac twoj post naliczylem 4 klasy, sporo. Nie spodziewalem sie ze trzeba ich tak duzo smile.gif
Ale tak jak mowisz klasa formularz powinna zajac sie np. waliadacja i przekazaniem danych z formularza do innego obiektu. Jezeli tak to wydaje mi sie, w takim razie dla kazdego formularza umieszczonego na stronie (zakladajac, ze mamy wiecej podstron) musialbym stworzyc osobne klasy dla kazdego z nich, bo raczej ciezko by bylo napisac wspolna klase dla nich wszystkich. Dobrze rozumiem?

Klasa baza_osob posiada metode getWszystkieOsoby() jednakze jak piszesz przyjmuje jako agrument tablice zawierajaca imie i nazwisko. Ale przeciez kiedy strona startuje nie moze podac imienia i nazwiska? I nie jestem w stanie stowrzyc obiektu tej klasy a w konsekwencji wykonac metody.

Dzieki za pomoca mam nadzieje, ze i teraz nie pozostaniecie obojetni smile.gif
Pozdrawiam!
Cysiaczek
Jasne, że nie może podać imienia i nazwiska. Tu właśnie pojawia się model MVC ze swoimi akcjami.
Formularz może się pojawiać jako jedna akcja z widokiem, a obsługa formularza po naciśnięciu submit() jako inna akcja.
Ewentualnie może to być jedna akcja działająca w dwóch trybach. Np. gdy są wysyłane dane POST, akcja uruchamia sprawdzenie tych danych i obsługuje wysłany formularz. Gdy nie ma danych POST, wyświetla formularz.
Mając taki podział, używasz w odpowiednich miejscach odpowiednich klas.

Kod, który pokazałem to po prostu obsługa bazy danych poprzez bibliotekę Propel.
Są też inne biblioteki jak np. bardzo popularne Doctrine, czy Zend_DB (jeśli nie pomyliłem nazwy)

Jeśli chodzi o pisanie aplikacji. Nie wyobrażam sobie pisania jakiejkolwiek aplikacji bez użycia frameworka. Owszem, nie zawsze istniejące FW są dobre do wszystkiego, ale przy każdym dużym projekcie pisanym "od zera", zespół programistyczny i tak wytworzy własny FW, albo skorzysta z jakichś zewnętrznych bibliotek. Na jedno więc wychodzi.

Pisanie stronek w gołym PHP, nawet z użyciem klas i obiektów powoduje jedynie większy bałagan i negatywnie wpływa na opinię o języku jak i samych programistach. Teraz najsensowniejszą drogą nauki jest jednoczesna nauka PHP i używanie frameworków do pisania jakichkolwiek, nawet najmniejszych stronek. Idąc do pracy musisz znać dobrze minimum jeden framework (znając jeden innych nauczysz się w dwa dni). W wolnych chwilach możesz próbować pisać własne rozwiązania, albo rozwijać istniejące.

Pozdrawiam.
karmer
Witam,
Odpowiem na pytanie pierwsze ponieważ właśnie jestem na etapie tworzenia własnego frameworka.
Powiem tak... jeżeli chcesz się nauczyć programować w php, sprawia Ci to przyjemność i może kiedyś będziesz na tym zarabiał lub stanie się to Twoim hobby - to ok w porządku. Ale jeżeli masz wykonać jakiś projekt lub kilka i nie chcesz poświęcić temu np. min. 3h dziennie to lepiej nie pisać własnego frameworka i wykorzystać gotowe rozwiązanie.
Dla mnie programowanie sprawia wielką frajdę i jest moim hobby - ścieżka kariery zawodowej :-) popłynęła w innym kierunku niestety. Dopiero pracując nad własnym frameworkiem zorientowałem się ile jest nad tym pracy. W tym miejscu podziękowania dla wszystkich forumowiczów PHP.pl za wiedzę zawartą na tym forum. Coś niesamowitego :-).

Odpowiadając dalej na pytanie o klasę formularza:
właśnie w tej chwili pracuję nad taką klasą. Wydaje mi się, że zaprojektowanie klasy, która mogłaby reprezentować wszystkie formularze jest bardzo trudne. Można sobie jednak trochę pomóc. U mnie wygląda to w tej chwili tak:
  • mam klasę jedną klasę formularz
  • dla każdego modułu projektuję formularz i zapisuję go katalogu 'forms'. Ścieżka wygląda np. tak /modules/nazwa_modułu/forms/nazwa_formularza.php
  • klasa formularza posiada metodę getForm(par1, par2), która pobiera dwa parametry: nazwę modułu i nazwę formularza.
  • klasa odczytuje formularz z katalogu modułu i wstawia go na stronę
  • Resztę powinienem jeszcze dziś opracować :-)
W tym miejscu drobna uwaga - do swojego frameworka można dodać edytor formularzy, który ułatwiłby ich tworzenie - po to między innymi jest framework.

A teraz klasa baza_osob.
Projektując klasy staraj się pisać konstruktory klas tak, abyś mógł utworzyć obiekt bez podawania parametrów (coś jakby konstruktor domyślny w językach java, c++). Co mam na myśli?

Metody klasy baza_osob:
  • public function __construct() - w konstruktorze odczytaj zapisane już gdzieś imiona i nazwiska (plik, baza danych) do prywatnej tablicy z osobami.
  • public function addPerson($par_imie, $par_nazwisko) - tą metodę może wykonać obiekt formularza gdy odczyta poprawne imię i nazwisko z pól formularza.
  • public function getAllPerson() - tą metodą możesz pobrać zapisane już w bazie osoby
to wszystko. Sorry za angielski w nazewnictwie - ale lepiej się przyzwyczajać - manual jest po angielsku :-)

O ilość klas się nie martw. 4 to bardzo mało. Funkcjonalne aplikacje posiadają ich naprawdę dużo, dużo więcej.

Pozdrawiam
Cysiaczek
No tak, profil użytkownika to może być np. 15 klas + kilka pomocniczych smile.gif
Polik
Ok, z waszych postow wywnioskowalem, ze musze zaczac korzystac z frameworkow. Z reszta sam uwazam ze aby isc do przodu poznanie ich jest nieuniknione. Swojego napewno nie bede pisal smile.gif

To takie moje ostatnie pytanie: jaki FW polecacie. Najlepiej zeby nie byl to super wypas, ktory ma mase mozliwosci w ktorych sie od razu pogubie. Taki jakis srednio zaawansowany na poczatek smile.gif

i dzieki za "obiektowe" rady. Teraz wiem juz wiecej smile.gif

Pozdrawiam!
phpion
Cytat(Polik @ 29.11.2008, 19:57:07 ) *
To takie moje ostatnie pytanie: jaki FW polecacie. Najlepiej zeby nie byl to super wypas, ktory ma mase mozliwosci w ktorych sie od razu pogubie. Taki jakis srednio zaawansowany na poczatek smile.gif

O wyborze frameworka jest osobny temat. Miałem styczność z kilkoma: od Code Igniter, przez Kohana, następnie chwila z Zend Framework, następnie Symfony. Każdy z nich jest zupełnie inny (poza CI oraz K). Ja ostatecznie wybrałem Kohana ze względu na prostotę, spore możliwości oraz szybkość działania. Polecałbym Ci właśnie ten framework.
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.