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

Autor wpisu: Kamil Adryjanek, dodany: 15.11.2014 16:01, tagi: php, symfony2

bc_circle_symfony2In my recent project i had great opportunity to work together with powerful Symfony2 and amazing ExtJS5 frameworks. In the next few entries i will try to show you how to setup and configure Symfony2 application to serve REST API, than how to build ExtJS UI that will communicate with our REST API and finally how to setup basic authentication for REST API and ExtJS application… and maybe more.

Post RESTful ExtJS 5 and Symfony2 REST API: Symfony2 pojawił się poraz pierwszy w Kamil Adryjanek.

Autor wpisu: Łukasz Socha, dodany: 12.11.2014 15:31, tagi: php

SQL injection jest techniką ataku starą jak świat. Mimo tego wciąż jest niestety dość powszechną i prostą metodą ataku na strony www (nawet na te największe jak portale). Dzieje się tak, ponieważ przy tej metodzie najsłabszym ogniwem jest programista. Zobacz na czym polega ten atak i jak się przed nim zabezpieczyć. Trochę teorii SQL injection […]

Autor wpisu: Piotr Śliwa, dodany: 10.11.2014 14:42, tagi: php

Na początku nakreślę problem. Mamy klasę Product oraz interfejs ProductRepository.

interface ProductRepository {  
    function save(Product $product);
    function delete(Product $product);
    function findOne($id);
    function findAll();
    //...
}

ProductRepository może mieć kilka implementacji, np.:

  • DoctrineProductRepository - zapisywanie obiektów do bazy danych z wykorzystaniem EntityManagera z Doctrine, nasza "rzeczywista" implementacja używana przez aplikację
  • InMemoryProductRepository - trzymanie obiektów w pamięci, klasa wykorzystywana np. do testów funkcjonalnych kontrolerów lub serwisów - nie chcemy angażować bazy danych aby testy były szybsze, prostsze do konfiguracji itp.

Obie implementacje muszą działać tak samo, tak więc powinny mieć taki sam zestaw testów.

Rozwiązanie problemu

Jednym z rozwiązań jest napisanie abstrakcyjnej klasy testu, testowany obiekt oraz tworzenie danych testowych są w formie metod abstrakcyjnych.

abstract class ProductRepositoryTest extends PHPUnit_Framework_TestCase {  
    protected $repository;

    protected function setUp() {
        $this->repository = $this->createSUT();
    }

    //tworzenie obiektu testowanego
    abstract protected function createSUT();

    //umieszczanie Produktu w źródle danych    
    abstract protected function insertProduct(Product $product);

    /**
     * @test
     */
    public function givenExistingProduct_whenItIsDeleted_thenProductCouldNotBeFound() {    
        //given        
        $product = new Product(...);
        $this->insertProduct($product);

        //when        
        $this->repository->delete($product);
        $actualProduct = $this->repository->findOne($product->getId());

        //then        
        $this->assertNull($actualProduct);
    }

    //...
}

W konkretnych podklasach nadpisujemy metody createSUT i insertProduct.

Jest jednak problem... Klasa testu operującego na rzeczywistej bazie danych niekoniecznie rozszerza bezpośrednio PHPUnit_Framework_TestCase. Klasa bazowa dla testów na bazie dostarcza tworzenie połączenia, obtacza testy w transakcję która na końcu jest rollbackowana itp. Tak więc występuje potrzeba wielodziedziczenia, DoctrineProductRepositoryTest powinien rozszerzać zarówno ProductRepositoryTest oraz DoctrineTestCase. Nie jest to możliwe, chyba że zamienimy ProductRepositoryTest w trait.

/**
 * @mixin \PHPUnit_Framework_TestCase
 */
trait ProductRepositoryTest {  
    //to samo co w klasie ProductRepositoryTest
    //w poprzednim listingu
}

Adnotacja @mixin jest interpretowana przez PhpStorm tak, jakby ProductRepositoryTest "rozszerzał" PHPUnit_Framework_TestCase, dzięki czemu poprawnie działa podpowiadanie metod (np. asercji).

Możemy zatem wykorzystać trait do stworzenia testu dla DoctrineProductRepository.

class DoctrineProductRepositoryTest extends DoctrineTestCase {  
    use ProductRepositoryTest;

    protected function createSUT() {
        return new DoctrineProductRepository($this->em);
    }

    protected function insertProduct(Product $product) {
        $this->em->persist($product);
        $this->em->flush();
    }
}

Podobnie by wyglądał InMemoryProductRepositoryTest. Gdy dopisujemy jakiś test do ProductRepositoryTest, automatycznie będzie on wykonywany dla dwóch różnych implementacji ProductRepository. Minusem tego rozwiązania może być zaburzenie pętli TDD. Pisząc jeden test tak naprawdę mamy w rezultacie dwa czerwone testy - czyli w następnym kroku musimy zaimplementować dwie funkcjonalności dla dwóch całkowicie różnych klas, aby na nowo mieć przed oczami tylko zieleń. Pętla "Red -> Green -> Refactor" zamienia się w "Red x2 -> Green, Red -> Green x 2 -> Refactor x 2". Można temu przeciwdziałać wstawiając test najpierw do DoctrineProductRepositoryTest, a po zaimplementowaniu funkcjonalności i refaktoryzacji, przenieść go do ProductRepositoryTest.

Mając na początku interfejs ProductRepository i pisząc pierwszą implementację (np. DoctrineProductRepository), nie powinniśmy zaczynać od razu od tworzenia cechy/klasy abstrakcyjnej ProductRepositoryTest, gdyż tak naprawdę nie wiemy czy ona będzie potrzebna. Metody testowe należy umieszczać bezpośrednio w DoctrineProductRepositoryTest, a gdy będziemy mieć drugą implementację ProductRepository, powinniśmy dokonać refaktoryzacji wydzielenia cechy (trait) bądź klasy.

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

Autor wpisu: matipl, dodany: 22.10.2014 17:53, tagi: php

Początkowo chciałem zrobić standardowe podsumowanie ostatniej konferencji PHPCon Poland. Po chwili zastanowienia uznałem, że tak naprawdę PHPCon Poland wyznacza trendy na następny rok na naszym polskim rynku PHP.

W moim mniemaniu liczą się obecnie tylko 2 frameworki – Symfony 2 oraz Zend Framework 2. Cała reszta nie jest warta uwagi. Jeśli Twoim zdaniem Sf2 lub ZF2 są za duże na Twój projekt – wykorzystaj tylko poszczególne komponenty jakich dostarczają, albo napisz coś własnego małego… i użyj komponentów od dużych braci.

Jednym z powodów przejścia GoldenLine na Symfony było wsparcie jakie daje firma, która stoi za frameworkiem, znajomość frameworku przez rynek (programistów) oraz jego dojrzałość rozumiana przez pryzmat mnogości komponentów, gotowych elementów. To prawda, że są to wielkie kobyły, bez włączonego opcache ani rusz, ale taki jest rynek…

Z powodu wejścia tak sporych frameworków między innymi zmienia się PHP jaki znamy. Do jądra nie tylko dochodzą nowe bajery, ale również trwa ciągła optymalizacja wydajności i zarządzania zasobami.

HHVM

Odważniejsi mogą spróbować HHVM, który „zastąpił” HipHopa i staje się coraz bardziej dojrzały. W tym momencie już 27 narzędzi/frameworków da się w pełni uruchomić z wykorzystaniem HHVM (m.in. laravel, doctrine2, composer, phpunit, twig). Wystarczy PHP w wywołaniu zastąpić HHVM i nic więcej nie trzeba robić co pokazał Mariusz Gil.

HHVM przyspiesza composera ponad 5x. Czas wywołań testów na standardowym bench.php są oszałamiające, HHVM potrzebuje tylko 0,26 s, gdzie te same operacje PHP (5.5.9) bez żadnego wsparcia wykonywał przez 1,44 s. Ale najważniejszą kwestią jest architektura aplikacji, pomyślenie w odpowiednim momencie o cache’u, bazie danych, zewnętrznych API, czy odpowiednim zastosowaniu Redisa. Dopiero w takim momencie możemy pomyśleć o HHVM, czy czekać na PHP-NG, które będzie domyślnym silnikiem w PHP 7.0.

xhprof i aktualizacje

Ale po co w ogóle coś usprawniać? Badania pokazały, że jeśli coś trwa mniej niż 100 ms nasz mózg uważa że jest to natychmiastowa operacja. Zacznijmy optymalizować, jeśli żądania trwają powyżej 100 ms.

Wtedy można skorzystać z xhprof, młodszego, lepszego brata xdebug’a, z którego naprawdę prosto się korzysta i równie prosto instaluje (np. w połączeniu z xhgui). Należy również pamiętać o aktualizacjach samego PHP. Przejścia na PHP 5.6 jeszcze nie zalecam z powodu zbyt młodego wieku, ale najnowsza wersja PHP 5.5 to obowiązek. To nie tylko nowe możliwości (np. generatory, finally, password_hash), ale również zwiększona szybkość.

Testy jednostkowe

Żeby móc rozpocząć jakiekolwiek optymalizacje czy refactoring kodu należy posiadać najpierw w aplikacji testy jednostkowe. Podstawowym problem zawsze wydaje się na początku brak czasu i brak budżetu, ale jak kolejny raz podkreślił Michelangelo van Dam tak nie jest. Testy jednostkowe to same plusy:

  • natychmiastowy feedback w przypadku błędu
  • test piszemy raz, korzystamy z niego przy każdym wdrożeniu
  • o wiele prościej dokonać zmian w kodzie (refactoring)
  • prościej analizować kod aplikacji (debug)

Pisząc unit tests należy tylko pamiętać, aby testować jak najmniejsze jednostki kodu (smallest unit-of-code). Powinniśmy testować warunek po warunku (condition by condition), a nie do końca skupiać się na liniach kodu w metodzie. Testy powinny nam przetestować przede wszystkim logikę aplikacji, a nie same dane. Jeśli posiadamy integrację z zewnętrznymi API (np. płatności), również powinniśmy przetestować punkty styku, ewentualnie wirtualizując odpowiedzi drugiej strony.

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

Autor wpisu: Piotr Śliwa, dodany: 20.10.2014 22:17, tagi: php

Programista nie małpa, czytać musi. Wrzucam listę książek z niezwykle prestiżowym, moim certyfikatem jakości. Nie zamieszczałem tytułów, których nie przeczytałem, a wiem że są świetne i są na mojej liście do przeczytania. Kolejność nie ma większego znaczenia. Jeśli chcesz dodać coś od siebie, to są komentarze pod tym wpisem.

Programowanie i projektowanie obiektowe

Refaktoryzacja

Dobre praktyki i samorozwój

Wzorce projektowe

Testowanie

Języki programowania

  • Javascript: mocne strony - fajna książeczka opisujące tą jasną stronę Javascriptu - jeśli piszesz coś w js, to musisz ją przeczytać
  • Java: Podstawy - dobra książka do rozpoczęcia nauki Javy
  • Java: Techniki zaawansowane - uzupełnienie powyższej pozycji
  • Java Efektywne programowanie - świetna książka na temat dobrego kodu napisanego w Javie
  • Scala od podszewki - nie jest to książka o podstawach Scali, a o jej bardziej zaawansowanych mechanizmach. Warto przeczytać gdy chce się poznać Scalę, zapewniam że głowa nie raz będzie swędziała podczas lektury ;)

Programowanie funkcyjne

  • Real-World Functional Programming - świetna książka o programowaniu funkcyjnym. Warto przeczytać aby na nowo znaleźć się w piaskownicy. Do książki drukowanej jest prezent - wersja elektroniczna w formatach pdf, epub i mobi - lubię to! Nie należy zrażać się przykładami, które są w C# i F#. Tak swoją drogą, F# wygląda bardzo ciekawie ;)
  • Scala od podszewki - w tej książce jest również wiele o programowaniu funkcyjnym w bardziej zaawansowanym wydaniu

Bezpieczeństwo

  • The Tangled Web - porusza tematy bezpieczeństwa aplikacji webowych oraz protokołu http. Autor jest Polakiem, więc jest również polskie wydanie
  • Cisza w sieci - o bezpieczeństwie sieci i protokołów
  • Metasploit. Przewodnik po testach penetracyjnych - daje wyobrażenie na temat ogólnego bezpieczeństwa systemów informatycznych, w tym aplikacji webowych. Dobre wprowadzenie do Metasploit

Narzędzia

  • Pro Git - świetny podręcznik git, dostępna darmowa wersja online, darmowa anglojęzyczna wersja mobilna oraz darmowa polskojęzyczna wersja mobilna (ale trzeba sobie samemu zbudować z repozytorium na githubie)

Autor wpisu: matipl, dodany: 29.09.2014 19:41, tagi: php

PHPers 3city

Za chwilę październik i przed nami 2 spotkania/konferencje w Trójmieście, na które moim zdaniem warto się wybrać.

Już 1 października odbędzie się powakacyjny tech.3camp w Gdyni. Uczestnictwo jak zwykle darmowe, ale wymagana jest wcześniejsza rejestracja. Przed nami 4 prelekcje. Prelegenci poruszą tematykę Big Data (Artur Senk, OKE Poland), testowania (Marcin Maj, Kainos) oraz komunikacji między developerami a managerami produktu (Bartek Gatz, Spartez). Będzie też o tym, jak programista może rozkręcić swój biznes (Piotr Macuk, Konfeo.com).

Miejsce: PPNT (Gdynia) Termin: 1.10.2014 18:00 Rejestracja: https://tech3camp1pazdziernika.konfeo.com

Natomiast 17 października zapraszam na kolejne spotkanie organizowane przez PHPers 3city. W planie są 3 prelekcje. Michał Łukaszewski opowie nam „Jak naprawić kod, żeby nie zepsuć aplikacji, czyli kilka słów o refactoringu” (mocno polecam). A Maciej Iwanowski pokaże „Współbieżność w ekosystemie PHP”. Trzeci temat to jeszcze zagadka.

Miejsce: GPNT (Gdańsk) Termin: 17.10.2014 18:00 Rejestracja/info: wydarzenie na FB

PS: A osobom mieszkającym w Warszawie polecamy Aulę Polskę, najbliższe spotkanie 9 października.

Autor wpisu: Piotr Śliwa, dodany: 27.09.2014 00:15, tagi: php

Poprzedni mój wpis objaśniał podstawy programowania funkcyjnego, tym razem zajmę się wzorcem projektowym, który wywodzi się z języków funkcyjnych i jest szeroko stosowany w Haskellu, Scali, czy F#. Mowa tutaj o type Option. Inne nazwy tego patternu to Optional (java8), czy Maybe (Haskell) - podaję jabyście chcieli coś na ten temat wygooglować.

Nadmiar ifów w kodzie nie jest dobry, jest wiele sposobów które pozwalają zredukować ich liczbę. Takimi sposobami są niektóre wzorce takie jak State, czy NullObject. Wzorzec Option Type w php ma ograniczone zastosowanie, ale mimo to w wielu przypadkach jest użyteczny.

Przykład

Może na początek przykład, który będzie nam towarzyszył do końca artykułu. Jest on z grubsza zaczerpnięty z kodu produkcyjnego, więc jest jak najbardziej praktyczny i nie modeluje zoo.

Na początek zarysuję trochę dziedzinę problemu oraz sam problem. Mamy kanały, które agregują wiadomości, a każdy kanał należy do grupy kanałów.

ChannelGroup 1----* Channel 1----* Message

Grupa kanałów m. in. określa, czy w kanałach które do niej należą jest aktywne "zaawansowane targetowanie wiadomości" (cokolwiek to znaczy - dla przykładu nie jest to ważne). Mamy tablicę danych, w których prawdopodobnie jest wartość pod kluczem "channelId", chcemy dodać coś do zapytania z Doctrine2 (np. join lub warunek where) z id grupy, gdy grupa podanego kanału ma włączone zaawansowane targetowanie.

W powyższym opisie występują słowa takie jak: "prawdopodobnie", "gdy", więc kilka ifów będzie niezbędnych.

Przykład kodu w stylu imperatywnym:

if(isset($data['channelId'])) {  
    $channel = $this->channelRepo->find(data['channelId']);

    if($channel !== null) {
        $group = $channel->getGroup();

        if($group->hasAdvancedMessageTargeting()) {
            $qb->...;//Dodanie jakiegoś warunku do zapytania
        }
    }
}

3 ify, w dodatku zagnieżdżone. Ten kod nie wygrałby konkursu piękności...

Ale działa.

Czy ten kod da się zapisać nie używając ani jednego wyrażenia warunkowego (ifa lub operatora trójkowego)? Tak, za pomocą typu Option.

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

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.