Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu symfony Kanał ATOM (tag: symfony)

Autor wpisu: Tomasz Kowalczyk, dodany: 01.04.2011 23:11, tagi: symfony, framework

Nowa wersja frameworka symfony - Symfony2 powinna już niedługo ukazać się w pierwszej oficjalnej, stabilnej wersji. W świat poszła wiadomość o planowanym wydaniu na koniec marca, czego niestety nie udało się osiągnąć, aczkolwiek zagraniczni blogerzy przewidują opóźnienie nie dłuższe niż 3 miesiące. Aktualną wersją, dostępną do pobrania ze strony symfony.com jest Preview Release 8 [PR8]. [...]

Autor wpisu: l3l0, dodany: 24.03.2011 22:20, tagi: symfony, php

Nauka przez testy jednostkowe

Ostatnio dowiedziałem się jaką wartość ma pisanie testów, gdy uczymy się nowej technologii lub biblioteki. Otóż napisałem klika testów do Symfony2. Chociaż było to tylko klika testów, naprawdę dużo się nauczyłem. Powiedzmy żę chcemy nauczyć się czegoś o routingu w Symfony 2.

Jak zacząć?

Najpierw powinniśmy objerzeć testy które są w komponencie. Często to wystarczy żeby zroumieć jak on działa. Jeśli mamy jakieś wątpliwości powinniśmy je rozwiązać pisząc nowy test i próbując, nawet coś popsujmy żeby zobaczyć co się stanie. Możemy próbować nieograniczoną liczbę parametrów i kombinacji. Testy jednostkowe mają tą zalete że wykonują się szybko więc szybko upewnią nas czy nasze przypuszczenia są poprawne. To podejście jest nawet lepsze gdy mamy jakiś gówniany kod.

Stary kod i też może… być testowany

Napewno znasz to uczucie gdy musisz dodać nowy kod do 6 letniego projektu o którym wszyscy zapomieli… ty nawet nie wiesz gdzie zacząć. Ja, w takim wypadku, zaczynam od ustawienia mojego środowiska testowego (albo od naprawienia i posprzątania środowiska testowego o ile istniało). Nastepnie powinniśmy przeanalizować kod i stwierdzić w których miejscach będziemy musieli zrobić zmiany. Przed dodaniem nowego kodu trzeba stworzyć test, jednak ważniejsze w tym momencie są testy dla functionalności w której grzebiemy. Jeśli nie ma testów musimy je utworzyć. Aby utworzyć testy musimy zanalizować kod. Czasami (nawet często) kodu nie da się przetestować, wtedy musimy troche pohakować (ostrożnie!) tak aby kod stał się testowalny. Po tym procesie możesz dodać nowe funkcionalności, co powinno być już łatwiejsze – twoja wiedza o kodzie wzrosła. Kodowanie teraz powinno być przyjemne, a testy powinny dać Ci większą pewność i oszczędzić dużą ilość stresu. Oczywiście twój kod jest teraz jakościowo lepszy.

Jakość i prostota kodu, a testy jednostkowe.

Testowanie powinno pomóc Ci tworzyć prosty kod, powinno Ci też pomóc tworzyć kod wysokiej jakości. Owszem ale tylko gdy robisz TDD. O ile pisanie testów po kodzie ma sens w czasie nauki, o tyle nie jest to dobre podejście z punktu widzenia projektowego, nie pomaga też tworzyć prostego kodu bo kod jest już stworzony. Pisanie testów przed kodem pomaga ustalić publiczne API oraz przede wszystkim wymagana od nas (programistów) myślenia przed napisaniem kodu. W TDD napierw piszemy test, potem kod ale tylko taki który sprawi że nasz test przejdzie (nawet głupi). Następnie musimy sprawić aby następne testy przeszły, jednak po każdej takiej iteracji powinnismy usuwać duplikaty kodu (zasada DRY czyli że nie powtarzamy się). Testy powinny być zdefiniowane tak aby otestować jak najbardziej nasze oczekiwania w stosunku do klasy.

Jest naprawdę wiele powodów żeby używać testów jednostkowych, tymbardziej nie mogę zrozumieć czemu istnieje tak wiele aplikacji bez testów.

Tutaj mam prośbę: Aplikacje potrzebują pomocy, gdy znajdziecie jakąś smutną aplikację bez testów, zlitujcie się i napiszcie parę testów!

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: l3l0, dodany: 18.03.2011 23:07, tagi: php, symfony

Instalacja “Standard Symfony2″ ddistribution. Więcej informacji o instalacji na stronie symfony.com Teraz powinniśmy skonfigurować baze danych, możesz to sprawdzić na doctrine configuration

Konfiguracja naszego bundla

php app/console init:bundle "l3l0\BackendBundle" src

rejestrujemy “namespace” naszego “bundle” w app/autoload.php

$loader->registerNamespace(array(
...
    'l3l0' => __DIR__ . '/../src',
...
);

oraz rejestrujemy nasz “bundle” w app/AppKernel.php

public registerBundles()
{
    $bundles = array(
      ...
      new l3l0\BackendBundle\l3l0BackendBundle()
    );

    return $bundles;
}

BDD Przy projekcie chcę używać BDD, chcę więc zainstalować Behata, żeby to zrobić starczy zainstalować BehatBundle. Opis instalacji na githubie https://github.com/Behat/BehatBundle/blob/master/README.md

Inicializacja Behata dla naszego bundla

php app/console behat:test:bundle --init l3l0\\BackendBundle

Implementacja historyjki użytkownika “Jako magazynier chcę logować się do systemu.”

Powiedzmy że musimy zaimpelementować taką funkcionalność.

Zaczniemy od pliku “feature” który jest odpowiednikiem testu w TDD może on wyglądać tak (eng) src/l3l0/BackendBundle/Tests/Features/login_to_system.feature

Feature: Login to system
  As a Guest I want to
  login to system.

  Background:
    Given user "l3l0" with password "password" is in database
    And I am on /login

  Scenario: Signin into system with valid login and password
    Given I fill in "loginForm[login]" with "l3l0"
    And I fill in "loginForm[password]" with "password"
    When I press "Login" in loginForm form
    Then I am logged in system
    And I should see "You are logged as l3l0"

  Scenario: Signin with invalid login
    Given I fill in "loginForm[login]" with "l3l01"
    And I fill in "loginForm[password]" with "password"
    When I press "Login" in loginForm form
    Then I am not logged in system
    And I should see "Your login or password is invalid"

  Scenario: Signin with invalid password
    Given I fill in "loginForm[login]" with "l3l0"
    And I fill in "loginForm[password]" with "password1"
    When I press "Login" in loginForm form
    Then I am not logged in system
    And I should see "Your login or password is invalid"

  Scenario: Signin with invalid login and password
    Given I fill in "loginForm[login]" with "l3l01"
    And I fill in "loginForm[password]" with "password1"
    When I press "Login" in loginForm form
    Then I am not logged in system
    And I should see "Your login or password is invalid"

Po uruchomienu feature zobaczymy że nie mamy zdefinowanych trzech kroków, aby je zdefinować musimy dodać do src/l3l0/BackendBundle/Tests/Features/steps/steps.php linijki:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: l3l0, dodany: 10.03.2011 00:33, tagi: php, symfony

Ostatnio miałem nie powtarzalną okazję przeanalizować prezentacje przygotowane na Symfony Live 2011 – konferencję Symfony która odbyła się w Paryżu. Na listę prezentacji udostępnionych na slideshare natrafiłem poprzez post @caefer-a oraz post Jakuba Zalasa. Postanowiłem napisać kilka słów o slajdach które przeczytałem.

1. Symfony 2 from the trenches

Prezentacja opisuje podstawowe koncepcje stojące za nowym frameworkiem z SensioLab. Nauczyłem się z niej wiele o kontenerze wstrzykiwania zależności oraz komponentach do cachowania no i oczywiście dowiedziałem się dlaczego Symfony2 rządzi.

2. Apostrophe (imporved Paris edition)

Myśle żę Apostrophe może być alternatywą dla Drupala czy WordPressa. Jest to całkiem porządny CMS oparty i napisany na symfony 1.4. Polecam go szczególnie tym programistom PHP którzy mają dość “poezji” Drupala i WordPressa. Mam nadzieję że będę mógł poznać i nauczyć się tego CMF-a w najbliższym czasie.

3. Leveraging Symfony2 Forms (Bernhard Schussek)

O nowych formularzach w Symfony 2 czytałem już wcześniej, jednak pierwszy raz spotkałem się w tej prezentacji z obiektami Configa w Symfony 2. Taki obiekt może być obsłużony przez mechanizm wstrzykiwania zależności (w przeciwieństwie do obiektu formularza). Wstrzykiwanie zależności jest bardzo dobym mechanizem który może pomóc nie powtarzać kodu, jednak nie wiem czy ma to sens w wypadku bardzo scustomizowanego formularza. Myśle jednak że może poprostu potrzebuje się z tym oswoić i nabrać praktyki.

4. Assetic (Symfony Live Paris)

Pierwszy raz słyszałem o Assetic-u. Bardzo mi się spodobał. Jest to optimizer do wszystkich rzeczy związanych z frontend-em czyli minimalizacji stylów, javascriptów oraz całej reszty. Ma on bardzo dobrą integrację z Symfoniowym Twigem przez TwigExtension. Napewno przyjrzę się Assetic-owi bliżej.

Podsumowanie

Nie widziałem jeszcze wszystkich prezentacji z Symfony Live. Uważam że takie slajdy są ogromną bazą wiedzy, jednak uczestnictwo w konferencji daje jeszcze więcej – nawet gdy wykłady nie są interesujące lub są dla nas oczywiste. Konferencja daje nam możliwość wymiany doświadczeń i poznania innego spojrzenia niż nasze – moim zdaniem to jest to bardzo wartościowe, dlatego polecam wszystkie konferencje. Żałuję tylko tego że nie mogłem wziąść udziału w Symfony Live, no nic może następnym razem.

Autor wpisu: Piotr Śliwa, dodany: 06.03.2011 00:13, tagi: php, symfony

Jedną z najbardziej podstawowych zasad programowania zorientowanego na obiekty to hermetyzacja danych. Mechanizmy php dostarczają nam modyfikatory dostępu, które to pomagają nam w hermetyzowaniu danych i implementacji poszczególnych klas, tak abyśmy mieli swobodę we wprowadzania zmian, które nie zmieniają funkcjonalności. API to interfejs, który nie ukrywamy, a udostępniamy. Co więc składa się na ten interfejs?

Na API klasy składają się:

  • składowe i metody publiczne
  • stałe
  • składowe i metody chronione, jeśli klasa jest przeznaczona do dziedziczenia (nie jest klasą finalną)
  • postać serializowana

Dwa pierwsze punkty wydają się oczywiste, API jest interfejsem obiektu, z którego może korzystać klient (czyli obiekt pracujący na innym obiekcie udostępniającym to API). Dwa pozostałe punkty nie wydają się tak oczywiste. Dla wyjaśnienia trzeciego punktu posłużę się przykładem z symfony 1.4.x:

[PHP]
  1. abstract class sfComponent
  2. {
  3. protected
  4. $moduleName = '',
  5. $actionName = '',
  6. $context = null,
  7. $dispatcher = null,
  8. $request = null,
  9. $response = null,
  10. $varHolder = null,
  11. $requestParameterHolder = null;
  12.  
  13. //ciach...
  14. }

Co by się stało gdyby developerzy symfony postanowili zmienić nazwę składowej $varHolder na np. $dataForView lub też typ przechowywany przez tą składową? Wiele projektów, które korzystają bezpośrednio z niej przestała by działać. Ustawiając tą składową jako chronioną sami siebie ograniczyli co do jej typu (klasy dziedziczące po sfComponent i pracujące bezpośrednio na $varHolder oczekują interfejsu jaki udostępnia klasa sfParameterHolder) oraz jej nazwy. Powyższa klasa udostępnia również rozmaite metody ustawiające, które operują na składowej $varHolder (getVar, setVar oraz magiczne metody __get, __set, __isset, __unset), które wyczerpują zastosowanie tej składowej. Klasa ta wcale nie ukrywa danych i swojej implementacji. Dlaczego składowa $varHolder oraz reszta składowych są chronione? Zapewne z przyzwyczajenia programisty lub też konwencji przyjętych przez zespół, dla dużej liczby programistów "podstawowym" modyfikatorem dostępu jest modyfikator chroniony, przez co klasy udostępniają za dużo informacji niż powinny, a co za tym idzie niepotrzebnie udostępniają większe, bardziej skomplikowane i naszpikowane szczegółami API. Ewentualna refaktoryzacja takiej klasy jest ograniczona, gdyż może już istnieć wiele kodu, który korzysta z jej szczegółów implementacyjnych. Wniosek jest taki, że nie należy bezmyślnie ustawiać wszystkim właściwościom modyfikatora chronionego, ale używać tego modyfikatora tam gdzie faktycznie jest on niezbędny. Taka sytuacja może mieć miejsce, gdy składowa jest prywatna i ma np. chronione metody ustawiające i pobierające, przez co sama prosi się o większą widoczność.

Podobna sytuacja ma się z metodami, jednakże modyfikator "chroniony" powinien być bardziej powszechny wśród metod, gdyż dane powinny być chronione w większym stopniu.

Ostatni składnik API, czyli postać serializacji jest pewnie największym zaskoczeniem. Pamiętajmy że dzięki mechanizmie serializacji można ustawić i odczytać prywatną właściwość obiektu. Domyślna postać serializacji udostępnia mnóstwo szczegółów na temat implementacji klasy.

[PHP]
  1. class A
  2. {
  3. private $objectOfB;
  4.  
  5. public function __construct(B $objectOfB)
  6. {
  7. $this->objectOfB = $objectOfB;
  8. }
  9. }
  10.  
  11. class B
  12. {
  13. private $text;
  14.  
  15. public function __construct($text)
  16. {
  17. $this->text = (string) $text;
  18. }
  19. }
  20.  
  21. $a = new A(new B('some text'));
  22.  
  23. echo serialize($a);

Wynik powyższego kodu będzie: O:1:"A":1:{s:12:"?A?objectOfB";O:1:"B":1:{s:7:"?B?text";s:9:"some text";}}

Widać więc, że klasa A ma właściwość prywatną o nazwie "objectOfB", której wartością powinien być obiekt klasy B. Mozna zmodyfikować tą postać serializowaną, przez co jawnie ustawimy wartość prywatnej składowej deserializowanego obiektu: O:1:"A":1:{s:12:"?A?objectOfB";s:9:"some text"}. Teraz gdy to zdeserailizujemy, w składowej "objectOfB" będzie przechowywany ciąg znaków - zostanie złamany niezmiennik obiektu, który zakłada (za pomocą konstruktora) że przechowuje ona obiekt typu B.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: matipl, dodany: 03.02.2011 10:05, tagi: php, framework, symfony

Zend FrameworkPrzed majem 2010 roku w świecie PHP poruszałem się głównie z pomocą Zend Frameworka. Kilka lat wcześniej był to autorski framework (netEngine) oraz firmowe frameworki. Z perspektywy czasu uważam, że złe było rozwijanie własnych narzędzi, zamiast pomóc społeczności. Taki zbiorowy projekt jest świetny:

  • bardzo szybko rozwijany
  • zawsze znajdziesz osobę, która zna framework (a Twój lub firmowy?)
  • spora baza tutoriali w Sieci
  • popularny = groźny (wykryta dziura w Australii może spowodować ciężki tydzień w Twojej firmie)

Od maja pracuję głównie z wykorzystaniem Symfony (1.4). Z mojego punktu widzenia przedstawia on odmienne podejście do sprawy. W Symfony da się sporo rzeczy ustawić z góry, dobry cmd line, a mnóstwo mamy out of box. Ale rozwijanie Symfony o własne dodatki czy helpery nie jest przyjemnością. Symfony odbieram jak takiego WordPressa – sprawdza się, ale jego kod pozostawia wiele do życzenia (przeplatanie języka proceduralnego z obiektowym).

Najgorszy minus Symfony 1.4 ? Mimo, że jest długo na rynku i jest najnowszą stabilną wersją Sieć prawie o nim milczy poza oficjalną dokumentacją. Jeśli przyjdzie zmierzyć się Tobie z nietrywalnym problemem lepiej od razu przejrzeć kod źródłowy frameworka niż szukać w Google.

Od grudnia znów pracuję z Zend Framework, przy okazji projektu bilancio. Wrażenia ogólne – bosko, w końcu czuję się jak w domu. Mam tyle obiektów ile dusza zapragnie. A Google bardzo jest pomocne. Najgorszy był początek przy powrocie z Symfony.

Nadal nie widzę dobrze opisanego application.ini w Sieci, a można obecnie przez niego pozbyć się nadpisywania większości zasobów (ach czasy ZF < 1.0). Dodatkowo wydaje mi się, że formularze w Symfony „szybciej mi szły”. Chociaż irytujące jest, że w większości wypadków wypluwał inputy, zamiast pełnego tagu form (łatwiej obudować w ZF jak się potrafi). No i te magiczne url_for() w Symfony (w zależności od parametru wywołuje rózne inne funkcje).

Po pierwszym tygodniu pracy z Zend Framework nie chcę się z nim znów rozstawać, Symfony to naprawdę nieprzyjemne środowisko. A przy okazji projektów ZF może w końcu zacznę dzielić się jakimiś drobnostkami z Wami. Zobaczymy czy czas pozwoli (jak widać po blogu tutejszym ostatnio mi go brak).

PS: Przed wczoraj został opublikowany Zend Framework w wersji 1.11.3 (30 załatanych dziur).

Autor wpisu: Wojciech Sznapka, dodany: 31.01.2011 12:15, tagi: php, symfony

Na firmowym blogu http://xlab.pl zamieściłem post odnośnie mojej ostatniej prezentacji na temat Symfony2 – zapraszam do lektury :-) Post jest dostępny pod tym linkiem.
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.