Dziś jest sobota, 31 lipca 2010 roku (z kalendarza...)

Yii Framework

Icon

17.02.2010, 12:44

PHP

Komentarze (13)

Powrót

Najpopularniejsze frameworki od kilku miesięcy nie mają u mnie zbyt dobrej opinii głównie za sprawą wciskania ludziom pod nazwą MVC czegoś, co z MVC ma niewiele wspólnego. Znajomy polecił mi jednak ostatnio młody i mało znany w Polsce framework o niecodziennej nazwie Yii, reklamujący się jako wydajna, a przy okazji wciąż funkcjonalna alternatywa dla "kobyłek". Mnie jednak zainteresowała jeszcze jedna rzecz... Od razu uprzedzę, że wpis ten nie jest dokładną analizą, gdyż zacząłem w nim programować raptem półtora tygodnia temu. Zamierzam tu raczej przedstawić moje pierwsze wrażenia.

Framework

Z początku framework wygląda, jak każdy inny. Dostajemy do ręki bibliotekę z klasycznym podziałem na kontrolery, akcje i widokoszablony, Active Record, system formularzy, generator kodu oraz inne rzeczy, których moglibyśmy oczekiwać. Siadamy, na podstawie tutoriala generujemy parę modeli oraz szkielet aplikacji CRUD, po czym wypełniamy go resztą. Gdy ujrzymy pierwsze kawałki wygenerowanego kodu, odkryjemy pewną ciekawą rzecz. Jakiś czas temu pisałem, że nie ma frameworka PHP, który pod nazwą MVC faktycznie udostępnia MVC. Okazuje się, że nie do końca. Autorzy Yii jako jedyni chyba spojrzeli na diagram tego wzorca, co zresztą widać w dokumentacji pokazującej, że między widokiem i modelem zachodzi bezpośrednia komunikacja. Nie jest to uwzględnione bezpośrednio w API, lecz realizowane za pośrednictwem rozmaitych widgetów. Przyjrzyjmy się jednej z akcji w wygenerowanym kontrolerze CRUD:

public function actionAdmin()
{
	$dataProvider=new CActiveDataProvider('Category', array(
		'pagination'=>array(
			'pageSize'=>self::PAGE_SIZE,
		),
	));
 
	$this->render('admin',array(
		'dataProvider'=>$dataProvider,
	));
}

Wyświetlenie listy wierszy z bazy zazwyczaj wymaga korzystania ze stronicowania, sortowania danych po kolumnach oraz innych bajerów. W innych frameworkach cały ten kod ląduje w kontrolerze, a żeby było śmieszniej, niektóre frameworki nawet nie generują kodu z obsługą nawet najprostszych bajerków. Oznacza to, że jeśli chcemy dodać sobie w końcu stronicowanie, musimy jak idioci poprawić każdy kontroler z osobna. Nie jest to ani produktywne, ani zgodne z filozofią projektowania aplikacji. Tymczasem w Yii musimy jedynie stworzyć obiekt CActiveDataProvider, który odpowiednio opakowuje odpowiedni model, a w szablonie odpalić CRUD-owy widget:

<?php $this->widget('zii.widgets.grid.CGridView', array(
	'dataProvider'=>$dataProvider,
	'columns'=>array(
		'id',
		'title',
		'body',
		'productNum',
		array(
			'class'=>'CButtonColumn',
		),
	),
)); ?>

Jeśli stwierdzimy, że część akcji musi jednak inaczej to wyświetlać, po prostu piszemy własny widget CRUD i podmieniamy go, co jest o wiele szybsze i pozwala uniknąć wielu błędów.

Dodatkowe biblioteki

Składanie aplikacji z generowanych kontrolerów jest bardzo szybkie. Yii automatycznie zabudowuje w nich szkielet mechanizmu uprawnień, który można bardzo prosto dostosować do własnych potrzeb, a także generuje wszystkie potrzebne pliki. Wiele elementów udostępnionych jest jako modele, dzięki czemu ich obsługa jest w miarę jednolita. Podstawowymi rodzajami modeli są CActiveRecord oraz CForm. Pierwszy z nich reprezentuje oczywiście wiersz tabeli z bazy danych oraz posiada wbudowaną funkcjonalność formularza do zarządzania nim. Drugi pozwala tworzyć swobodne formularze, niezwiązane z konkretnym bytem (np. logowanie). Jeżeli tworzymy aplikację wielojęzyczną, możemy wykorzystać system tłumaczeń posiadający wbudowaną obsługę formatowania warunkowego. Poniżej pokazany jest przykład zastosowania:

Yii::t('kategoria', '1#W bazie jest jedna książka|n>1&&n<5#W bazie są {n} książki|n>4#W bazie jest {n} książek',
array('{n}' => $number));

Wiele innych bibliotek można sobie doinstalować dzięki obszernej bazie rozszerzeń.

The Zyxist Kustomizer

Oczywiście jak to z frameworkami bywa, pierwszą rzeczą, którą na nich próbuję zrobić, jest coś, co je dokumentnie zagina. Yii sprawdza się świetnie przy tworzeniu aplikacji CRUD oraz stron o sztywnej, w miarę ustalonej strukturze, którą można zapisać na sztywno w kodzie (portal, aplikacja bazodanowa). Aplikację możemy dodatkowo podzielić na moduły posiadające własne kontrolery, widoki, modele oraz komponenty, jednak schody zaczynają się, gdy spróbujemy zbudować na nim konfigurowalną aplikację CMS. Tego typu projekt wymusza trochę inne działanie aplikacji, które niezbyt przystaje do sztywnego podziału na kontrolery i akcje. Tutaj kontroler musi załadować informacje z bazy, odnaleźć odpowiednie moduły, przekazać im sterowanie, a następnie odebrać wynik. Oczywiście nie można mieć wszystkiego, zatem siadłem sobie i stwierdziłem, że napiszę własny kontroler bazowy rozszerzający klasę CBaseController dostosowany do takiej konfigurowalnej struktury modułowej. Zaczęło być wesoło, gdy zorientowałem się, że wraz z tą klasą dostaję cały pakiet zupełnie niepotrzebnych mi metod do zarządzania... renderowaniem, osadzaniem widgetów, buforowaniem kodu HTML itd. I to jest kolejny z powodów, dla którego jestem wrogiem redukowania warstwy widoku do szablonów.

Jest jeszcze jedna mała niedogodność. Framework powstał za czasów PHP 5.2, przez co dubluje trochę funkcjonalności, która pojawiła się w wersji 5.3. Mowa tu o strukturach danych oraz o formatowaniu warunkowym w systemie tłumaczeń, które jest też wbudowane w nową bibliotekę Unicode. Ale to już takie czepiactwo pro forma - ciężko wymagać, by autorzy korzystali z czegoś, czego w momencie rozpoczęcia prac jeszcze nie było, a ponadto trzeba mieć na uwadze wsteczną kompatybilność.

Podsumowanie

Choć Yii też do końca nie zaspokoił moich wygórowanych wymagań odnośnie MVC, na pewno jest to perełka pośród frameworków, gdyż przynajmniej nie wmawia programistom głupot, że cała komunikacja z modelu do widoku musi iść przez kontroler. Do typowych zastosowań niewymagających korzystania z bardziej niskopoziomowego API jest jak znalazł. Warto się z nim zapoznać i zobaczyć czy taki styl pracy nam odpowiada.

Powrót

Komentarze

Napisał Tuner w środę, 17 lutego 2010 o 14:18

Miło, że ktoś bliżej spojrzał na ten framework :)

Napisał giver w środę, 17 lutego 2010 o 14:49

Swego czasu istniał projekt polskiego frameworka Rapide. Co prawda już nie jest rozwijany, ale można znaleźć a internecie informacje na jego temat. On również miał zaimplementowany wg. mnie dobrze wzorzec MVC a szczególnie bezpośrednią komunikację widoku z model. Co prawda nie było to domyślne rozwiązanie, ale był do tego stworzony odpowiedni plugin.

Napisał canni w środę, 17 lutego 2010 o 16:42

Jedna rzecz domyślnie według mnie powiedział bym nawet kolokwialnie "niedorobiona" w Yii...

Domyślny generator modeli wręcz głupieje gdy spróbujemy wygenerować model dla tabeli z bazy, która nie ma zdefiniowanego klucza primary...
By jednak być dokładnym... Yii wygeneruje nam szablon pliku klasy, natomiast nie poradzi sobie z generowanymi z automatu validatorami i innymi perdółkami, które trzeba sobie potem dopisać.

Komuś może nie przeszkadzać, mnie irytuje dość mocno...

Druga rzecz...
Twórcy Yii uparli się by stricte przestrzegać swojej konwencji nazewnictwa plików klas, i trzeba modyfikacji klasy YiiBase, by autoloader sobie poradził z ładowaniem klas utrzymanych w Zend'owym stylu nazewnictwa
Oczywiście można sobie załadować autoloader z biblioteki której używamy, ale na przykładzie lib PHPExcel, który nie dostarcza autoloadera, a korzysta z konwencji Zend'owego nazewnictwa klas/katalogów, musiałem prze-edytować autoloader, po co pisać nowy, jak domyślny po dodaniu 2 linijek kodu sobie poradzi z wszystkimi przypadkami zend'owego zazewnictwa (łącznie z całym Zend lib)?

Napisał Sin w środę, 17 lutego 2010 o 17:47

No i jest bardzo szybko według testów które można było kiedyś na stronie tego frameworka znaleźć a które oczywiście jak są potrzebne na szybko gdzieś się pochowały ;) Mnie osobiście nie bardzo podobało się routowanie (na marginesie router dostępny jest jako oddzielny projekt), jakiś tam błąd w nim od razu wyłapałem. Ale to było już jakiś czas temu, być może poprawili.

Napisał itako w czwartek, 18 lutego 2010 o 00:08

zyxusiu, uczepiłeś się tego MVC niesamowicie (z resztą zauważyłem, że lubisz się czepiać popularnych i dobrych rozwiązań - tak samo ze Smarty. Zazdrość? :) )
MVC to teoria, jak zostanie zaimplementowany jest inną sprawą.
Liczy się:
a)ogólne rozdzielenie kodu na części odpowiadające za poszczególne role MVC
b)to, czy framework oparty o MVC będzie po prostu sprawny

Są to rzeczy, które zostały wymuszone przez rynek profesjonalnych (w sensie pracujących) developerów, gdzie liczy się przede wszystkim czas i wygoda, a nie to, czy stronicowanie walniemy w kontrolerze, czy widoku (chociaż zależy co rozumiemy pod pojęciem paginacji - konfiguracja? wyświetlanie? Bo jak dla mnie w symfony jest to bardzo dobrze zaimplementowane).

W skrócie: mnie nie interesuje, czy framework jest w 100% zgodny z założeniami MVC. Interesuje mnie czy jest sensownie podzielony na część prezentacji, kontrolerów i modelu, oraz czy szybko mogę na nim postawić projekt i za rok nie mieć problemu z jego edycją i odnalezieniem poszczególnym fragmentów kodu.

A jeśli już będziesz odpowiadał na ten koment - co nam da "bezpośrednie połączenie" widoku i modelu?
W symfony i tak to można bez problemu osiągnąć, ale jak na moje oko to tylko zmniejsza czytelność layoutu - i być może tutaj jest pies pogrzebany?

Napisał Zyx w czwartek, 18 lutego 2010 o 07:36

No wybacz, ale jeśli naprawdę uważasz, że tak archaiczny, źle zaprojektowany i zrobiony bez żadnego zastanowienia się nad sensem skrypt, jak Smarty jest dobry, to chyba nie mamy o czym rozmawiać. Nie widzę żadnej innowacyjności w tym, że zamiast <?php piszę { i to samo robię tak samo, tylko przy pomocy bardziej ezoterycznej składni.

I tak samo jest z MVC. Sam napisałeś - liczy się czas i wygoda, a ja nie widzę żadnego zysku w tym, że robię coś tak samo, jak przed poznaniem MVC, a jedyna różnica polega na tym, że odwołania do bazy nazwano modelem, szablony - widokiem, a całą resztę kontrolerem. A tym bardziej nie lubię, gdy mi się wciska kit, nawet w słusznej sprawie. Przecież nikt nad nimi nie stał z batem, wrzeszcząc: "k***, nazwijcie to MVC!!!". Skoro nie robią MVC, niech nie nazywają tego wynalazku MVC i tyle, tym bardziej że ma on swoją fachową nazwę MVP.

Ad. ostatniego pytania -> odsyłam do stosownego wpisu na tym blogu poświęconego wzorcowi MVC, a także do jego nieco bardziej rozbudowanego tłumaczenia w wersji angielskiej. Pracowałem z prawdziwym wzorcem MVC i uważam, że ma to dużo większy potencjał, niż MVP.

Napisał Egz w czwartek, 18 lutego 2010 o 11:33

Wyczuwam próbę narzucenia własnego spojrzenia na wzorce - co z miejsca dyskwalifikuje takie podejście jako poprawne w świetle dowolnej implementacji wzorców.

Ilu developerów, tyle implementacji MVC, starasz się jakoś na chama przepchnąć swoją, tak aby inni uważali ją za jedyną słuszną.

Bzdura i tyle. Sprawa ma się podobnie do porównania smarty z plain php... A przepraszam bardzo co robi OPT? Jakoś tak trochę niesmacznie wygląda ten wpis.

Napisał Tomasz Kowalczyk w czwartek, 18 lutego 2010 o 14:44

Fajnie, że napisałeś o Yii, bo zamierzam się właśnie zabrać za niego - symfony jest ok, ale tak jak wspomniałeś - to trochę za duża "kobyła" na dłuższą metę.

Napisał Zyx w czwartek, 18 lutego 2010 o 16:44

Egz -> nie przypominam sobie, bym kiedykolwiek publikował jakąś implementację MVC, więc co niby mam "przepychać"? Nie mam w tym absolutnie żadnego interesu poza tym, że czuję się lekko oszukany. Moim zdaniem mam prawo oczekiwać, że pod słowami "implementujemy wzorzec XXX" znajdę faktycznie wzorzec XXX, a nie DGB. Dla Ciebie wywalenie z wzorca jednego z założeń to nic takiego. Dla mnie to potężne odstępstwo, które może znacząco zmienić właściwości wzorca, zupełnie jakby np. dekorator pozbawić możliwości dekorowania. Tak w ogóle to o MVC kilka miesięcy temu był wpis i tam zapraszam do dyskusji, bo zbaczamy mocno z tematu.

Ad. OPT -> zapraszam do poczytania tego i owego o systemach szablonów i samym OPT. OPT i PHPTAL to przedstawiciele naprawdę nielicznej rodziny systemów szablonów, których celem nie jest reimplementacja podzbioru PHP i nic więcej.

Napisał bigZbig w sobotę, 20 lutego 2010 o 18:46

Zadajmy sobie pytanie czym jest właściwie Widok, czym Model, a czym Kontroler.

W niektórych definicjach model sprowadzony jest do źródła danych, w innych zalicza się do niego również narzędzia dostępu do danych. Niektórzy uważają, że Kontrolery to przyciski w aplikacji umożliwiające sterowanie nią, reszta wyświetlana na ekranie to Widok, a cała reszta to Model, inni z kolei zaliczają do Kontrolera całą logikę aplikacji w tym np. podział wyników na strony.

Pora przejść do Widoku. Czy widget paginatora w Yii zaliczyłbyś do Modelu czy do Widoku? A widget Formularza + cały proces jego obsługi łączenie z walidacją to Widok, Kontroler a może Model? Zend_Form można zdefiniować podobnie jak Zend_Table i potraktować jak model - dodaje się do niego validatory i dekoratory powodujące, że wyświetla się on w postaci np. listy definicji. W Kohana Framework "formo" definiuje się w kontrolerze ale ma swoje szablony - szybko łatwo i przyjemnie. A w OPT? Czy w OPT formularze to tylko zbiór kontrolek czy też ma jakieś zintegrowane mechanizmy do obsługi formularza? Jeśli ma to czy OPT należy do warstwy Widoku czy też wychyla się poza narzucone granice?

Cały ten mój wywód służy poparciu trzech tez.
1. Granice między Modelem, Widokiem i Kontrolerem są niejednoznaczne.
2. Model, Widok i Kontroler przenikają się wzajemnie.
3. Odstępstwa od wzorca są dopuszczalne, jeśli czynią pracę łatwiejszą.

Napisał Adam w sobotę, 6 marca 2010 o 12:37

MVC nie bardzo pasuje do web ale taki jeden framework wziął sobie 3 literki, a potem cała masa innych to skopiowała.

Wspomnienie o "właściwym MVC" zawsze zaognia dyskusję, IMHO trzeba przeczekać i dać wypłynąć nowszym modelom architektonicznym, np. Naked Objects, Event Driven, SOA, DI, etc.

Napisał deallas w środę, 10 marca 2010 o 22:06

Myślę, że żaden framework napisany w PHP nie ważne czy to ZF, Symfony czy Yii nie będzie szybszy od tych napisanych w Pythonie czy Javie z dwóch przyczyn. Pierwsza oczywista - PHP jest wyraźnie wolniejszy od Javy czy Pythona. Druga przyczyna to każdorazowe wczytywanie tych samych danych, zadań (loadery itp) przy każdym wywołaniu. A przecież można by było zmienić koncepcję wprowadzając podobną jak w servletach, że na samym początku wczytywane byłyby wszystkie dane konfiguracyjne, tworzone byłoby połączenia z bazami itd. Udało mi się nawet stworzyć prosty serwer aplikacyjny dla ZF dzięki któremu zyskałem 5x większą wydajność (z 45req do 250req) przy prostym "Hello world". Jedyne co zrobiłem to forkowałem 15 oddzielnych procesów, który każdy z nich na początku miał w pamięci wszystkie dane konfiguracyjne oraz klasy ZF. Myślę że ten rezultat dałoby się co najmniej podwoić jakby przystosować odpowiednio ZF do pracy z wątkami jak i sam język PHP. Zend mógłby w końcu zrobić coś w tym kierunku. Posiadają przecież własny serwer, frameworka no i oczywiście mają ogromny wpływ na to co się dzieje z PHP

Napisał thejw23 w wtorek, 16 marca 2010 o 21:25

MVC to cos jak analiza wiersza na polskim - kazdy ma swoja wizje, a i tak autor mial na mysli cos innego ;)

jesli tylko jest to spojne w calej aplikacji to ja bym sie nie czepial o interpretacje - oczywiscie pomijam takie rzeczy jak tworzenie obiektu ORM w widoku. chodzi mi raczej o walidacje (M vs C) czy upload pliku (M vs C vs Helper). bigZbig ladnie to podsumowal w 3 punktach.

yii nie znam, aczkolwiek poznam.


Pamiętaj, dbaj o kulturę wypowiedzi oraz dyskusji w sieci.

Skomentuj

NickInformacja
E-mailNa wypadek potrzeby kontaktu z autorem (niepublikowany)
BlogNie zapomnij o http://
LayoutNapisz tu, czy widzisz dzienny czy nocny layout.
WpisFormatowanie wikiKomentarze są moderowane - przeczytaj zasady!

Na Zyxist.com panuje swoboda wyrażania opinii oraz krytyki pod dowolnym adresem. Jedyny warunek: musi być ona kulturalna i rzeczowa. Na chamstwo, prostactwo lub jawne obrażanie kogokolwiek nie ma tu miejsca i takie komentarze są bardzo szybko usuwane. Jeśli zamierzasz polemizować z treścią wpisu, wpierw uważnie ją przeczytaj.

© Tomasz "Zyx" Jędrzejewski 2005 - 2010 | Wykonanych zapytań: 2 | Serwer wirtualny zapewnia