Spawn Framework – piszemy pierwszą aplikację

W poprzednim wpisie przedstawiłem oraz omówiłem podstawy Spawn Framework. Dziś postaram się zaprezentować jak stworzyć swoją pierwszą aplikację w tym frameworku. Omówimy dokładniej wzorzec MVC, oraz przyjrzymy się podstawowym klasom jakie dostarcza nam Spawn.

Zacznijmy od skonfigurowania bazy danych dla ORM. Aby w pełni skonfigurować bazę do pracy z ORM musimy wykonać dwie czynności:

W pliku Database.php znajdującym się w katalogu Bin/Config aktualizujemy dane dotyczące nazwy bazy, użytkownika oraz jego hasła. Są to dane które zostaną dostarczone silnikowi PDO na którym opierają się klasy spawna.

Kolejnym krokiem będzie wywołanie połączenia bazy, oraz jego rejestracja umożliwiająca dostęp do bazy z dowolnego modelu. Aby tego dokonać otwieramy plik bootstrap.php znajdujący się w katalogu Application, oraz tworzymy blok odpowiedzialny za połączenie z bazą:

Powyższy kod wykorzysta klasę \Spawn\Db\Manager do zapamiętania połączenia.

Na koniec stwórzmy tablicę dla przykładowego systemu newsów:

MVC – model, widok, kontroler

Zajmijmy się teraz stworzeniem pierwszej strony. Aby stworzyć stronę potrzebujemy kontrolera oraz akcji która zwróci widok. Każdy kontroler dzieli się na akcje, czyli podstrony naszej aplikacji. Kontrolerem jest klasa, zaś akcjami metody kończące się wyrazem Action.

Jak pisałem w poprzednim wpisie główne katalogi programu mieszczą się w katalogu Application. Zacznijmy od stworzenia głównego kontrolera Home. W tym celu w katalogu Application/Controller tworzymy plik Home.php z kodem podanym w listingu:

Powyższy kod załaduje layout index.phtml oraz wczyta do niego widok o nazwie akcji, w tym wypadku będzie to Home/index.phtml. Stwórzmy przykładowy plik layoutu oraz treści strony w katalogu Application/View.
Plik index.phtml:

Oraz plik treści strony w katalogu View/Home

Jako ostatnią czynność przed odpaleniem strony w przeglądarce ustawimy kontroler Home jako domyślny kontroler. Zmiany domyślnego kontrolera oraz akcji należy dokonać w pliku index.php.
Ustalmy nową wartość dla parametru controller:

Wejdźmy teraz w przeglądarce pod adres 127.0.0.1 gdzie znajduje się nasza strona, aby zobaczyć wynik pracy:
spawn_wpis_2_screen_1

To tyle jeśli chodzi o podstawy pracy z kontrolerem i widokiem. Zajmijmy się teraz włączeniem do naszej aplikacji logiki odpowiedzialnej za pracę z bazą danych. Aby się nie przepracować wspomożemy się klasą ORM która przy pierwszym wywołaniu wygeneruje nam model reprezentujący tabelę news.

Stwórzmy nowy kontroler o nazwie News posiadający akcje index oraz read. Akcja index będzie pobierała pięć wpisów z bazy, oraz generowała paginację jeśli wpisów w bazie jest więcej. Akcja read będzie odpowiedzialna za wyświetlenie jednego wpisu. Dokładny opis wykorzystanych klas znajdziemy odpowiednio w tutorialu opisującym zastosowanie ORM oraz Pager.

Stwórzmy pliki widoku index.phtml oraz read.phtml w katalogu View/News. Plik index.phtml odpowiedzialny za wylistowanie artykułów oraz wyświetlenie paginacji:

Plik read.phtml odpowiedzialny za wyświetlenie pojedynczego newsa:

Aby zobaczyć efekt pracy udajmy się pod adres 127.0.0.1/news
spawn_wpis_2_screen_2

Podsumowanie

Po tym artykule posiadasz już podstawową wiedzę na temat pracy z Spawn Framework. Potrafisz skonfigurować framework, tworzyć kontrolery, widoki oraz przeprowadzać proste operacje na bazie danych z wykorzystaniem ORM. W kolejnych dwóch wpisach zostaną omówione możliwości pracy na wielopoziomowych kontrolerach, korzystanie z firewalla oraz autoryzacji, na koniec stworzymy CRUDowy panel admina do zarządzania bazą danych.

Osoby zainteresowane frameworkiem zapraszam na stronę Społeczności.

Programista webdeveloper, miłośnik oraz aktywny działacz open-source, od lat związany z społecznością php.

  • Tomasz Dudzik

    A w czym to jest lepsze od powiedzmy całkiem prostego w nauce Yii? 🙂

    • Tomasz Kowalczyk

      Ba, w czym to jest lepsze od czystego PHP, bo przykład możnaby bez tej całej otoczki zrobić kilka razy lepiej po prostu tworząc obiekt PDO i wyrzucając dane do szablonu np. Twiga.

  • piotrooo

    Trochę za dużo się dzieje w tych akcjach kontrolerów. Zamiast ustawiania tam wszystkich ORM’ów, pagerów, etc. powinien być stworzony osobny ViewObject, który dostawałby dane z kontrolera, robił wyżej wspomniane akcje i był przekazywany do widoku. A tak to kontroler robi wszystko.

    • Spawnm

      Ty tak na serio?! Rozumiem że to jedna z tych wariacji typu chudy kontroler gruby model? Podziękuję za takie rady, wiem do czego dążysz ale nie w tym przypadku i nie w ten sposób 😉

      • piotrooo

        Nie gruby model, tylko dodatkowa warstwa pośrednia pomiędzy persystencją a dodawaniem dodatkowych komponetów (np.: pagerów), bo dlaczego to kontroler powinien ustawiać klasę pagera?

        • Potfur

          A dlaczego nie powinien?

          • thejw23

            ViewModel jest dobry bo pozwala wydzielić logikę związaną z widokiem (np. parsowanie danych, ustawianie zmiennych itd) z kontrolera, bo na pewno to nie jest jego rola. Jak uznać, że kontroler odpowiada za request to można dojść do wniosku, że samo ustawianie paginacji też może powinno być w innym miejscu – np. ze względu na SRP z SOLID. To są jednak tematy na które każdy ma swoje zdanie, nie da się nikogo przekonać do swoich racji, punkty widzenia są różne, wioski również – i dobrze, zawsze jest o czym porozmawiać. Ja się skłaniam do np. ViewModel i tam ustawiania paginacji – w skrócie: baby na traktory, a kontrolery do requestów 😉

          • Potfur

            IMHO
            Widok powinien być możliwie jak najchudszy, tylko prezentacja: formatowanie, układanie itd.

            Stronicowanie nie jest formatowaniem a filtrowaniem (zmienia ilość a nie format), więc może być w kontrolerze.

            Klasa pagera generuje/udostępnia jedynie interfejs pozwalający na zmianę ustawień filtru stronicowania. Sposób prezentacji interfejsu zależy od widoku.

          • thejw23

            Właśnie taki jest cel ViewModel (czy ViewObject, jak zwał, tak zwał) – parsowanie, obrabianie, przypisywanie zmiennych itd, po to aby widok nic nie robił innego niż wyświetlanie. Dzięki temu kontroler może zająć się requestem, a model zwracaniem danych. VM odciąża pozostałe elementy. Można w nim dodać ustawianie stronicowania, można wydzielić formularze do osobnych klas i w VM z nimi się bawić zamiast w kontrolerze itd. Jak kto lubi. VM to moim zdaniem sensowny pomysł, niewielkim nakładem pracy pozwala nam lepiej zapanować nad aplikacją.

          • Potfur

            Mamy różne interpretacje widoku.

            Dla mnie widok to nie jest jakiś szablon, bliżej mu do opisywanego przez ciebie ViewObject, który z otrzymanych danych tworzy treść odpowiedzi. Różne widoki, różne treści z tych samych danych : HTML, PDF, PNG, JSON itp.

            Tym samym, widok nie wyświetla treści. Treść wraca do kontrolera, który decyduje co z nią zrobić.

            Może opakować treść nagłówkami i odesłać jako odpowiedź do przeglądarki, wysłać mailem albo zapisać na dysk… albo wszystko jednocześnie 🙂
            Ergo: kontroler może korzystać z dowolnej ilości widoków.

            W takiej sytuacji ViewModel jest zbędny.

          • thejw23

            Generalnie – teraz to się zgadzam 🙂

        • piotrooo

          Pozwala lepiej zapanować na aplikacją i wtedy można mówić o SRP, bo jakie jest SRP dla modelu który ustawia paginator i robi operacje na modelu. Powinno się to przekazać do niższej warstwy.

          @thejw23 Mówisz że każdy ma swoje zdanie na taki temat. Uważam to za błędny wniosek bo można coś robić co jest zgodnie z jakimiś regułami (patternami) a można walić wszędzie haki i robić workaround’y. Jeśli ma być single responsibility to nie można mówić o poprawnym zastosowaniu się do tego gdy ustawiamy miliard rzeczy w kontrolerze i mówimy, że model jest gruby.

      • Riu

        Można wykryć istnienie parametru odpowiadającej za porcjowanie/paginacje i włączać go przed kontrolerem – serwis wywoływany w widoku jeśli posiada jakąś wartość. Ma to sens i wcale nie musi oznaczać grubego modelu. Zaleta? Jeśli masz wiele takich stron z paginacją to za każdym razem w akcji nie musisz powtarzać pewnych rzeczy, a jedynie wstrzykujesz jeśli chcesz jakieś wartości do tej paginacji (np. zmieniasz limit na stronę, albo zmieniasz widok paginacji).

        • Potfur

          Przeniosłeś powtórzenie do innej warstwy 🙂
          To co opisałeś można z powodzeniem realizować w kontrolerze, upraszczając widok.

          • piotrooo

            Oczywiście że nie można, nie od tego jest kontroler.

          • Potfur

            Rzeczowy kontrargument: a właśnie że tak.

          • piotrooo

            Skoro argument „nie od tego jest kontroler” nie jest rzeczowy to nie wiem co było by wstanie Cie przekonać.

          • Potfur

            Argumentacja była by.
            Opinia, nie jest argumentem.

          • norzechowicz

            Abstrahując od tego konkretnego przypadku polecam posiedzieć trochę nad narzędziem PHPSpec2. Kontroler to zwykła klasa w tym przypadku i tak też ma być traktowana.
            Autorowi frameworka też by to nie zaszkodziło bo coś takiego https://github.com/Spawnm/Spawn-Framework/blob/master/Library/Spawn/Orm.php#L475 to jedno wielkie nieporozumienie.

          • Spawnm

            Wiem, ta metoda będzie wydzielona jako osobne 3 klasy do generowania modeli orm/form/valid.

          • Riu

            W widoku wypluwamy tylko rezultat, a realizowane to jest przed kontrolerem jako zdarzenie. Ostatnio pisząc o naszych fw podałeś przykład autoryzacji która dzieje się zanim dojdzie do odpalenia kontrolera i paginacja może być bardzo podobnym przykładem.

          • Potfur

            IMHO nie powinno. Kontroler może mieć logikę modyfikującą/niwelującą parametr stronicowania.

            Autoryzacja jest trochę wyżej niż kontroler 🙂

          • Riu

            A co ja we wcześniejszym komentarzu napisałem? Że co można w kontrolerze 🙂 ?

          • Potfur

            Źle ująłem. Parametr stronicowania przed kontrolerem jest tylko jakąś tam zmienną. Kontroler dopiero nadaje jej kontekst, określa jej wykorzystanie.
            To się może dziać w ramach widoku, ale nie przed czy po kontrolerze.
            Wszystko to oczywiście IMHO

  • norzechowicz

    Uhm jakoś nie szczególnie przekonuje mnie „framework” bez ani jednego testu, nawet jeżeli miałbym traktować go w kategorii „mikro”.

  • Tadeusz

    Dla początkujących – jeśli masz projekt w podkatalogu – pamietaj o ściężkach do css i js.

  • OstatniLogin

    W tej mikro dyskusji brakowało mi tylko „argumentu” z zapytaniem „gdzie jest composer?!” 😀

    Niepokoi mnie sytuacja w której pieczołowite trzymanie się pierdół w postaci testów, chwilowych trendów w kodzeniu błędnie uznawanych za wyznacznik i kurczowe trzymanie się określonych wzorców projektowych przyćmiewa sens tworzenia aplikacji i całą ich logikę powstania.

    Wiecie, że w programowaniu chodzi głównie o swój własny styl? To, że 30 osób wymyśliło 100 rzeczy, nie znaczy że trzeba z nich korzystać, to tylko wytyczne które mogą być użyte, ale nie muszą bo są albo dobre, albo kompletnie wyssane z palca i aż wstyd tego użyć.

    A tu jak zwykle spina, bo nie ma tego i tamtego jakby ORM czy testy były jakimkolwiek wyznacznikiem. Cały świat odchodzi o nakładek w postaci ORMów, bo zwyczajnie do małych projektów się nie opłacają, a do dużych tym bardziej, ale nie… ORM! ORM! ORM!

    • thejw23

      ORM – jak każda biblioteka/wzorzec ma swoje zastosowanie i nie jest z gruntu zła, ani dobra. Trzeba wiedzieć jak i kiedy z niej korzystać.

      A co do reszty… Tak z 5 lat temu zapewne wiele osób by się z Tobą zgodziło, ale teraz… 😉

      • OstatniLogin

        Za kolejne 5, nikt nie będzie pamiętał o nich a raczej o tym przy czym się upierają 😉

        • thejw23

          Design Patterns: Elements of Reusable Object-Oriented Software – wydane w 1994. Extreme Programming Explained – wydane w 1999. Patterns of Enterprise Application Architecture – wydane w 2003. Nadal aktualne. I tak można jeszcze wyliczać. Stopniowo zostało to docenione w np. Javie, Nie tak dawno w PHP (bo PHP dorosło do tego). I w tą stronę PHP idzie, odchodzi od „w programowaniu chodzi głównie o swój własny styl” bo… nie o to chodzi 🙂 Wzorce to nie dekalog – to pokazanie jak coś można zrobić. Jeśli chcesz zrobić to inaczej – proszę, nikt nie zabrania. Ale dobrze znać już przetarte szlaki, aby nie tracić czasu na wymyślanie koła na nowo. Trochę mi ten tekst o własnym stylu przypomina niedawno przeczytaną odpowiedź na pytanie czy JS potrzebuje coding style https://github.com/airbnb/javascript/issues/102 😉 Generalizując – im większe projekty robisz i w większym teamie pracujesz, tym bardziej doceniasz wzorce, SOLID, coding style i inne takie „pierdoły”.

  • trollo

    Przydałby się w następnej części lub dopisanie tutaj, poradnik jak zorganizować aplikację w podkatalogach, np. admin i front 🙂

    • Spawnm

      Właśnie w kolejnym wpisie o tym będzie, przy okazji omówienia firewalli i autoryzacji 😉

  • creomax

    http://spawnframework.com/learn/page/3.html – mamy tam zapisane: „Aby ustawić własny kontroler startowy należy otworzyć plik index.php, oraz przejść do linijek:

    Pierwsza z linijek jest nazwą klasy kontrolera którego plik znajduje się w /Apllication/Controller.”. problem w tym, że nie ma takiego pliku w podanej lokalizacji. Tak wiec jeśli to ma być dla żółtodziobów, to raczej ich tylko rozwali.

Send this to a friend

webmastah.weekly
Cotygodniowa porcja linków ze świata WEBDEV BEZ spamu, TYLKO samo mięcho!
Zobacz poprzednie wydania. Dołącz do 2 tysięcy webdeveloperów!
HTML5, CSS3, JS (React, Angular, Ember, Vue), PHP, SQL