Some of posts from this blog has been moved to dywicki.pl. You will be automatically redirected to new blog if you would submit comment.
New posts are published on dywicki.pl, this blog contains old content and it is not continued.

Niektóre posty z tego bloga zostały przeniesione do dywicki.pl. Zostaniesz automatycznie przekierowany jeśli bedzięsz chciał dodać komentarz.
Nowe posty sa publikowane na dywicki.pl, ten blog zawiera stare treści i nie jest kontynuowany.

O::ptimization

Filed under PHP by

Jako, że prace nad frameworkiem troszkę się posunęły (doszło uruchamianie akcji) postanowiłem sprawdzić ile czasu zajmuje jedno ządanie. Jakież było moje zaskoczenie, gdy mym oczom ukazał się czas ponad 1 sekundy. Szybko sobie jednak przypomiałem, że autoloader jest do wymiany. Przebudowałem stary tak, aby współpracował z tokenizerem beli. Zmiana – względem poprzedniego czasu – znaczna. Czas spadł do około 0.2 s. Kilka poprawek i zszedłem poniżej – teraz czas jednego rządania wynosi od 0.12 do 0.15 s. Stwierdziłem, że to strasznie długo tym bardziej, że nie ma jeszcze obsługi kilku istotnych rzeczy (FilterChain, Validator, View, ActionForms). Wniosek? Błędy w projekcie. Oto porównanie z innymi skryptami, które udało mi się odanleść na dysku:

Mój framework:
czas od 0.12 do 0.15 – 33 włączone pliki.

Odin:
czas od 0.047 do 0.063 – 23 włączone pliki (w tym Smarty.class.php)

Blog+ (Pinky):
czas od 0.24 do 0.26 – 58 włączonych plików (plus połączenie z MySQL)

Daeron:
czas od 0.92 do 0.96 – 15 włączonych plików (PDO zgłasza wyjątek)

Cake:
czas od 0.11 do 0.14 – 28 włączonych plików (troszkę niedziałająca wersja)

Mojavi 3.0:
czas od 0.16 do 0.23 – 41 włączonych plików (PHPView, bez połączenia z bazą)

Co dziwne – najmniej włączający Daeron okazał się znacznie wolniejszy od reszty. Za to kolejny pod względem liczby dołączanych plików Odin najszybszy. Przypadek? Trudno powiedzieć, ponieważ wszystkie testowane frameworki/aplikacje są w różnym stadium rozwoju. Obrazowo – Odin szybszy od Daerona ponad 19 razy, a od drugiego w testach Cake’a o ponad 2 razy. Stosunek czasów Odina do Blog+ i Mojavi to 5 i 3. Podkreślam, że testy były przeprowadzane manualnie i pomyłki są bardzo prawdopodobne. Testy przeprowadziłem na swoim domowym sprzęcie: Athlon 2000 XP (1.67 Ghz), 768 MB RAM (DDR 400), OS: Windows XP HE, Apache 1.3.33 i PHP 5.1.0 b2 (z PDO i XSL). W tle działały wciąż te same aplikacje.

5 responses so far

Dylematy.

Filed under PHP by

kliknij aby powiększyć Tak to już jest, że coraz większość problemów pojawia się przy detalach… Również i w przypadku tego, co piszę obecnie pojawiła się garść problemów.

Pierwszy problem to zrezygnowanie z buforowania plików konfiguracyjnych. Do operowania na XMLu wykorzystuję XPatha, a ten jest dostępny poprzez DOM bądź SimpleXML. Podejrzewam, że tak czy owak SimpleXML przerzuca swój obiekt do obiektu DOM, żeby wykonać xpath_eval, ale nie jestem w stanie tego udowodnić. Jak wielkie spowolnienie z tego wyniknie? Nie jestem w stanie powiedzieć. Bez buforu konfiguracji jedno żądanie zajmuje około 0.05s. Gdy tworzona jest mapa klas czas ten wzrasta ponad dziesięciokrotnie.

No, ale jakoś sobie poradzę. Mogę tam, gdzie SimpleXML jest konwertowany do tablicy zastosować warunek, który będzie sprawdzał czy w pliku zostały wprowadzone zmiany. Problem drugi to łańcuchy. Kolega z pracy, który wiele pracował ze Strutsem zaproponował, żeby nie implementować łańcuchów tylko obsługę forwardów tak jak w wyżej wymienionym frameworku.

W sumie nie jest to problem, stworzę obiekt ForwardConfig, który będzie wczytywał dane z forwardami lokalnymi i globalnymi dla całego modułu/aplikacji.

Walczyłem również z obsługą Requestu.Tzn. problem pojawił się, gdy postanowiłem rozdzielić odpowiedzialność na dwie klasy. Console oraz Web. Ostatecznie, aby wiedzieć skąd pochodzi zmienna w przypadku korzystania z obiektu WebRequest nadpisałem metodę

Request::getParameter. Teraz przyjmuje dwa argumenty zamiast jednego. Pierwszy to nazwa argumentu, drugito miejse, skąd ma pochodzić zmienna. Jest to numer – odpowiednio 0 dla COOKIE, 1 dla GET, 2 dla POST, 3 dla FILES. Domyślnie drugi argument przyjmuje wartość 1, czyli dane będą pobierane z GETa.

Obecnie cały czas walczę nad skończeniem Controllera. Wtedy będę mógł zająć się klasą ApplicationController, która będzie miała za zadanie obsługiwać moduły.
No a najcięższy kawałek chleba zapowiada się przy XML2Form. Myślę, że za około miesiąc, może 2, gdy całość zacznie jako-tako funkcjonować uwolnię źródła.

Dzisiaj udało mi się również uruchomić SimpleTest. Być może dzisiaj napiszę kilka testów do frameworka. Wczoraj straciłem ponad 2 godziny na próbę uruchomienia Propela. To kurewskie środowisko jest nie do uruchamienia. Tym, bardziej, że bez dostępu do internetu w domu nie mogę ściągnąć wersji z SVN, a bez tego po prostu klapa. Teoretycznie wykonuję wszystko tak jak jest w dokumentacji, ale w praktyce nie są generowane klasy, bo pojawia się wszędobylski błąd ‘Class File not found’. Wg. wskazówek, które są na stronie powinno starczyć tylko dodanie w jednym pliku Phing do linii, ale nie pomaga.

No responses yet

Komentarz na helion.pl

Filed under Ogólne by

Odnośnie książki prezentowanej niżej… :)

Continue Reading »

No responses yet

Po prostu. XML

Filed under Ogólne by

Po prostu?Chciałem Was ostrzec przed nabywaniem czy nawet zbliżaniem się do tego tytułu. Książka zaczyna od omówienia XMLa, którego nie czytałem, bo jak XML wygląda to wiem. Pożyczając tą książkę chciałem lepiej poznać DTD oraz XSD. Pomimo szczerych chęci nie udało się.
Autorka tak pokrętnie wyjaśnia wszytko, że nie sposób to zrozumieć. Z wielkimi trudami przyswoiłem wiadomości o DTD, podobnie jak o XSL, ale XSD to męka.. nie wiem, może to zmęczenie po pracy działa na mnie tak otępiająco? Chyba nie, bo komentarze na helionie też nie są zbyt pochlebne. W każdym razie, czekam na kolejną pozycję o XMLu którą, będę miał pożyczoną – mianowicie “XML. Na poważnie”, która zapowiada się świetnie. Jutro to zweryfikuję. Tym czasem powracam do bojów z Propelem i PHPUnit.
// właśnie mam przed sobą XML na poważnie, za gruba to ona nie jest, ale zobaczymy co ciekawego piszą o XMLu :)

Linki do plików:
config.xml
test.dtd
test.xsl

Continue Reading »

3 responses so far

Garść informacji ;)

Filed under PHP by

Planowałem to zrobić wcześniej, ale dopiero świadectwo Beli mnie ostatecznie zmotywowało :). Byłem pozytywnie zakoczony tym, że jeszcze ktoś mnie odwiedza…

katalogi... Obok prezentuję struktóre katalogów. Myślę, że jest ona dośćprzejrzysta, można powiedzieć zapożyczona z Mojavi.
Troszkę może Was dziwić tak wielkie rozbicie konfiguracji, ale jest to zamierzone, moim zdaniem łatwiej się pracuje w takim rozdrobnieniu, ponieważ każdy moduł posiada oddzielnąkonfigurację i może mieć zgoła inne parametry. W kataloguWebApp znajdują się ustawienia globalne takie jak dostęp do bazy danych oraz zdefiniowane moduły + pluginy, czyli klasy które można zastąpić (rozwiązanie Beli z Odina).
WebApp/Config.php zawiera definicje ścieżek.
WebApp/Modules/Default/config.xml to definicja akcji, jakie znajdują się w module oraz obsługę błędów (404,403,500);
WebApp/Modules/Config/ActionName.xml zawiera szczegółowe dane takie jak używane filtry i akcje odpalane w stosie (można to nazwać blokami). Zastanawiam się czy implementować coś takiego jak Bela – fallbacki, dla tych akcji które zwróciły fałsz.
Gdyby trafiły się jakieś pytania odnośnie katalogów i ich zawartości piszcie.
Teraz garść informacji o tym, jak całość ma być zorganizowana.
Zgodnie z tym, co pisałem na forum.php.pl zaimplementuję łańcuchy akcji, czyli możliwość uruchamiania kilku akcji połączonych w logiczną całość.Będzie to przypominało kreatory na kształt tych, które są w Prado. Przykład takiego łańcucha dla dodawania nowego użytkownika:
Wpisz token -> Podaj dane -> Wpisz kod aktywacyjny Nie ma możliwości odpalenia akcji “Podaj dane” poza stosem. Podobnie jak “kod aktywacyjny” jest dostępna tylko po przejściu wcześniejszego ogniwa. Zainteresowanych zapraszam do zapoznania się z tematem na forum.
Na akcję składać będą się różne obiekty.
Action – warstwa logincza
ActionForm – część warstwy prezentacyjnej, interfejs XML2Form
ActionValidator – filtr sprawdzający poprawność danych
ActionErrors – lista błędów, które zostały wygenerowane poprzez wcześniejsze elementy
Obiekt ActionErrors zawiera obiekty ActionError, które umożliwiają internacjonalizację na poziomie walidacji formularzy. ;)
W temacie na forum wspominałem o beanach, ale nie pisałem jak planuję to rozwiązać. Do użytkownika będzie docierać tylko FormBean więc łatwo załatwić to poprzez dodanie hiddena z jego nazwą. Podczas, gdy na serwerze wciąż będzie kopia użytkownik będzie miał do dyspozycji swój egzemplarz, który będzie mógł modyfikować.
Akcja będzie mogła samodzielnie sprawdzać dane (podobnie jak w Strutsie i Mojavi) poprzez metodę Action::validate(). Gdy metoda ta zwróci fałsz nie dojdzie do uruchomienia metody Action::run(). Zostanie wyświetlona poprzednia akcja razem z błędami, które powinny znajdować się już w obiekcie ActionErrors. Gdy walidacja przebiegnie pomyślnie zostanie uruchomiona warstwa logiczna. Jeśli metoda Action::run() zwróci fałsz zostanie cofnięta transakcja uruchomiona poprzez kontroler (ROLLBACK). Akcja może zawierać również metodę finalize, która jest uruchamiana tylko po pomyślnym zakończeniu tranzakcji (COMMIT). Jeśli akcja znajduje się w łańcuchu to metoda finlize nie jest wykorzystywana. Jest ona uruchamiana dopiero w ostatniej akcji, czyli jak we wcześniejszym przykładzie po poprawnym wpisaniu kodu aktywacyjnego.

ActionForm
Jak wcześniej pisałem jest to interfejs do obsługi formularzy. Jeśli pojawią się błędy ActionForm powinien samodzielnie podświetlić pola i dodać komunikaty o błędach.
W ustawieniach odnośnie formularzy można zdefiniować czy formularz może być wysłany kilkakrotnie (blokada post-backu). Jeśli istnieje potrzeba blokady ponownego wysłania danych to do formularza jest dodawany hidden z losowym tokenem, który równocześnie jest zapisywany w sesji.
ActionForm to klasa uniwesalna, zawsze jest wykorzystywany tylko jeden egzemplarz/byt.

XML2Form
Jest to bardzo ważny elementcałego systemu. Klasa XML2Form zawiera obiekty elementów, beany oraz obiekt klasy XML2FormLayout. Po dodaniu do obiektu XML2Form beana trafia on do odpowiedniego elementu, który powinien samodzielnie zmienić wartości swych pól.
Przy wyświetlaniu XML2Form przekazuje referencje do Layoutu ($this), który kolejno wyświetla elementy. Element formularza ma podstawową metodę, która zwraca kod kontrolki, np. <input ..>, Opis jest wyciągany poprzez metodę Element::getDesc(), a sprawdzany poprzez Element::gasDesc().
Teraz przykładowy szablon. ColumnRadioLayout:

<table [class=”<?=$this->hasError()?'error_input':'normal_input'?>"]><tr><td> <?=$this->getLabel()?><br /> <?=$this->getDesc()?> </td><td> <?$this->toLayout()?><br /> <?$this->gerError()?><br /> </td></tr></table>

Jeżeli w szablonie strony wcześniej pojawiło się wywołanie getErrors to przy elementach getError() nie zwraca tekstu, jest tylko podświetlone pole. Myślę, aby część tego zadania przerzucić na CSS i zmieniać tylko klasę.
Diagram nie zgadza się z opisem, ponieważ od pewnego czasu nie zajmowałem się XML2Form i rozmyła mi się wizja całości. Być może, uda mi się to lepiej zorganizować, póki co czekam na opinie. kliknij aby powiekszyc

Internacjonalizacja załatwiona będzie niemal tradycyjnie, tzn. Formularz + zczytywaniez nagłowka ACCEPT_LANGUAGE przy tworzeniu nowej sesji. W zależności od wybranego tłumaczenia jest wczytywany plik z komunikatami.

Tym sposobem straciłem 2h na pisanie tego i nie stworzyłem DTD do plików konfiguracyjnych..

2 responses so far

Pomysł

Filed under Ogólne by

W głowie mej pojawił się nowy pomysł. :) W krótce więcej detali. Jak na razie powiem tyle, że chodzi o “coś” co załatwi problem walidacji danych i jednocześnie generowania formularzy. Nie jest to kolejna kopia PEAR::QuickForm, tylko coś innego, w sensie działającego w zgoła inny sposób..

3 responses so far

Zafascynowanie

Filed under Ogólne by

Znowu ponad dwutygodniowa przerwa w notach.. Nic dziwnego, że liczba odwiedzin od czerwca ma tendencję spadkową. Dla zainteresowanych (na oko) czerwiec 413, lipiec 387, sierpień 285. Ale wracając do spraw związanych z programowaniem i od razu na wstępie tłumacząc tytuł notki – zafascynowanie narzędziami z Javy. Moje szczególne uznanie zdobył Struts oraz Hibernate. Jedno i drugie ma swój odpowiednik w PHP – Studs oraz Propel. Co do pierwszego: nic ciekawego, bo pod PHP 4, odnośnie drugiego – dopiero poznaję. :] Z tego co widziałem w pracy Hibernate do niektórych zastosowań jest znakomity, jak wypadnie Propel – to się okaże. Jedno co mnie martwi to brak wsparcia dla PDO i brak konkretnej odpowiedzi czy w końcu się ono pojawi. Mam nadzieję, że w końcu zostanie to wymuszone.. Ze Strutsa najbardziej mi się widzi walidacja formularzy poprzez configi, stosunkowo łatwa internacjonalizacja oraz beany. Mam jakieś ebooki odnośnie budowania aplikacji w nim, ale mószę jeszcze raz wrócić do nauki Javy, ponieważ wcześniej czytałem tą książkę bez dostępu do komputera, a wiadomo każdy przykład trzeba sprawdzić. ;) Najgorsze jest to, że wcześniej przerabiając TiJ miałem pomysły/koncepcje rozwiązania niektórych zadań, a teraz mam w głowie same pytajniki – “o co tam chodziło???”. W pracy, można powiedzieć, zaaklimatyzowałem się, pojawiają się dyskusje odnośnie przeglądarek itp.

Co do Thora, można powiedzieć – zawieszony. Nie ma co kryć na dzisiejszy stan rzeczy (czytaj mojej wiedzy) nie jestem w stanie go dokończyć. Swój czas w sporej mierze poświęcam poznawaniu Mojavi, tzn. bardziej przeglądaniu źródeł niż tworzeniu aplikacji z użyciem tego frameworka.

Tak w zarysie – zero programistycznych konkretów, znowu same ogólniki. Ale nie ma co się dziwić. Brak sieci w chacie doskwiera…

No responses yet

Thor omówienie diagramu sekwencji

Filed under Thor by

Za jakość diagramu przepraszam :)

kliknij aby powiększyćNa przedstawionym diagramie widać 4 węzły. Pierwszy to użytkownik, który będzie wywoływał zdarzenia. Myślę, że jego zadań nie trzeba opisywać ;). Celowo operuję na ogólnikach aby nie zawężać Wam jak i sobie pola widzenia.

Pierwszy element dostarczany przez Thora to komponent. Każdy komponent posiada obiekt JavaScript, który komunikuje się z obserwatorem. Komponent przekazuje informacje o rodzaju zdarzenia. Jako parametr jest przekazywana zdefiniowana wcześniej wartość. Np. OnClick=”KliknietoMnie();” zostaje przekształcone na OnClick=IDentyfikator.call( onClick, KliknietoMnie()) powoduje to, że do obserwatora wędruje OnClick oraz KliknietoMnie.

Obiekt obserwatora ma za zadanie przekazać informację do serwera, którą zajmie się w dalszym ciągu framework. Obserwator jest bardzo ważnym elementem. Od jego działania zależy poprawność działania systemu. Obserwator musi rozróżnić operacje które ma zlecić do wykonania innym obiektom reprezentującym komponenty czy wysłać żądanie prosto do serwera.
Nota: czy rozsądniejsze by nie było stworzenie rozbudowanego zaplecza po stronie JS i pozwolić operować komponentom na sobie, a informacje do serwera wysyłać tylko po to żeby np. zapamiętać pozycję komponentu typu ‘sticky’?

Z pewnością AJAX będzie miał za zadanie zwracać treści z bazy danych. Myślę, że będzie się to odbywało poprzez zmianę atrybutu datasource. Zostanie o tym powiadomiony obserwator, który automatycznie wyślę rządanie do serwera. Ten odpowiednio sparsuje rządanie oraz określi czy użytkownik posiada uprawnienia do pobrania określonej treści. Ostatnim elementem w łańcuchu, lecz najważniejszą jest samo PHP. Thor będzie musiał na początku wygenerować stronę wraz z zestawem początkowych komponentów. Dobrze by było gdyby mógł później wydawać polecenia Obserwatorowi, który dalej kazałby usuwać komponenty bądź je dodawać.

Gdzieś trzeba jeszcze zostawić miejsce na style, to znaczy będzie musiała starczyć zwykła zmiana cssa, ale w dobie CSS 2 oraz 3 to nie powinno stanowić problemu (poza IE).

3 responses so far

Nota zbiorcza

Filed under Ogólne by

Witam po sporej przerwie :).

Piszę to o 23:23, tuż po ustawieniu budzika na 6:20, wiadomo – kto rano wstaje temu Pan Bóg daje. Wstałem dzisiaj po 5 i jak przystało na rasowego programistę czytałem w autobusie “Thinking in Java” w wydaniu trzecim. Po kilku dniach spędzonych z tą książką czuję się zagubiony. Przykładów jest sporo, a nie miałem okazji ich nawet uruchomić. Jak na razie nie miałem trudów z przyswojeniem wiadomości, okaże się jak zrozumiałem treść kiedy zacznę robić ćwiczenia. Tak czy siak tak łatwo się nie poddam. :)

Na polsacie właśnie leci jakieś badziewie pod postacią VIP. Normalnie nie wiem skąd oni biorą takie denne seriale.

Co z Thorem? No jak na razie po pracy jestem zbyt wypompowany żeby wyłuskać z siebie cokolwiek entuzjazmu do kodowania. W międzyczasie przeczytałem rozdział o projektowaniu aplikacji z TiJ. Na podstawie porad, które tam wyczytałem postaram się przeanalizować budowę Thora raz jeszcze. No zadanie będę miał nieco utrudnione dlatego, że to nie jest ‘zwykła’ aplikacja OOP tylko framework nastawiony na wykorzystanie komponentów. Po przerobieniu parsera na kształt tego z Prado mam problemy z połączeniem całości w logiczny zespół, to znaczy może inaczej – nie wiem w którym miejscu tworzyć obiekty komponentów na podstawie uzyskanej z parsera tablicy, która ma kształt drzewa. To znaczy:

Tree[korzeń][numer] = array(type,attr,childs); gdzie korzeń to kolejne komponenty występujace w dokumencie:

<!-- tutaj nagłówki meta itp. --> <thor:panel> 	treść 1 </thor:panel> <thor:panel> 	treść 2 </thor:panel> 

tablica Tree będzie w tym przypadku wyglądać tak: Tree[0][0] = array(panel); Tree[1][0] = array(panel);

W przypadku gdy komponent posiada dzieci są one dodawane poprzez referencję pod kluczem childs. Po var_dump-ie widać ładne drzewko.

Aby wyświetlić całe drzewo wystarczy zacząć od Tree[n][‘childs’]

Podczas prac miałem na prawdę spore problemy z uzyskaniem tego wyniku. Najpierw nie mogłem stworzyć odpowiedniej referencji następnie były problemy z tagiem <prop:atrybut></prop:atrybut>. Teraz kolejnym problemem jest uzyskiwanie wnętrza komponentu. Gdy wewnątrz komponentu znajduje się inny uzyskany kod jest znacznie okrojony, a dokładniej pozbawiony znajdujących się wewnątrz niego dzieci. Będę musiał zajrzeć do Prado i podejrzeć jak to jest rozwiązane. :)

Wracają do lektur, które przerabiam – po TiJ czeka na mnie “Java. Aplikacje bazodanowe, najlepsze rozwiązania” oraz “Java. Programowanie sieciowe”. Wszystkie książki pożyczyłem od kolegów z pracy. Dodatkowo obok mnie siedzi osoba zajmująca się Javą więc w razie problemów mam do kogo się zwracać.

Obecnie na pierwszy plan przed Thora wychodzi LiveChat, który piszę. Jest to poniekąd typowy chat, lecz nie mogę zdradzić póki co większej ilości informacji ponieważ ktoś może mnie uprzedzić z rozwiazaniem i będę na przegranej pozycji :).

W pracy jestem zmuszony do pracy na Auroksie którego zaczynam powoli mieć dość. Raz – problemy z Xami, dwa ogólna niechęć do tej dystrybucji. Zaczynam się coraz bardziej zastanawiać nad Slackware’m.

Jeśli już robię notkę zbiorczą to wspomnę, że zmartwychwstało OPB (Open Powe Board). Miejmy nadzieję, że czasy anarchii już nie wrócą. Mam do siebie spory żal za to, że zaniedbuję Pomocnik XUL, na prawdę nie mam usprawiedliwienia, kurde leń ze mnie i tyle. :(

PS. Jedyną rzeczą na która mogę na prawdę narzekać w Bydgoszczy jest jedzenie, a właściwie jego częsty brak w odpowiedniej ilości i jakości…

5 responses so far

Praca

Filed under Ogólne by

Właśnie jestem w pracy. Jest ok, podoba mi się tutaj. Wczoraj pospacerowałem sobie po Bydgoszczy (od PKSu do Czyżówka), kto wie jaki to jest odcinek ten ma wyobrażenie jak bardzo się błąkałem. ;) Znalazłem pokój na poddaszu, normalnie super, prawie jak w domu. Niestety problem jest z netem, bo ulica przy której mieszkam to póki co gruntówka i nie ma jak podciągnąć kabla. Pozostaje mi chyba radiówka… ale na to trzeba poczekać. Póki co mam internet na miejscu (czyt. w biurze).

3 responses so far

« Newer Entries - Older Entries »