Archiwum autora: Techniczny Inside

Jak uprościć sobie pracę z wirtualnymi hostami instalując dnsmasq?

Pracując z kilkoma projektami na lokalnym środowisku prędzej czy później stwierdzimy, że ręczne dodawanie hosta wirtualnego jest dość męczące. Niby sprowadza się to tylko do dodania jednego wpisu w konfiguracji serwera oraz jednej linijki do pliku /etc/hosts, jednak na dłuższą metę może to być męczące. Można prościej? Oczywiście. Wystarczy zainstalować dnsmasq oraz odpowiednio skonfigurować webserver.

W tym wpisie pokażę, w jaki sposób ułatwiłem sobie pracę z wieloma projektami na lokalnym komputerze w odpowiedni sposób konfigurując środowisko programistyczne. Jako że aktualnie pracuję na serwerze www Apache w wersji 2.2 to na nim oprę swój przykład. Nic nie stoi jednak na przeszkodzie, żeby go zaadoptować na serwer Nginx lub inny.
Porada: wszystkie pliki konfiguracyjne wymagają praw roota do zapisu!

Instalacja i konfiguracja serwera WWW

MacOS ma świetny manager pakietów. Mówię tu o projekcie MacPorts (https://www.macports.org/). Jest to odpowiednik Debianowego apt-get, więc jeśli znasz to narzędzie poczujesz się jak w domu. Instalacja „apacza” sprowadza się do wydania polecenia

sudo port install apache2

w terminalu. Cały serwer instaluje się do lokalizacji

/opt/local/apache2

Tutaj znajdują się binarki i pliki konfiguracyjne. Na początku edytujemy plik

/opt/local/apache2/conf/httpd.conf

Odnajdujemy tu dyrektywę DocumentRoot i zmieniamy ją wedle uznania, u mnie na

DocumentRoot „/home/lukasz/workspace”

(Oczywiście katalog workspace należy utworzyć w swoim katalogu domowym). Parę linijek niżej znajduje się konfiguracja tego katalogu (dyrektywa Directory), w której należy podać tę samą ścieżkę co wyżej. Następnie należy odkomentować linijkę zawierającą wpis

Include conf/extra/httpd-vhosts.conf

W tym pliku zdefiniujemy swój wirtualny host. Tak więc otwieramy ten plik i wpisujemy przykładową treść:

NameVirtualHost *:80                                          
<VirtualHost *:80>                                            
        VirtualDocumentRoot /home/lukasz/workspace/%1/public/
        ServerName dev                                        
        ServerAlias *.dev                                     
        <Directory /home/lukasz/workspace/*/public/>          
		AllowOverride All                                  
        </Directory>
</VirtualHost>  

Co tu się dzieje? Już tłumaczę. Informujemy Apache, że chcemy, aby każdy katalog w naszym workspace traktował jako osobny host wirtualny. Nazwą tego hosta będzie nazwa katalogu z doklejoną domeną .dev. Tak więc dla katalogu /home/lukasz/workspace/test nazwą hosta będzie test.dev. Zwracam tu jeszcze uwagę na fakt, że wszystkie publiczne pliki („widoczne przez przeglądarkę”, a więc pliki js, css, obrazki etc. muszą znaleźć się w katalogu public).

Konfiguracja dnsmasq

Kolejnym krokiem jest skonfigurowanie usługi, która przetłumaczy nam adresty z domeny dev na odpowiedni adres ip (w naszym przypadku na 127.0.0.1). Ponownie w terminalu wydajemy polecenie

sudo port install dnsmasq

Po instalacji edytujemy plik konfiguracyjny (/opt/local/etc/dnsmasq.conf). W tym pliku umieszczamy następujące wpisy (możesz usunąć całą zawartość i wpisać tylko to):

resolv-file=/etc/resolv.conf
address=/dev/127.0.0.1   

Ostatnim krokiem jest stworzenie tzw. resolvera. W tym celu tworzymy katalog /etc/resolver:

sudo mkdir /etc/resolver

oraz plik, który wskaże serwerowi, jak ma przetłumaczyć naszą domenę:

sudo echo „nameserver 127.0.0.1” > /etc/resolver/dev

Zapisujemy wszystkie pliki konfiguracyjne i restartujemy usługi:

sudo port unload dnsmasq
sudo port load dnsmasq  
sudo port unload apache2
sudo port load apache2  

Możemy już przetestować naszą konfigurację. W tym celu zakładamy klika katalogów w naszym workspace:

mkdir -p ~/workspace/test1/public && echo „test1” > ~/workspace/test1/public/index.html
mkdir -p ~/workspace/isystems/public && echo „i-systems” > ~/workspace/isystems/public/index.html

Teraz wpisując w przeglądarce test1.dev zobaczymy „test1″, a wpisując isystems.dev zobaczymy „i-systems”.

Autorem tekstu jest Łukasz Wojtyczka.

Zephir – nowe narzędzie do tworzenia i utrzymywania rozszerzeń dla PHP

Ze(nd Engine) Ph(p) I(nte)r(mediate), czyli dzisiaj o nowym narzędziu do tworzenia i utrzymywania rozszerzeń dla PHP.

Niedawno odwiedziłem stronę: https://zephir-lang.com/

PHP is one of the most popular languages in use for the development of web applications. Dynamically typed and interpreted languages like PHP offer very high productivity due to their flexibility. Since version 4 and then 5, PHP is based on the Zend Engine implementation. This is a virtual machine that executes the PHP code from its bytecode representation. Zend Engine is almost present in every PHP installation in the world, with Zephir, you can create extensions for PHP running under the Zend Engine. PHP is hosting Zephir, so they obviously have a lot of similarities, however; they have important differences that give Zephir its own personality. For example, Zephir is more strict, and it could be make you less productive compared to PHP due to the compilation step.

Postanowiłem sprawdzić czy rzeczywiście następuje przyspieszenie. Jednym z najczęciej wykorzystywanych funkcjonalności w sklepie internetowym jest obliczanie ceny. W tym celu przepisałem jedną z naszych libek: https://packagist.org/packages/ayeo/price do formatu Zephira, skompilowałem i wykonałem test wydajności na prostym rachunku:

Wersja php:

1

Wersja z przekompilowanego rozszerzenia:

2

W każdej iteracji kwoty netto były losowane z przedziału od 10 do 100, działanie pozostawało te same. Poniżej wyniki:

3

Jednak nie kłamali: 3-krotnie szybszy kod 🙂

Autorem tekstu jest Marek Rode.

Ionic – idealne narzędzie do tworzenia hybrydowych aplikacji mobilnych

Dzisiejszy wpis będzie poświęcony narzędziu do tworzenia hybrydowych aplikacji mobilnych – Ionic. Zostanie przedstawiony sposób działania narzędzia i przejdziemy przez cały proces – od instalacji do uruchomienia.

Ionic to rozbudowane narzędzie, które przy pomocy Cordovy umożliwia tworzenie bogatych i w pełni funkcjonalnych aplikacji mobilnych.

Do zbudowania aplikacji w Ionic’u wykorzystujemy technologie webowe – Angular, HTML, CSS. Cordova odpowiedzialna jest za natywną część aplikacji – platformy, wtyczki, webview.

Połączenie tych dwóch technologii daje nam możliwość tworzenia hybrydowych aplikacji mobilnych, czyli połączenie części natywnej z częścią webową.
 Zaletami takiego zastosowania jest bardzo duża uniwersalność naszych aplikacji – pisząc raz, możemy aplikacje uruchamiać na wielu platformach np. iOS, Android, Windows lub jako aplikację webową na serwerze.

1. Instalacja


Przejdziemy najpierw krok po kroku przez proces instalacji środowiska.

a) Node.js


brew install node


b) Cordova


sudo npm install -g cordova


c) Ionic


sudo npm install -g ionic

2. Tworzenie projektu


Aby utworzyć projekt wpisujemy podaną komendę w terminalu.


ionic start {nazwa_projektu} {starter}

starter – to szablon, który zostanie wykorzystany przez framework do stworzenia naszego projektu. Możemy utworzyć pusty projekt wpisując „blank”. Lub skorzystać z szablonu z wbudowanym menu (podając „sidemenu”) czy zakładkami („tabs”).

Przykład:

ionic start myAwesomeApp tabs

Po wykonaniu tej operacji zostaną zainstalowane wszystkie potrzebne zależności.

3. Podział aplikacji


Struktura projektu wygląda następująco:

1

Kod źródłowy naszego programu znajduje się w katalogu src, wyjściowe zbudowane pliki w www, ikona oraz ekran startowy w resources, biblioteki w node_modules, dodatkowe skrypty w hooks, wtyczki z cordovy w plugins oraz środowiska platform w platforms (2 ostatnie katalogi tworzone są podczas wywołania akcji „build” i „run” czyli podczas budowania projektu lub przy ręcznym dodaniu tych składników).

4. Budowanie aplikacji


Aby zbudować projekt, należy wywołać akcję build lub run jeśli chcemy go od razu uruchomić.

ionic cordova run ios/android –prod –release
lub

ionic cordova build ios/android –prod –release

Framework najpierw zbuduje nasze źródła (część webową) do plików wyjściowych, które będą uruchamiane przez konkretny webview, a następnie wykona się proces budowania części natywnej dla iOS (wymagany jest system operacyjny OSX oraz Xcode) lub Android (Wymagana jest platforma JDK oraz Android SDK).

Po wykonaniu tych operacji w katalogu platforms znajdziemy zbudowany projekt.

a) dla iOS’a

1

b) dla Android’a

1

Te pliki posłużą nam do wgrania aplikacji na dane urządzenie.

5. Uruchamianie na urządzeniu

a) iOS

– Otwieramy nasz wcześniej zbudowany projekt *.xcodeproj.
– Wybieramy urządzenie na jakim uruchomimy naszą aplikację (fizyczne urządzenie lub emulator).

1

– Następnie klikamy przycisk „Run” (cmd + r), który powoduje kompilacje projektu i uruchomienie na wybranym urządzeniu.

1

b) Android


– Wpisujemy komendę


ionic cordova run android

Framework przy pomocy Android SDK zbuduje aplikację (plik .apk) oraz zainstaluje ją na wybranym urządzeniu lub emulatorze.

1

Podsumowanie

Jak widzimy Ionic pozwala nam w łatwy i szybki sposób tworzyć aplikacje mobilne. W tym artykule został przedstawiony bardzo prosty przykład wykorzystania narzędzia, nie zmienia to jednak faktu, że dzięki rozbudowanemu ekosystemowi frameworka np. Ionic Cloud, możemy wykorzystać narzędzie do budowania wysoce zaawansowanych aplikacji 🙂

Praktyczne wykorzystanie Ionic’a możecie sprawdzić w naszej autorskiej aplikacji mobilnej dedykowanej ecommerce.

Android
https://play.google.com/store/apps/details?id=pl.isystems.isklep

iOS
https://itunes.apple.com/us/app/i-sklep/id1169416679

Po więcej informacji na temat działania framework’a odsyłam na stronę Ionic’a 🙂
http://ionicframework.com/docs/

Autorem tekstu jest Kamil Moroń.

Optymalizacja przy pomocy blackfire.io

Optymalizacja kodu to czasochłonny i trudny temat. Przede wszystkim musimy znaleźć miejsca w aplikacji, które „pochłaniają” większość czasu procesora lub zajmują dużo pamięci. Aby to zrobić potrzebujemy narzędzia, które przygotuje nam profil wywołań metod/funkcji naszej aplikacji. W tym celu przedstawione zostanie narzędzie blackfire.io

Blackfire.io dostępne jest do pobrania z oficjalnej strony: https://blackfire.io/ Jest to narzędzie płatne, jednak istnieje opcja darmowego użytkowania, mocno ograniczona ale pozwalająca na podstawowe optymalizacje naszego kodu.

Po zainstalowaniu i sprawdzeniu poprawnego działania (wg instrukcji na stronie producenta) możemy przystąpić do stworzenia pierwszego profilu naszej aplikacji. Załóżmy, że chcemy sprawdzić co obciąża naszą stronę główną. Wywołujemy polecenie:
blackfire curl –samples=10 „http://localhost/”
Gdzie parametr ‘samples’ mówi o tym ile razy chcemy wywołać dany adres.

Po zakończeniu profilowania w konsoli wyświetli nam się krótkie podsumowanie. Nie to jest jednak najważniejsze. Przechodzimy na dashboard znajdujący się na stronie blackfire.io i wybieramy profil który powinien tam się pojawić:
AT01

Po lewej widzimy listę wywołań metod wraz z ich czasami. Listę tą możemy posortować wg czasu wywołania wliczającego podwywołania (incl.) lub wg czasu własnego wywołania (excl.) co jest bardziej dla nas interesujące ponieważ pokazuje jak długo konkretna metoda działa. Po prawej widzimy drzewo wywołań, gdzie kolorem czerwonym podkreślone są wywołania/ścieżki zajmujące najwięcej czasu żądania.

AT02
W tym przypadku widzimy, że funkcja curl_exec zajmowała średnio 3s czasu z każdego z naszych 10 pomiarów. Widzimy również że znaczna większość tego czasu poświęcona została dla GeoLocalizationService. Nie wdając się w szczegóły i zasadność rozwiązania, spróbujmy „zoptymalizować” to miejsce (dla przykładu usuwając to wywołanie :D). Robimy to i profilujemy kod ponownie:
AT03

Widzimy znaczną poprawę, curl_exec zajmuje w tym momencie tylko 250 ms. Oczywiście sama optymalizacja jest nie do końca właściwa (nie powinniśmy optymalizować przez usunięcie funkcjonalności :D), natomiast pokazuje jako przykład poprawne wykorzystanie blackfire.
Dodatkowym atutem tego narzędzia jest możliwość czytelnego pokazania zmian pomiędzy dwoma profilami:
AT04

Osobiście zachęcam do spróbowania przynajmniej raz z blackfire w celu optymalizacji. Jeżeli nie chcemy bawić się w zakładanie kont/instalowanie zewnętrznych narzędzi, dobrą alternatywą może być wbudowany w xdebug profiler (xdebuga chyba każdy ma) + dodatkowo narzędzie qcachegrind do wyświetlania profili.
Dodam, że blackfire bardzo pomógł nam w optymalizacji sklepu w ramach projektu „Struś pędziwiatr”.

Autorem tekstu jest Adam Tront

Wzorzec projektowy – Adapter

Dzisiejszy wpis będzie poświęcony tematyce inżynierii oprogramowania – zostanie opisany wzorzec projektowy Adapter. Zostanie wytłumaczone na czym on polega oraz przedstawione będzie jego zastosowanie w kontekście integracji z systemami ERP.

Adapter – co to jest?

Wzorzec Adapter jest to strukturalny wzorzec projektowy, znany jest również pod nazwą Wrapper (z ang. Opakowanie). Adapter powinien być używany w przypadku, 
gdy wykorzystanie istniejącej klasy jest niemożliwe ze względu na jej niekompatybilny interfejs. Innymi słowy służy do „opakowania” klas bądź bibliotek w taki sposób, 
aby zagwarantować jak największą uniwersalność w całym tworzonym systemie.

Schemat UML wzorca Adapter

Schemat UML wzorca Adapter

Adapter – jak go wykorzystać?

Zwykle adapter jest wykorzystywany w przypadku gdy korzystamy z jakiejś zewnętrznej biblioteki, której użycie jest problematyczne, np. metody zwracają typy które nie są zgodne z modelem aplikacji. Adapter idealnie wtedy nadaje się do opakowania takich metod aby zwracały typy zgodne z modelem. W integracji z systemami ERP używanie wzorca Adapter jest wręcz konieczne. Sposób w jaki jest to realizowane został przedstawiony na Rysunku1. Zazwyczaj korzystamy z gotowych bibliotek firm zewnętrznych, które udostępniają je wraz 
ze swoim systemem ERP. Aby ustandaryzować używanie tych bibliotek konieczne 
jest zastosowanie Adaptera. Tworząc ogólny interfejs udostępniający wymagane do integracji funkcje, np. pobieranie listy produktów, implementujemy go z wykorzystaniem metod udostępnionych przez zewnętrzną bibliotekę. Metody te zwracają dane w swoich zdefiniowanych typach, należy więc użyć ich w taki sposób aby utworzyć obiekty klasy jakie chcemy otrzymać (zdefiniowane w interfejsie). Następnie już tylko wywołujemy metody które udostępnia interfejs. Dzięki takiemu podejściu zagwarantowana jest duża skalowalność – mamy jeden ogólny interfejs który może być implementowany na wiele różnych sposobów 
w zależności od biblioteki – jeśli pojawia się nowy system ERP do integracji, wystarczy zaimplementować interfejs i w odpowiedni sposób opakować funkcjonalności biblioteki.

Podsumowanie

Na koniec kilka słów podsumowania. Adapter nadaje się wszędzie tam, gdzie wykorzystywane są zewnętrze biblioteki. Praktycznie zawsze w takiej sytuacji należy go użyć. Sama implementacja wzorca nie jest skomplikowana, po prostu tworzymy interfejs, który 
ma udostępniać funkcjonalność taką jaką my chcemy mieć. To w jaki sposób ją uzyskać 
z innych klas należy określić w implementacji tego interfejsu.

Autorem tekstu jest Mateusz Łysień.

file_exists » performance

Trywialny temat: porównanie czasu wykonania poszczególnych funkcji sprawdzających dostępność pliku.

Testy zostały przeprowadzone na wersji php:
1

W każdej iteracji funkcja sprawdzała jeden losowy plik spośród 20 tysięcy istniejących. Po każdym wykonaniu funkcji wywoływano funkcję clearstatcache celu opróżnienia cache. Wyniki prezentują się następująco:2

W zestawieniu znalazła się również funkcja stream_resolve_include_path ze względu na http://php.net/file_exists

Warning This function returns FALSE for files inaccessible due to safe mode restrictions. However these files still can be included if they are located in safe_mode_include_dir.

W sytuacji includowania to, że plik istnieje nie oznacza, że jest gotowy do odczytu. Poprawniejszym rozwiązaniem jest wykorzystanie: http://php.net/stream_resolve_include_path

Resolve filename against the include path according to the same rules as fopen()/ include.

Pozostałe wnioski pozostawiam czytelnikom 🙂

Autorem tekstu jest Marek Rode.