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

Autor wpisu: batman, dodany: 22.03.2012 18:35, tagi: php, internet

logo_kolorowe_nova_versja_poziomo

Już niedługo, bo za niecały miesiąc, odbędzie się czwarta edycja konferencji 4Developers. Miałem okazję uczestniczyć w dwóch poprzednich edycjach i bardzo chciałbym wziąć udział w tym roku, niestety z powodu kilku drobnych zawirowań, muszę tym razem odpuścić sobie tę przyjemność. Bardzo tego żałuję, ponieważ w tym roku interesujących tematów na pewno nie zabraknie. Do najciekawszych moim zdaniem można zaliczyć między innymi Tworzenie i wdrażanie z użyciem strategii chmur hybrydowych, Jak wybrać odpowiednią bazę NoSQL, REST i ograniczenia hypermediów, czy Hadoop w Hurtowni Danych nk.pl. Oczywiście nie są jedyne interesujące sesje, których pełną listę znajdziecie na stronie poświęconej konferencji. Podobnie jak w zeszłych latach i tym razem do wyboru są 4 ścieżki. Są to Java, Zarządzanie projektami IT, Wydajność i skalowalność oraz PHP. Oprócz samych sesji wykładowych na uczestników czekają warsztaty oraz konkursy z nagrodami.

Ale do rzeczy. Mam dla Was wejściówkę dla jednej osoby. Co trzeba zrobić, aby ją wygrać? Napiszcie w komentarzu na jaką sesję chcielibyście najbardziej pójść i dlaczego? Komisja egzaminacyjna w tajnym składzie zadecyduje o zwycięzcy. Na odpowiedzi macie czas do końca weekendu (wiem, wiem – ładna pogoda, a ja wymyślam jakieś zadanie na weekend), czyli do północy 25 marca. I nie zapomnijcie, że w ten weekend przestawiamy zegarki o godzinę do przodu.

Strona konferencji – 4developers.org.pl.

Autor wpisu: sokzzuka, dodany: 21.03.2012 13:59, tagi: php

Ostatnimi czasy, mam okazję tworzyć dość duże ilości testów jednostkowych. Zwykle tworze je do cudzego kodu, co pozwala mi w pewnym sensie ocenić jego jakość. Zapytacie może, jak proces pisania testów jednostkowych do istniejącego kodu pozwala ocenić jego jakość ?

Otóż, pewna stara programistyczna fama głosi, że gdy kod jest łatwo testowalny, to prawdopodobnie jego jakość, a przynajmniej architektura będzie wysokiej jakości. Automatycznie na myśl przychodzi takie proste rozwiązanie, że skoro kod ma być łatwo testowalny, to najlepiej by było zacząć jego tworzenie od napisania testów. Takie podejście nazywa się TDD (Test Driven Development). Pewnie wielu z Was słyszało o takim podejściu, natomiast jeżeli pracujecie w typowej firmie wytwarzającej „stronki”, to pewnie nie mieliście wielu okazji by zastosować takie podejście.

Oczywiście nie koniecznie jest to grzech – w prostych projektach zastosowanie TDD może być dyskusyjne ze względu na narzut czasowy jaki generuje. Znając jednak życie, prosty projekt zwykle przeradza się w projekt skomplikowany, którego skali nikt nie przewidział.

Abstrahując jednak od TDD, chciałbym się podzielić z Wami, moimi spostrzeżeniami na temat typowych „wzorców” w kodzie, które znacząco obniżają jego testowalność. Przy okazji zaproponuje sposoby ich rozwiązania poprzez refaktoring kodu oraz omówię konsekwencje jakie niosą za sobą poszczególne antypatterny.

Tak więc, jeżeli spotkasz jeden z podanych poniżej przypadków – wiedz, że coś się dzieje ;)

  1. Testując dany obiekt sprawdzam jego stan po wywołaniu danej metody:
  2. Testując dany obiekt tworzymy mocki obiektów od których jest zależny w sposób łańcuchowy
  3. Testując dany obiekt łapiemy się na tym, że testując metodę publiczną w istocie chcielibyśmy przetestować metody prywatne z których ona korzysta

Kilka przykładów kodu, żeby było wiadomo o co chodzi:

Przykład nr. 1:

class Bar(var i: Int) {}class TestSubject1 {        def doFoo(bar: Bar){    bar.i = 10  }  }def testCase1() {    val bar = new Bar(0)        val testedObject = new TestSubject1    testedObject.doFoo(bar)        if(bar.i == 10){      println("true")    } else {      println("false")    }  }
view raw gistfile1.scala This Gist brought to you by GitHub.

Mamy zdefiniowane dwie klasy – Bar, która ma property „i” oraz klasę TestSubject1 która jest testowana przy użyciu funkcji testCase1. Co jest złego w tego rodzaju kodzie ? Przede wszystkim następuje niejawna manipulacja obiektem klasy Bar. Poza tym, jako, że metoda ma typ void (w tym przypadku w Scali jest to Unit), programista, który chce użyć takiego kodu, tak naprawdę nie wie jaki jest efekt jego działania. Kod po refaktoringu:

class TestCase1refactored {    def doFoo(bar: Bar): Bar = {    val result = new Bar(bar.i + 10)    return result  }  }def testCase1refactored() {    val bar = new Bar(0)        val testedObject = new TestSubject1refactored()    val result = testedObject.doFoo(bar)        if(result.i == 10){      println("true")    } else {      println("false")    }  } 
view raw gistfile1.scala This Gist brought to you by GitHub.

Jak widać, metoda po refaktoringu zwraca jakąś konkretną wartość, poza tym zamiast zmieniać stan obiektu, tworze nowy ze zmienioną wartością, dzięki czemu unikam modyfikowania globalnego stanu.

Przykład nr.2:

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

Autor wpisu: Diabl0, dodany: 20.03.2012 17:22, tagi: javascript, php

Użytkownicy pracujący w serwisach intranetowych wielokrotnie stoją przed koniecznością wydrukowania jakiegoś dokumentu czy formularza celem zachowania papierowej dokumentacji czy wydania papierowej wersji klientowi. Dotychczas realizowałem to tworząc i otwierając w nowym oknie dokument PDF gdzie użytkownik musiał ręcznie wybrać opcję Drukuj. Teoretycznie to działa, aczkolwiek jest troszkę upierdliwe. Jednakże ostatnio  przypadkowo trafiłem na informację że PDF może zawierać swój kod JS więc postanowiłem troszkę poeksperymentować.

Sytuacja z życia wzięta – pielęgniarka pobiera próbki do badań laboratoryjnych. Na stronie ma listę zleconych testów oraz informacje jakie i ile próbek pobrać. Na każdą próbkę powinna wydrukować naklejkę z unikalnym kodem kreskowym. Problemem jest to drukowanie: naklejki są małe, kod długi i mało czytelny bez czytnika – przy drukowaniu „masowym” po pobraniu wszystkich próbek łatwo o pomyłkę. Drukowanie każdego kodu w miarę dodawania jest znowu bardzo niewygodne – kliknięcie „dodaj próbkę”, czekanie aż otworzy się okienko z plikiem PDF, kliknięcie drukuj, potwierdzenie ustawień drukowania (wybrać drukarkę do etykiet) i druk, zamknięcie okienka z plikiem PDF. Na szczęście jest na to sposób.

Tym sposobem jest właśnie Acrobat JavaScript.

Dla zainteresowanych dokumentacja znajduje się tutaj: http://partners.adobe.com/public/developer/en/acrobat/sdk/pdf/javascript/AcroJS.pdf

Co prawda AJS nie daje nam pełnych możliwości w zakresie drukowania dokumentu, ale już to co jest może nam znacznie ułatwić życie. Dzięki temu udało mi się zredukować cały proces do kliknięcia „dodaj próbówkę” i kliknięcia OK w komunikacie że PDF chce coś wydrukować.

Zaczynamy od naszego dokumentu PDF. Jako kreatora używam znakomitej biblioteki TCPDF, w której można znaleźć metodę IncludeJS(). Mój kod JS wygląda następująco:


// Ustawieniadrukowania
var pp = this.getPrintParams();

// Wybieramy drukarkę (Nazwa drukarki widoczna w systemie)
pp.printerName = "DYMO LabelWriter 450 Turbo";

// Ustawiamy automatyczny wybór rozmiaru papieru
pp.flags |= pp.constants.flagValues.setPageSize;

// Dodatkowe skalowanie aby dopasować dokument do papieru
pp.pageHandling = pp.constants.handling.fit;

// Drukujemy tylko treść bez żadnych dodatków
pp.printContent = pp.constants.printContents.doc;

// tryb "cichego" drukowania - pomijamy okno z preferencjami drukowania
pp.interactive = pp.constants.interactionLevel.silent;

// Wymuszenie drukowania
this.print(pp);

Taki JS  należy „zapisać” w dokumencie PDF. W TCPDF jak wspomniałem odpowiada za to metoda IncludeJS

$pdf = $this->_prepareStickerPDF( $stickerData );

if ( $this->getRequest()->getParam('print', 'false') != 'false' ) {
    // KOD Adobe PDF JS do wymuszenia drukowania i ustawienia podstawowych parametrów
    $js = '
        var pp = this.getPrintParams();
        pp.printerName = "DYMO LabelWriter 450 Turbo";
        pp.flags |= pp.constants.flagValues.setPageSize;

        pp.pageHandling = pp.constants.handling.fit;
        pp.printContent = pp.constants.printContents.doc;
    ';

    if ( $this->getRequest()->getParam('print', 'false') == 'silent' ) {
        $js .= 'pp.interactive = pp.constants.interactionLevel.silent;';
    }

    $js .= ' this.print(pp); ';

    $pdf->IncludeJS($js);
}

$pdf->Output('Sticker.pdf', 'I');

Ok. Mamy spreparowany dokument PDF który automatycznie przy otworzeniu chce się drukować na ustawionej drukarce. Teraz trzeba coś zrobić aby pozbyć się popupów z PDF’em. Z pomocą przyjdzie nam możliwość osadzania obiektów PDF w HTML’u. Możemy to zrobić przez znaczniki HTML lub z poziomu JS (więcej info: http://blogs.adobe.com/pdfdevjunkie/web_designers_guide). Z poziomu JS wykorzystuję do tego PDFObject. W pliku HTML mam placeholder o zerowych rozmiarach i do niego wczytuję dokumenty PDF.

 

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

Autor wpisu: Śpiechu, dodany: 16.03.2012 16:06, tagi: php

Pomysł na wpis dał mi kilka dni temu Facebook, a dokładniej ich totalnie niekonsekwentne oznaczenia co się kiedy wydarzyło na naszej tablicy. Raz jest to 23 minut(y) temu, raz 7 godz. temu, jeszcze inaczej około godziny temu. Być może różne ekipy robią osobno opisy czasu i stąd różnice. Postanowiłem dla sportu zmierzyć się z problemem. Powstało takie coś jak Timespan Smarty Modifier.

Opis jak to zainstalować, wymagania i sposób użycia możecie sobie przeczytać w moim kaleczonym angielskim w GitHubie. Tutaj chciałbym się skupić jak to działa. Najwygodniejszym sposobem korzystania z biblioteki jest poprzez modyfikator w szablonach Smarty, a więc {$jakaśZmienna|naszModyfikator}.

Przede wszystkim sama nazwa pliku musi nazywać się modifier.nazwa.php, za to funkcja smarty_modifier_nazwa($argument). Pierwszy argument automatycznie dostaje wartość zmiennej, dla której wywołujemy modyfikator. Jeśli chcemy, następne podajemy po dwukropku. Drobna uwaga: nigdy niczego nie „echujemy”, tylko zwracamy poprzez return. Chodzi o łańcuchowe łączenie modyfikatorów.

Z uwagi na to, że całość rozrosła się do ponad 400 linii kodu, nie ma sensu wszystkiego tutaj przytaczać. Skupię się na najważniejszych rzeczach.

Całość ma formę klasy abstrakcyjnej rozszerzanej przez poszczególne języki. Na podstawie zadeklarowanego języka skrypt próbuje znaleźć sobie właściwą klasę (fragm. modifier.timespan.php):

$className = 'Spiechu\TimeSpan\TimeSpan' . strtoupper($lang);
   if (class_exists($className)) {
      $timeSpan = new $className();
 
      // sprawdz czy klasa rozszerza AbstractTimeSpan
      if (!($timeSpan instanceof Spiechu\TimeSpan\AbstractTimeSpan)) {
         $timeSpan = new Spiechu\TimeSpan\TimeSpanEN();
      }
   } else {
 
      // jesli nie ma takiego jezyka lub klasa niewlasciwa uzywam angielskiego
      $timeSpan = new Spiechu\TimeSpan\TimeSpanEN();
   }

Potem tylko konfigurujemy klasę i zwracamy wynik:

$timeSpan->setStartDate($date)->showSuffix($suffix);
return $timeSpan->getTimeSpan();

W klasie AbstractTimeSpan z kolei mamy trochę logiki związanej z obliczaniem interwału:

$curDate = new \DateTime('now');
$diff = $curDate->diff($this->_startDate); //otrzymujemt obiekt DateInterval

Począwszy od największej jednostki (rok) odpytujemy $diff która z jego zmiennych publicznych jest większa od 0 oraz za pomocą metod isHalfUnit($actualUnit, $fullUnit), almostFullUnit($actualUnit, $fullUnit) sprawdzamy czy może przekroczyliśmy połowę obecnej jednostki, większej jednostki oraz czy nie można jej zaokrąglić do następnej całej.

Klasy rozszerzające implementują m.in. metodę getUnit($howMany, $unitSymbol, $half). Liczebniki angielskie są tak trudne, że potrzeba na nie aż 1 linijki:

if ($howMany > 1) $howMany = 2;
return $this->_units[$howMany][$unitSymbol];

Jeśli mowa o $this->_units to wygląda to tak:

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

Autor wpisu: bastard13, dodany: 12.03.2012 12:20, tagi: oop, php

na wstępie słów kilka

Znowu dłuższa przerwa w publikowaniu czegokolwiek. Na szczęście dobiegła końca i mam nadzieję, że w ciągu najbliższych kilku-kilkunastu tygodni uda mi się dokończyć wszystkie zaległe wpisy, na które pomysły dojrzewały, lecz z braku czasu nie mogły się doczekać realizacji:(O czym dzisiaj? O stałych. A czym są te stałe? Kiedy ich używać, a kiedy nie? O tym dalej:)Czytaj więcej »

Autor wpisu: zleek, dodany: 08.03.2012 09:24, tagi: zend_framework, php

Podczas przygotowywania formularzy z wykorzystaniem Zend_Form zachodzi czasami konieczność przekazania do formularza zmiennej lub zmiennych, które będą warunkowały odpowiednie wygenerowanie formularza. Przykładem może tutaj być przedstawienie innego formularza dla kobiety i innego dla mężczyzny. Powstaje wówczas konieczność “poinformowania” formularza o płci użytkownika. Stworzenie jakiejś dodatkowej metody i wywołanie jej na instancji formularza nie przyniesie zamierzonego [...]

Autor wpisu: Kamil, dodany: 05.03.2012 03:41, tagi: php, apache

Konieczność ograniczania prędkości pobierania plików przez użytkowników raczej nie występuje zbyt często, niemniej jednak warto znać rozwiązanie (które de facto jest proste w implementacji). W niniejszym wpisie pokażę, w jaki sposób samodzielnie napisać kod rozwiązujący problem ograniczania prędkości pobierania zasobów z serwera przy pomocy PHP oraz alternatywne rozwiązanie dla serwerów Apache. Limit prędkości pobierania plików [...]
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.