Fork me on GitHub

Witaj!

W Sieci można znaleźć wiele publikacji na temat PHP. Niestety, wiele z nich jest nieaktualnych, niekompletnych lub nie odnosi się do aktualnych dostępnych wersji. Wprowadza to wszechobecny zamęt i prowadzi nowych fanów tego języka na przysłowiowe manowce. Tak dalej być nie może. PHP: The Right Way jest przystępnym zbiorem najlepszych praktyk i standardów kodowania, a także linków do sprawdzonych i solidnych tutoriali pałętających się w czeluściach Internetu.

Tłumaczenia

PHP: The Right Way jest (lub niebawem będzie) przetłumaczony na wiele języków:

Uwaga

Nie istnieje żaden standardowy sposób, który określałby w jaki sposób powinieneś korzystać z PHP. Dokument ten ma jednakże na celu zebrać w jednym miejscu najlepsze praktyki, najważniejsze możliwości języka oraz inne cenne informacje i przeznaczony jest zarówno dla początkujących programistów, rozpoczynających swoją zabawę z PHP, jak dla zaawansowanych wyjadaczy, którzy zagłębiając się w jego lekturze będą mieli możliwość przemyślenia swoich dotychczasowych przyzwyczajeń bądź poznania najlepszych rozwiązań.

Dokument ten jest wciąż rozwijany oraz uzupełniany o kolejne materiały i przykłady. Jeżeli chciałbyś pomóc w jego rozwoju, bądź masz uwagi do bieżącego tłumaczenia, przeczytaj poniższy akapit.

Jak mogę pomóc?

Jeżeli chciałbyś/chciałabyś mieć wpływ na zawartość tego dokumentu lub po prostu chcesz powiedzieć światu o tej inicjatywie - zapraszamy!

Strona projektu w serwisie GitHub

Podziel się dobrą informacją!

PHP: The Right Way udostępnia banery reklamowe, które śmiało możesz umieścić na swojej stronie internetowej, aby pomóc nam promować tę inicjatywę wśród programistów PHP.

Obejrzyj dostępne banery

Na górę{.top}

Pierwsze kroki

Korzystaj z ostatniej stabilnej wersji

Jeżeli dopiero rozpoczynasz swoją przygodę z PHP, upewnij się, że korzystasz z ostatniej stabilnej wersji (obecnie PHP 7.1). PHP jest silnie rozwijane i twórcy tego języka wciąż dodają do niego nowe, przydatne funkcje. Mimo tego, że konwencja nadawania kolejnych numerów wersji języka może sugerować, że zmiany są niewielkie, w rzeczywistości różnice między kolejnymi wersjami są znaczące. Na stronach php.net dostępna jest obszerna, przetłumaczona na wiele języków dokumentacja zawierająca opis możliwości języka PHP, jak również spis wszystkich dostępnych funkcji i sposobów ich wywołania.

W środowiskach produkcyjnych najbardziej rozpowszechnionymi wersjami PHP są obecnie te z zakresu 5.x. Ostatnią wersją 5.x jest 5.6. Jest to nadal dobra opcja, ale jeśli jesteś odpowiedzialny za jakiś projekt PHP, to powinieneś jak najszybciej uaktualnić go do najnowszej stabilnej wersji, bo PHP 5.6 nie będzie otrzymywało poprawek bezpieczeństwa po roku 2018. Aktualizacja nie jest skomplikowana, ale należy uwzględnić kilka zmian, które nie są kompatybilne wstecznie. Informacje o dostępności funkcji i funkcjonalności w poszczególnych wersjach PHP dostępne są w podręczniku PHP.

Wbudowany serwer WWW

PHP 5.4 (oraz nowsze) posiadają własny, wbudowany w dystrybucję serwer WWW, więc jeżeli korzystasz z wersji PHP 5.4 lub nowszej, możesz łatwo rozpocząć naukę programownaia bez instalacji standardowego serwera HTTP, takiego jak Apache. Aby uruchomić serwer, wykonaj następujące polecenie w głównym katalogu swojego projektu:

> php -S localhost:8000

Instalacja na Maku

W systemie macOS PHP jest zainstalowane domyślnie, lecz nigdy nie jest to najświeższa wersja. +Wersja “Mavericks” posiada PHP 5.4.17, “Yosemite” - 5.5.9, “El Capitan” - 5.5.29 a “Sierra” 5.6.24.

Jest możliwość aktualizacji preinstalowanej wersji PHP do najnowszej - można to zrobić poprzez odpowiednie pakiety. Zalecamy instalację php-osx by Liip.

Możesz także skompilować PHP samodzielnie, ale wcześniej upewnij się, że masz zainstalowany Xcode lub “Command Line Tools for Xcode”, które możesz ściągnąć ze strony Mac Developer Center firmy Apple.

Istnieje również możliwość instalacji pakietu “all-in-one”, który zawiera PHP, serwer Apache oraz bazę MySQL wraz z graficznym interfejsem do zarządzania całym pakietem. Jeżeli interesuje Cię ta opcja, zainteresuj się projektem MAMP.

Instalacja w systemie Windows

PHP w systemie Windows można zainstalować na kilka sposobów. Pierwszym z nich jest instalacja binariów. Do wersji 5.3.0 można było korzystać z instalatora .msi, obecnie ten sposób instalacji nie jest już wspierany.

Do nauki i lokalnego rozwijania aplikacji opartych o PHP najlepiej użyć serwera WWW wbudowanego w dystrybucję. Używając go, nie musisz się martwić o jego konfigurację. Jeżeli potrzebujesz czegoś więcej, możesz użyć jednego z pakietów “all-in-one”, który sprawnie zainstaluje dedykowany serwer WWW, PHP oraz bazę danych MysQL. Najbardziej znanymi rozwiązaniami tego typu są Web Platform Installer, Zend Server CE, XAMPP oraz WAMP. Używając ich, pamiętaj o tym, że takie środowisko może różnić się od produkcyjnego, działającego np. na Linuksie.

Jeżeli chcesz stworzyć środowisko produkcyjne w systemie Windows, najlepszym rozwiązaniem jest użycie serwera IIS7, który uznawany jest obecnie za najszybszy i najbardziej stabilny serwer WWW dla Windows. Aby skonfigurować PHP na serwerze IIS7 możesz użyć pluginu phpmanager. Przydatne informacje możesz znaleźć na stronie http://php.iis.net.

Pamiętaj o tym, że rozwijanie aplikacji w systemie znacznie różniącym się od docelowego może prowadzić do problemów podczas instalacji aplikacji na serwerze produkcyjnym. Jeżeli tworzysz aplikację pod Windowsem, a uruchamiasz ją pod Linuksem, rozważ możliwość użycia maszyny wirtualnej. W tym celu zainteresuj się projektami Vagrant, a także Puppet lub Chef.

Na górę{.top}

Jak formatować kod

Społeczność zgromadzona wokół języka PHP jest relatywnie duża i zróżnicowana, dzięki czemu powstało wiele bibliotek, frameworków i komponentów. Typową praktyką stosowaną przez programistów PHP jest wybór kilku takich składników i stworzenie na bazie tego własnego projektu. Stąd istotną sprawą jest to, aby te biblioteki stosowały wspólne konwencje i styl kodowania.

Aby wyjść temu problemowi naprzeciw, Framework Interop Group (znane także jako ‘PHP Standards Group’) wypracowało serię rekomendacji dotyczących stylu kodowania znanych jako PSR-0, PSR-1, PSR-2 oraz PSR-4. Są one zbiorem konwencji i dobrych praktyk, których powinny trzymać się programiści tworząc swoje projekty. Już teraz konwencje te stosują m.in. takie projekty jak Drupal, Zend Framework, CakePHP, phpBB, AWS SDK, FuelPHP, czy Lithium. Oczywiście stosowanie tych zaleceń nie jest obowiązkowe, równie dobrze możesz tworzyć kod używając swojego własnego stylu.

Decydując się na używanie PSR, ułatwiasz potencjalnym programistom, którzy będę z Tobą współpracować, zrozumienie Twojego kodu. Struktura dokumentów PSR jest zorganizowana w ten sposób, że stosowanie PSR-1 wymusza stosowanie PSR-0, ale nie PSR-2, itd.

Aby sprawdzić czy Twój kod spełnia założenia PSR, możesz użyć projektu PHP_CodeSniffer z użyciem rozszerzenia phpcs-psr lub wtyczek do edytorów tekstowych sprawdzających poprawność stylu w locie, np.: wtyczka sublime-phpcs dla edytora Sublime Text. Aby automatycznie poprawić styl kodu możesz użyć jednego z narzędzi:

PHP_CodeSniffer użyty w linii poleceń

phpcs -sw --standard=PSR2 file.php

wyświetli listę błędów (odstępstw od standardu) wraz z informacją o sposobie usunięcia błędu. Pakiet PHP_CodeSniffer zawiera drugie polecenie - phpcbf - pozwalające automatycznie naprawić wykryte błędy:

phpcbf -w --standard=PSR2 file.php

PHP Coding Standards Fixer domyślnie naprawia błędy automatycznie, a z odpowiednimi parametrami (--dry-run i --diff) wyświetla podsumowanie proponowanych zmian nie zmieniając plików.

Kod powinien być pisany z wykorzystaniem angielskiego nazewnictwa. Komentarze powinny być pisane w języku zrozumiałym dla aktualnych oraz potencjalnych programistów.

Na górę{.top}

Rzut okiem na język

Paradygmaty programowania w PHP

PHP jest językiem, w którym możesz programować na wiele sposobów. Przez ostatnie lata mocno rozwinął swoje możliwości. W wersji 5.0 (2004) dodano zupełnie nowy model programowania obiektowego, w 5.3 (2009) wprowadzono m.in. anonimowe funkcje i przestrzenie nazw, a w 5.4 (2012) - traity.

Programowanie obiektowe

PHP posiada rozbudowany model programowania obiektowego, który obsługuje m.in klasy, klasy abstrakcyjne, interfejsy, dziedziczenie, konstruktory, klonowanie, czy wyjątki.

Programowanie funkcyjne

PHP od wersji 5.3 wspiera możliwość przypisania funkcji do zmiennej - są to tzw. funkcje anonimowe lub closure’y. Zarówno funkcje wbudowane, jak i te stworzone przez programistę, mogą być dzięki temu wywołane w sposób dynamiczny, przekazane jako argumenty wywołania innych funkcji lub nawet przez nie zwracane.

Funkcje mogą także wywoływać same siebie, czyli działać rekurencyjnie.

W PHP 5.4 dodano możliwość przypisania closure’a do zakresu obiektu w taki sposób, że mogą one być stosowane zamiennie z funkcjami anonimowymi praktycznie w każdej sytuacji.

Metaprogramowanie

PHP wspiera metaprogramowanie udostępniając mechanizmy takie jak Reflection API i magiczne metody - m.in. __get(), __set(), __call(), __callStatic(), __clone(), __toString() i __invoke(), które umożliwiają programiście wywołanie danego kodu podczas konkretnych zdarzeń w cyklu życia obiektu.

Przestrzenie nazw

Jak wspomniano wcześniej, społeczność PHP jest tworzona przez niezliczoną ilość programistów. Powoduje to, że może zdarzyć się sytuacja, w której dwie różne biblioteki użyją klasy o takiej samej nazwie. W takim przypadku pojawi się problem.

Naprzeciw temu problemowi wychodzą przestrzenie nazw, których działanie można porównać z funkcją katalogów w systemie plików. Tak samo jak dwa pliki o tej samej nazwie mogą istnieć w dwóch różnych katalogach, klasy o takich samych nazwach mogą istnieć w różnych przestrzeniach nazw.

Z tego powodu istotne jest, aby Twój kod był przypisany do własnej przestrzeni nazw. Dzięki temu jego elementy (klasy, funkcje, czy stałe) nie będą kolidowały z klasami bibliotek, których używasz. Traktuje o tym dokument PSR-0.

W grudniu 2013 roku PHP-FIG przygotowało kolejny standard: PSR-4, który pewnego dnia zastąpi standard PSR-0.

Biblioteka standardowa (SPL)

Biblioteka standardowa (SPL, Standard PHP Library) jest zbiorem klas i interfejsów, które zapewniają dostępność typowych struktur danych (stos, kolejka, kopiec, itp) oraz iteratorów zdolnych do trawersowania po nich. W SPL znajdziesz też funkcje i mechanizmy umożliwiające automatyczne ładowanie klas oraz klasy pomocnicze, przydatne przy tworzeniu rozwiązań opartych o wzorce projektowe, np. SplObserer, SplSubject).

Interfejs CLI (Command Line Interface)

PHP znajduje zastosowanie głównie przy tworzeniu aplikacji webowych, ale może być również użyteczny jako język skryptowy, uruchamiany z poziomu konsoli. Dzięki temu można łatwo automatyzować typowe zadania, jak testowanie jednostkowe, proces deploymentu, czy administrację aplikacją.

Skrypty uruchamiane z poziomu konsoli mają dostęp do całego kodu Twojej aplikacji i mogą go uruchamiać w ten sam sposób jak w przypadku wywołania z poziomu serwera WWW. Pamiętaj, aby nie umieszczać skryptów przeznaczonych do uruchomienia pod konsolą w publicznej części Twojego projektu.

Spróbuj uruchomić następujące polecenie z poziomu linii poleceń:

> php -i

Twoim oczom powinna ukazać się pełna konfiguracja PHP, zbliżona do tej, którą zwraca funkcja phpinfo.

Inną ciekawą opcją jest -a - umożliwia ona uruchomienie interaktywnej konsoli PHP, podobnej do tej z Ruby’ego, czy Pythona.

Aby zapoznać się z pełną listą opcji interfejsu konsolowego, zajrzyj na tę stronę.

Jeżeli argumentem wywołania polecenia php będzie plik z kodem źródłowym, zostanie on uruchomiony. Uruchamiając skrypt z poziomu konsoli otrzymujesz dostęp do dwóch zmiennych - $argc i $argv. Pierwsza z nich jest liczbą naturalną, reprezentującą ilość przekazanych argumentów wywołania, a druga tablicą z ich wartościami. Ponadto istnieje możliwość zwrócenia kodu wyjścia, aby poinformować powłokę, czy skrypt wykonał się poprawnie. Więcej informacji na temat kodów wyjścia znajdziesz tutaj.

Poniżej znajdziesz kod skryptu drukującego napis “Witaj, $imie” z możliwością podania imienia przez linię poleceń. Plik z przykładu nazywa się hello.php.

<?php
if($argc != 2) {
    echo "Usage: php hello.php [imię].\n";
    exit(1);
}
$imie = $argv[1];
echo "Witaj, $imie!\n";

A oto przykład wywołania powyższego skryptu:

> php hello.php
Usage: php hello.php [imię]
> php hello.php Marek
Witaj, Marek!

XDebug

Jednym z najbardziej użytecznych narzędzi podczas programowania jest debugger. Debugger pozwala na śledzenie wykonywania kodu i monitorowanie zawartości stosu. W PHP dostępny jest debugger o nazwie XDebug. Można go używać z poziomu IDE do śledzenia wykonywania kodu, a także wykorzystywać do profilowania aplikacji za pomocą KCacheGrind, czy tworzenia raportów pokrycia kodu testami w PHPUnit.

Debugger przydaje się tam, gdzie ręczny debug za pomocą funkcji print_r/var_dump nie daje rady.

Instalacja XDebuga może okazać się dość skomplikowana. Najważniejszą funkcjonalnością jest zdalne debuggowanie (“Remote Debugging”) - przydaje się, gdy tworzysz kod lokalnie, a testujesz go na wirtualnej maszynie, bądź na zdalnym serwerze.

Aby skorzystać z tej funkcji, należy zmodyfikować konfigurację vhosta w poniższy sposób:

php_value xdebug.remote_host "?.?.?.?"
php_value xdebug.remote_port "9000"

Wartości dyrektyw remote_host i remote_port powinny wskazywać na adres IP lokalnego komputera i port na którym nasłuchuje IDE. Po załadowaniu adresu z dodatkowym parametrem XDEBUG_SESSION_START o wartości 1 (np. http://your-website.example.com/index.php?XDEBUG_SESSION_START=1), IDE przechwyci bieżący stan wykonywanego skryptu umożliwiając kontrolę jego wykonywania. To bardzo ułatwia debuggowanie aplikacji.

Na górę{.top}

Zarządzanie zależnościami

PHP posiada tysiące bibliotek, frameworków i komponentów. Tworząc swój projekt wybierzesz prawdopodobnie kilka z nich - będą to jego zależności. Przez wiele lat PHP nie posiadał sprawnie działającego sposobu na zarządzanie zależnościami. Nawet jeżeli udało Ci się zestawić razem potrzebne Ci biblioteki, musiałeś ręcznie zadbać o ich dołączenie do projektu. Nigdy więcej.

PHP dysponuje dwoma niezależnymi systemami pakietów. Są nimi Composer i PEAR. Zastanawiasz się pewnie który wybrać. Otóż wszystko zależy od tego w jaki sposób chcesz go użyć.

Innymi słowy, pakiety Composera będą dostępne jedynie w projekcie, dla którego je przygotujesz, podczas gdy biblioteki PEARa będą dostępne dla wszystkich aplikacji w obrębie instalacji PHP. Mimo, że PEAR wydaje się być łatwiejszym podejściem, istnieje wiele przesłanek, aby zarządzać swoimi zależnościami per projekt, czyli używając Composera.

Composer i Packagist

Composer jest genialnym systemem wspomagającym zarządzanie zależnościami aplikacji w PHP. Wystarczy jeżeli wylistujesz swoje zależności w pliku composer.json, a narzędzie to, przy użyciu kilku prostych poleceń, automagicznie ściągnie odpowiednie wersje bibliotek i ich zależności oraz odpowiednio skonfiguruje autoloadera.

Za pomocą Composera można zainstalować wiele znanych bibliotek. Ich listę znajdziesz na stronie projektu Packagist - oficjalnego repozytorium bibliotek kompatybilnych z tym systemem.

Instalacja Composera

Composera możesz zainstalować lokalnie (w katalogu Twojego projektu) lub globalnie (np. w /usr/local/bin). Aby móc użyć tego narzędzia, wejdź do jego katalogu swojego projektu i wydaj polecenie:

curl -s https://getcomposer.org/installer | php

Polecenie to ściągnie do bieżącego katalogu plik composer.phar, który będziesz mógł uruchomić za pomocą PHP, aby zarządzać zależnościami. Pamiętaj, że przekierowanie zawartości strony bezpośrednio do interpretera PHP może nie być bezpieczne - przed wykonaniem tego polecenia zapoznaj się z kodem znajdującym się pod adresem http://getcomposer.org/installer.

Aby zainstalować Composera dla wszystkich użytkowników, wystarczy jeżeli przeniesiesz ściągnięty plik composer.phar do współdzielonego katalogu, np. /usr/local/bin, zmieniając jego nazwę na composer (sudo mv composer.phar /usr/local/bin/composer).

Ręczna instalacja Composera

Ręczna instalacja Composera jest bardziej skomplikowanym procesem, gdyż sam musisz sprawdzić swój system, aby upewnić się, że spełnia on wymagania stawiane przez tę aplikację. Instalacja automatyczna sprawdza: - czy używasz odpowiedniej wersji PHP, - czy rozszerzenie phar jest zainstalowane, - czy uprawnienia do katalogów są odpowiednie, - czy nie zostały zainstalowane problematyczne rozszerzenia PHP, - oraz czy plik php.ini zawiera odpowiednie ustawienia.

Aby pobrać Composera ręcznie, wykonaj następujące polecenia:

curl -s https://getcomposer.org/composer.phar -o $HOME/local/bin/composer
chmod +x $HOME/local/bin/composer

Ścieżka $HOME/local/bin (lub dowolna inna którą wybierzesz) powinna znajdować się w zmiennej środowiskowej $PATH, dzięki czemu będziesz miał możliwość skorzystania z polecenia composer zamiast php composer.phar.

Jak definiować i instalować zależności

Najpierw stwórz plik composer.json w katalogu głównym swojego projektu i umieść w nim odpowiednie wpisy. Poniższy przykład demonstruje jak przy użyciu Composera zainstalować projekt Twig. W pliku composer.json umieść poniższą zawartość:

{
    "require": {
        "twig/twig": "1.8.*"
    }
}

A następnie, będąc w tym samym katalogu, uruchom poniższe polecenie:

php composer.phar install

Efektem działania będzie ściągnięcie odpowiedniej wersji projektu Twig do katalogu vendors/ oraz odpowiednie skonfigurowanie autoloadera. Aby z niego skorzystać, musisz dołączyć plik vendor/autoload.php do swojego skryptu:

<?php
require 'vendor/autoload.php';

Od teraz możesz korzystać z klas dostarczonych przez bibliotekę.

PEAR

Innym, zdecydowanie starszym menadżerem pakietów, jest PEAR. Działa on mniej więcej w ten sam sposób, co Composer i także jest godny zainteresowania.

Strona projektu PEAR.

Na górę{.top}

Praktyki kodowania

Wyjątki

Wyjątki dostępne są w większości języków programowania, lecz programiści PHP często je pomijają. Języki takie jak Ruby często używają wyjątków. Za każdym razem, gdy coś pójdzie nie tak, nieważne, czy jest to problem z wykonaniem żądania HTTP, zapytania SQL, czy nawet ze znalezieniem pliku, Ruby rzuca wyjątek. Dzięki temu z łatwością można odnaleźć przyczynę problemu.

W PHP niestety nie ma tak dobrze. Funkcja file_get_contents() w przypadku nieznalezienia żądanego pliku zwraca false i komunikat błędu. Wiele starych frameworków, takich jak CodeIgniter w przypadku błędu zwraca po prostu false i loguje komunikat do swojego własnego źródła, w najlepszym razie dając Ci do dyspozycji metodę a’la $this->upload->get_error(), abyś sprawdził sobie co poszło nie tak. Problemem jest to, że musisz o tym wiedzieć lub szukać rozwiązania w dokumentacji, zamiast otrzymać jasny komunikat w postaci wyjątku.

Innym problemem jest fakt, że zwykle w przypadku błędu aplikacje wyświetlają komunikat błędu na stronie i kończą wykonywanie skryptu przez exit, przez co developerzy tracą możliwość dynamicznego obsłużenia takiego przypadku. Naprzeciw temu wychodzą wyjątki, które informują dewelopera o problemie i pozwalają mu podjąć odpowiednie kroki. Przykład:

<?php
$email = new Fuel\Email;
$email->subject('Mój temat');
$email->body('Jak się masz?');
$email->to('guy@example.com', 'Ktoś');

try
{
    $email->send();
}
catch(Fuel\Email\ValidationFailedException $e)
{
    // Walidacja danych wejściowych nie powiodła się
}
catch(Fuel\Email\SendingFailedException $e)
{
    // Aplikacja nie była w stanie wysłać maila
}

Wyjątki w SPL

Wyjątek sam w sobie nie ma żadnego konkretnego znaczenia i najprostszym sposobem na zmianę tego stanu rzeczy jest nadanie mu nazwy:

<?php
class ValidationException extends Exception {}

To pozwala na dodanie kilku bloków catch i obsługę różnych wyjątków w odmienny sposób. Biblioteka SPL dostarcza kilka typów wyjątków, których możesz używać w swojej aplikacji. Jest to między innymi wyjątek BadFunctionCallException wyrzucany w przypadku wywołania złej funkcji, czy InvalidArgumentException, którego możesz użyć w przypadku przekaaznia nieprawidłowego argumentu do funkcji czy metody. Pełną listę wyjątków, które dostarcza SPL znajdziesz w manualu.

Data i czas

W PHP istnieje wbudowana klasa DateTime, która dostarcza spójny, obiektowy interfejs do zarządzania datami i czasem. Dzięki niej możesz łatwo wykonywać operacje takie jak odczyt, zapis, porównywanie oraz różne obliczenia, nawet w wielu strefach czasowych. PHP oferuje również zwykłe funkcje, które potrafią wykonywać takie operacje, lecz wiodły one prym w starszych dystrybucjach, gdzie DateTime nie było jeszcze dostępne.

Aby uzyskać obiekt klasy DateTime zawierający bieżący czas, należy po prostu użyć konstrukcji new \DateTime; aby użyć określonej daty - należy skorzystać ze statycznej metody fabrykującej createFromFormat(). Metoda format() potrafi natomiast skonwertować czas zapisany w obiekcie z powrotem na odpowiednio sformatowany ciąg znaków.

<?php
$raw = '22.11.1968';
$start = \DateTime::createFromFormat('d.m.Y', $raw);

echo "Data rozpoczęcia: " . $start->format('Y-m-d') . "\n";

Operacje arytmetyczne na obiekcie DateTime najłatwiej wykonuje się za pomocą klasy DateInterval. DateTime posiada metody add() i sub(), które przyjmują obiekt klasy DateInterval jako argument - dzięki temu możesz zapomnieć o problemach związanych ze strefami czasowymi oraz istnieniem czasu letniego i zimowego. Przykładowo, aby obliczyć interwał czasu między dwiema datami, możesz użyć metody diff(). Zwraca ona obiekt DateInterval, który bez zbędnych obliczeń zamienisz na zrozumiały dla użytkownika ciąg znaków.

<?php
// stwórz kopię obiektu $start i dodaj do niego miesiąc i 6 dni
$end = clone $start;
$end->add(new \DateInterval('P1M6D'));

$diff = $end->diff($start);
echo "Różnica: " . $diff->format('%m miesiąc, %d dni (razem: %a dni)') . "\n";
// Różnica: 1 miesiąc, 6 dni (razem: 37 dni)

Stosując obiekty DateTime możesz używać zwykłych operatorów porównania:

<?php
if($start < $end) {
    echo "Rozpoczęcie ma miejsce przed zakończeniem!\n";
}

Ostatni przykład pokazuje użycie klasy DatePeriod, która służy do iterowania po liście powtarzających się zdarzeń. Przekazując do jego konstruktora dwa obiekty DateTime (początek i koniec) oraz interwał czasowy, otrzymamy iterator zawierający listę wszystkich zdarzeń między nimi.

<?php
// wyświetl listę wszystkich czwartków między datami $start i $end
$periodInterval = \DateInterval::createFromDateString('first thursday');
$periodIterator = new \DatePeriod($start, $periodInterval, $end, \DatePeriod::EXCLUDE_START_DATE);
foreach($periodIterator as $date)
{
    // wyświetl datę
    echo $date->format('m/d/Y') . " ";
}

Wzorce projektowe

Wzorce projektowe bywają bardzo pomocne podczas tworzenia aplikacji. Dzięki ich użyciu, prościej jest zarządzać swoim kodem, a innym deweloperom - zrozumieć jak działają jego wewnętrzne mechanizmy.

Wiele popularnych frameworków PHP implementuje wzorce projektowe. Jeżeli używasz któregoś z nich w swojej aplikacji, do Ciebie należy jedynie podążanie za nimi w kodzie swojej aplikacji. Jeżeli budujesz coś własnego od zera, będziesz musiał znaleźć i dopasować wzorce, które odpowiadają strukturze Twojej aplikacji.

Na górę{.top}

Bazy danych

Tworząc aplikacje webowe, wielokrotnie staniesz przed koniecznością przechowania pewnych informacji. Służą do tego bazy danych. PHP wspiera wiele różnych silników baz danych. Zalecanym sposobem komunikacji z bazami danych do wersji 5.1 były natywne sterowniki, takie jak mysql, mysqli, pgsql, itd.

Sterowniki te sprawują się dobrze, o ile łączysz się z tylko jednym rodzajem bazy danych, np. MySQL, czy MSSQL, gdyż każdy z nich posiada inne API, a nauka każdego z nich szybko może się okazać bezsensownym nakładem czasu. Dodatkowo, sterownik mysql nie jest już aktywnie rozwijany i od wersji PHP 5.4.0 ma status “Long term deprecation”, co oznacza, że wkrótce może zostać usunięty z PHP. Jeżeli obecnie używasz w swojej aplikacji funkcji mysql_connect(), czy mysql_query(), zapewne wkróce staniesz przed problemem przepisania tej części. Aby tego uniknąć, zaleca się stosowanie obiektowych rozszerzeń, takich jak mysqli lub PDO.

PDO

PDO jest bazodanową warstwą abstrakcji dostępną od PHP 5.1.0, która dostarcza obiektowy interfejs do komunikacji z wieloma silnikami baz danych. PDO nie tłumaczy Twoich zapytań SQL ani nie emuluje brakujących funkcjonalności; jest natomiast biblioteką umożliwiającą łączenie się do wszystkich obsługiwanych przez siebie baz danych przez jedno wspólne API, co jest doskonałym rozwiązaniem dla aplikacji w których osoba instalująca ją decyduje o typie silnika.

Co ważne, PDO pozwala na przekazywanie parametrów do zapytania SQL bezpośrednio z żądania ($_GET, $_POST). Nie musisz martwić się już o ataki SQL injection, gdyż biblioteka w odpowiedni sposób zabezpieczy ich wartości, aby nie były niebezpieczne. Dzieje się to dzięki tzw. “prepared statements” (PDO::prepare()) i wstrzykiwaniu parametrów przy użyciu metody bindParam().

Spójrzmy na typowy przykład. Twój skrypt otrzymuje numeryczne ID w parametrze GET. To ID uzywane jest później w zapytaniu SQL, aby wyciągnąć z bazy informacje na temat konkretnego rekordu. Poniżej przedstawiony jest kod, który nie korzysta z “prepared statements”:

<?php
$pdo = new PDO('sqlite:users.db');
$pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NIE!

Cóż, ten kod jest tragiczny. Parametr id wstrzykiwany jest do zapytania SQL prosto z żądania ($_GET['id']), co umożliwia wykonanie ataktu SQL injection, a w efekcie wykonanie dowolnego zapytania SQL na Twojej bazie danych. Aby tego uniknąć, powinieneś zabezpieczyć wartość tego parametru. Dzięki bindParam(), operacja zabezpieczenia wykona się automatycznie:

<?php
$pdo = new PDO('sqlite:users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); //<-- Automatyczne zabezpieczenie wartości parametru
$stmt->execute();

To jest poprawny kod. PDO przy użyciu metody bindParam() zabezpiecza w odpowiedni wartość parametru uniemożliwiając wykonanie ataku SQL injection.

Warstwy abstrakcji

Sporo frameworków posiada własną warstwę abstrakcji bazy danych. Niektóre z nich bazują na PDO, inne nie. Często emulują funkcjonalności niedostępne w danym silniku poprzez opakowywanie zapytań w metody. Jest to oczywiście pewien narzut czasowy, ale jeżeli Twoja aplikacja ma działać jednocześnie np. na MySQL, PostgreSQL i SQLite, czasem przejrzystość kodu jest ważniejsza niż niewielki narzut.

Niektóre z tych warstw zostały napisane z uwzględnieniem standardu przestrzeni nazw PSR-0, dzięki czemu mogą być użyte w dowolnej aplikacji napisanej w PHP.

Na górę{.top}

Bezpieczeństwo

Bezpieczeństwo aplikacji webowych

Są na świecie dranie, którzy chcieliby wykorzystać Twoją aplikację do niecnych celów. Jako deweloper, powinieneś być świadomy zagrożeń, które czyhają z ich strony i w odpowiedni sposób zabezpieczyć swoją aplikację, aby ich uniknąć. Na szczęście dobrzy ludzie z projektu The Open Web Application Security Project (OWASP) przygotowali obszerną listę potencjalnych zagrożeń wynikających z dostępności Twojej aplikacji w Internecie wraz z informacjami o sposobach zabezpieczenia przez nimi. Jest to lektura obowiązkowa dla każdego dewelopera PHP chcącego pisać bezpieczne aplikacje webowe.

Kodowanie haseł za pomocą Bcrypt

Każdy programista napisze pewnego dnia aplikację, w której jedną z funkcjonalności będzie możliwość zalogowania się użytkownika. W takiej aplikacji, dane autoryzacyjne (login i hasło) zwykle przechowywane są w bazie danych, aby za ich pomocą zautentykować użytkownika. W takim przypadku bardzo istotną kwestią jest odpowiednie zakodowanie (zahashowanie) zapisanych haseł, aby uniknąć sytuacji, w której po ataku hackerskim na bazę danych, konta Twoich użytkowników pozostaną dostępne włamywaczom.

Na szczęście w PHP wbudowany jest prosty, acz skuteczny mechanizm hashowania dowolnych danych - Bcrypt. Po zastosowaniu go, otrzymujemy skrót, na podstawie którego nie ma możliwości odgadnięcia pierwotnej postaci zakodowanego ciągu znaków.

w PHP dostępnych jest kilka bibliotek bazujących ba Bcyrpt, których móżesz użyć w swojej aplikacji.

Filtrowanie danych

Nigdy, przenigdy nie ufaj zewnętrznym danym wprowadzonym do Twojego kodu. Zawsze waliduj i zabezpieczaj je przed użyciem. Możesz użyć do tego funkcji filter_var() i filter_input(), które pomagają w tych czynnościach - potrafią przykładowo w prosty sposób sprawdzić poprawność składniową wprowadzonego przez użytkownika adresu e-mail.

Zewnętrzne dane mogą znaleźć się wszędzie: głównym ich źródłem są tablice $_GET i $_POST zawierające parametry żądania. Niektóre wartości w tablicy $_SERVER pochodzą wprost z nagłówków, które wysyła użytkownik, czy fopen('php://input', 'r') - ciało żądania HTTP. Pamiętaj, że zewnętrzne dane to nie tylko dane z formularzy wysłanych przez użytkownika. Pliki, które ściągasz, dane sesji, ciasteczka, czy nawet dane z zewnętrznych webservice’ów powinny być traktowane jako dane, którym nie można ufać.

Z uwagi na to, że zewnętrzne dane mogą być przechowywane w bazach danych, należy pamiętać o tym, żeby przy ich odczycie również zadbać o ich zabezpieczenie. Za każdym razem, gdy próbujesz użyć takich danych zadaj sobie pytanie, czy są one odpowiednio zabezpieczone i czy można im ufać.

Sposób zabezpieczania zewnętrznych danych zależy od sposobu ich użycia. Przykładowo gdy chcesz użyć danych pochodzących od użytkownika w HTML’u, musisz zadbać o usunięcie bądź zamianę znaczników sterujących, takich jak ‘<’, ‘>’ na odpowiednie encje HTML, gdyż w przeciwnym razie odpowiednio spreparowany ciąg znaków może uruchomić skrypt JS, co może być bardzo opłakane w skutkach - może przykładowo pomóc w przejęciu sesji użytkownika. Taki rodzaj ataku to XSS (Cross-Site Scripting).

Innym przykładem jest przekazywanie danych od użytkownika jako fragment lub całość komendy do wykonania z poziomu linii poleceń. Nieodpowiednie zabezpieczenie takich danych przed użyciem w ten sposób może doprowadzić do wykonania niepożądanego polecenia, co może być poważnym zagrożeniem bezpieczeństwa aplikacji i/lub systemu na którym ona działa. Aby bezpiecznie przekazać takie dane do wiersza poleceń, zabezpiecz je za pomocą funkcji escapeshellarg().

Niebezpieczeństwo może czyhać również tam, gdzie za pomocą danych z zewnątrz ustalasz ścieżkę w systemie plików. Atakujący może wykorzystać to poprzez odpowiednią zmianę przekazanych wartości. Twoja aplikacja wczyta wtedy inny plik niż powinna, co może spowodować wyciek prywatnych danych lub pomóc w przeprowadzeniu innego ataku. Aby zabezpieczyć się przed tym, usuwaj “/”, “..” i tzw. “null bytes” ze zmiennych przy użyciu których ustalasz ścieżkę pliku do wczytania.

Zabezpieczanie danych z zewnątrz (escaping)

Dane pochodzące z zewnątrz mogą posiadać niebezpieczne znaki. Aby bezpiecznie się nimi posługiwać w aplikacji (np. aby bezpiecznie skorzystać z danych wejściowych w HTML’u bądź zapytaniu SQL), należy się ich pozbyć. Proces ten nazywany jest escapingiem.

W przypadku zapytań SQL najlepszym sposobem na automatyczne zabezpieczenie się przez niebezpiecznymi znakami jest użycie PDO, które zrobi to za Ciebie. Jeżeli chodzi o HTML, częstym wyzwaniem jest konieczność dopuszczenia kilku wybranych tagów, aby umożliwić użytkownikowi proste formatowanie wpisanego tekstu. W takim przypadku jednym z wyjść jest użycie formatowania Markdown lub BBCode, bądź bibliotek takich jak HTML Purifier.

Lista filtrów escape’ujących

Walidacja

Dzięki walidacji możesz upewnić się, że wprowadzone przez użytkownika dane są tym, czego się spodziewasz. Dobrym przykładem jest walidacja danych takich jak adres e-mail, numer telefonu, czy wiek, wprowadzonych w formularzu rejestracji.

Lista filtrów walidujących

Pliki konfiguracyjne

Jeżeli Twoja aplikacja używa zewnętrznych plików konfiguracyjnych, pamiętaj, że nie powinny być one dostępne dla zewnętrznego świata. Zalecane jest użycie jednego z poniższych sposobów ich zabezpieczenia:

register_globals

UWAGA: Od wersji PHP 5.4.0 dyrektywa register_globals została usunięta i nie ma możliwości korzystania niej. Jej dostępność w wersjach >= 5.4.0 ogranicza się do wyświetlenia odpowiedniego komunikatu w przypadku omyłkowego użycia.

W poprzednich wersjach PHP, po włączeniu dyrektywy register_globals, zmienne pochodzące od użytkownika (m.in. $_POST, $_GET i $_REQUEST) były “spłaszczane” do zwykłych zmiennych dostępnych w globalnej zakresie widoczności. To w łatwy sposób mogło prowadzić do problemów bezpieczeństwa, gdyż aplikacja nie była w stanie stwierdzić skąd pochodzą wartości poszczególnych zmiennych.

Przykładowo, po włączeniu register_globals, zmienna $_GET['foo'] byłaby dostępna jako $foo, co może nadpisać inną zmienną $foo i powodować problemy.

Podsumowując, jeżeli używasz PHP < 5.4.0 upewnij się, że dyrektywa register_globals ma wartość off.

Raportowanie błędów

Wyświetlanie błędów jest pomocne przy szukaniu problematycznych miejsc w Twojej aplikacji, ale ma jeden poważny minus: eksponuje systemowe, być może kluczowe z punktu widzenia bezpieczeństwa, informacje całemu światu. Pamiętaj o tym, że środowisko produkcyjne (live) powinno być skonfigurowane pod tym względem inaczej niż deweloperskie.

Środowisko deweloperskie

W środowisku deweloperskim lub testowym wyświetlanie komunikatów błędów może być przydatne podczas śledzenia problemów z aplikacją. W tym środowisku powinieneś skonfigurować raportowanie błędów w ten sposób:

Za php.net:

Passing in the value -1 will show every possible error, even when new levels and constants are added in future PHP versions. The E_ALL constant also behaves this way as of PHP 5.4.

Poziom raportowania E_STRICT jest dostępny od wersji 5.3.0 nie będąc częścią poziomu E_ALL. W wersji 5.4.0 zmieniono to zachowanie i E_STRICT jest częścią E_ALL. Co oznacza to dla programisty? To, że jeżeli potrzebuje wyświetlać wszystkie możliwe błędy w 5.3.0, należy użyć wartości -1 lub E_ALL | E_STRICT.

Podsumowując:

Środowisko produkcyjne

W środowisku produkcyjnym wszystkie błędy powinny być ukryte i logowane do zewnętrznego pliku. W tym środowisku powinieneś skonfigurować raportowanie błędów w ten sposób:

Aby uzyskać więcej informacji na temat funkcji kontrolujących sposób raportowania błędów, zajrzyj do manuala:

Na górę{.top}

Testowanie

Pisanie testów automatycznych do dobra praktyka zwiększająca prawdopodobieństwo, że Twoja aplikacja będzie dobrze zbudowana. Uruchamiając testy automatyczne podczas kodowania upewniasz się, że zmiany, które wprowadzasz nie psują innych rejonów aplikacji. Korzystaj z nich, jeżeli możesz.

Istnieje kilka sposobów automatycznego testowania kodu aplikacji napisanych w PHP. Każdy z nich ma na celu zredukowanie nakładu na ręczne testowanie, co oczywiście przekłada się na mniejsze zespoły testowe, a w efekcie do ograniczenia kosztów projektu.

Test-Driven Development

Cytując Wikipedię:

Test-driven development (TDD) jest techniką tworzenia oprogramowania, która polega na wielokrotnym powtarzaniu kilku kroków: najpierw programista pisze automatyczny test sprawdzający dodawaną funkcjonalność. Test w tym momencie nie powinien się udać. Później następuje implementacja funkcjonalności. W tym momencie wcześniej napisany test powinien się udać. W ostatnim kroku, programista dokonuje refaktoryzacji napisanego kodu, żeby spełniał on oczekiwane standardy. Technika została stworzona przez Kenta Becka. Można jej też używać do poprawiania istniejącego kodu.

Istnieje kilka sposób testowania aplikacji, których możesz użyć podczas rozwijania swojej aplikacji.

Testy jednostkowe

Testy jednostkowe są techniką, która umożliwia sprawdzenie, czy funkcje, klasy i metody działają tak jak powinny - przez cały cykl ich życia. Sprawdzanie ich wewnętrznej logiki odbywa się poprzez ich wywoływanie z różnymi parametrami wejściowymi i badaniu ich odpowiedzi za pomocą odpowiednich asercji. Jeszcze dokładniejsze wyniki testów oraz bardziej kompletne pokrycie kodu testami można uzyskać dzięki wstrzykiwaniu zależności oraz korzystaniu z “mocków”.

Kiedy tworzysz klasę lub funkcję, powinieneś napisać test jednostkowy pokrywający i testujący zachowanie, które powinna posiadać. Najprostszym przykładem jest stworzenie testu, który sprawdzi, czy dla poprawnych danych wejściowych funkcja/metoda działa prawidłowo, a dla złych - odpowiednio to obsługuje. Dzięki temu wykonując kolejne zmiany i refaktoryzacje masz pewność, że kod wciąż działa tak jak powinien.

Testy jednostkowe znajdują zastosowanie również w open-source - dzięki nim możesz w łatwy sposób pokazać, że dana funkcjonalność nie działa prawidłowo, a następnie po wprowadzeniu poprawki sprawdzić, że ona faktycznie działa. Jeżeli prowadzisz projekt, w którym korzystasz z tzw. “pull requests”, zdecydowanie powinieneś wymagać wykonania odpowiednich testów jednostkowych.

PHPUnit jest najbardziej znanym frameworkiem, dzięki którym łatwo rozpoczniesz korzystanie z testów jednostkowych. Są również alternatywy:

Testy integracyjne

Cytując Wikipedię (polskie tłumaczenie):

Testowanie integracyjne, zwane także Integracją i Testowaniem (ang. Integration and Testing, “I&T”) jest fazą produkcji oprogramowania polegającą na automatycznym testowaniu odpowiednich grup modułów jako całość. Testy integracyjne wykonuje się zwykle po wykonaniu odpowiednich testów jednostkowych, a przed testami funkcjonalnymi. Testowanie integracyjne odbywa się na modułach, które zostały przetestowane jednostkowo. Moduły grupuje się w większe zbiory, na których stosuje się odpowiednie testy ujęte w planie testu integracyjnego i dostarcza się zintegrowany produkt, gotowy do testowania funkcjonalnego.

Proces wykonywania testów integracyjnych rządzi się zasadami podobnymi do testowania jednostkowego, więc do ich wykonywania możesz używać tych samych narzędzi.

Testy funkcjonalne

Czasami znane również jako testy akceptacyjne. W odróżnieniu od testów jednostkowych, zamiast konkretnych fragmentów kodu, testują one pełną aplikację. Takie testy zwykle korzystają z rzeczywistych danych i symulują zachowanie prawdziwych użytkowników.

Narzędzia do testów funkcjonalnych

Behavior Driven Development

Istnieją dwa rodzaje BDD (Behavior-Driven Development): SpecBDD i StoryBDD. Pierwszy z nich charakteryzuje się technicznym podejściem, gdzie istotny jest kod i jego zachowanie, podczas gdy drugi reprezentuje podejście biznesowe, gdzie najważniejszą kwestią jest to jak produkt będzie funkcjonował z perspektywy klienta. W PHP dostępne są frameworki wspierające oba te typy.

W StoryBDD piszesz zrozumiałe dla człowieka historyjki, które opisują zachowanie Twojej aplikacji. Są one później uruchamiane jako testy aplikacji. Frameworkiem, który wspiera taki typ testowania jest Behat, inspirowany projektem Cucumber dla Ruby’ego. Do opisywania historyjek w Behat używa się języka Gherkin DSL (Gherkin Domain Specific Language).

W SpecBDD piszesz natomiast specyfikacje opisujące w jaki sposób powinien zachowywać się Twój kod. Zamiast testować funkcję, czy metodę, opisujesz jak powinna się zachowywać. Ten typ BDD wspierany jest przez framework PHPSpec, który z kolei inspirowany jest projektem RSpec project, także dla Ruby’ego.

Linki

Dodatkowe narzędzia

Oprócz frameworków wspomagających testowanie istnieje również wiele innych narzędzi i bibliotek przydatnych podczas testowania aplikacji.

Linki

Na górę{.top}

Serwery i deployment

Aplikacje napisane w PHP mogą być deployowane na serwery produkcyjne na wiele różnych sposobów.

Chmura

Chmura, czyli PaaS (skrót od Platform as a Service), dostarcza pełną architekturę, której wymaga Twoja aplikacja PHP, aby być dostępna w Sieci. Oznacza to, że za pomocą kilku kliknięć jesteś w stanie uruchomić takie środowisko, a nawet zainstalować odpowiednie frameworki, czy biblioteki.

Ostatnimi czasy, głównie ze względu na łatwość skalowania aplikacji, rozwiązania oparte o chmurę zdobywają coraz większą popularność. Listę dostawców rozwiązań PaaS znajdziesz w rozdziale linki;

Serwery wirtualne lub dedykowane

Jeżeli potrafisz administrować serwerem bądź planujesz naukę w tym kierunku, zainteresuj się serwerami wirtualnymi. Dzięki nim masz możliwość skonfigurowania każdego detalu swojego środowiska produkcyjnego.

nginx i PHP-FPM

PHP potrafi dobrze współdziałać z serwerem nginx przy użyciu wbudowanego managera procesów FastCGI (FPM). Nginx jest lekkim i szybkim serwerem WWW, który zużywa znacznie mniej zasobów maszyny niż Apache, przez co potrafi obsłużyć więcej jednoczesnych procesów.

Apache i PHP

PHP i Apache mają za sobą długą historię. Serwer ten cechuje się łatwą, a zarazem dość obszerną konfiguracją, a także posiada wiele modułów rozszerzających jego możliwości. Na serwerach hostingowych jest często wybierany jako platforma pod popularne aplikacje open-source (np. Wordpress), czy aplikacje bazujące na frameworkach. Apache jednakowoż podczas pracy zużywa więcej zasobów serwera, przez co nie może obsłużyć tak wielu jednoczesnych połączeń, jak jego konkurent, nginx.

Istnieje kilka możliwości zainstalowania PHP na serwerze Apache. Najczęstszym wyborem jest prefork MPM (od Multi-Processing Modules) i moduł mod_php5. Jest to najszybszy sposób, który wymaga relatywnie niewielkiego nakładu pracy administracyjnej i jest najlepszym podejściem dla osób, które wolą ten czas przeznaczyć na kodowanie. Minusem jest fakt, że mod_php5 zużywa więcej zasobów, co może wpłynąć na szybkość działania.

Jeżeli chcesz wycisnąć z Apache’a nieco więcej szybkości oraz stabilności działania, możesz użyć tego samego systemu FPM, który współdziała z serwerem nginx i uruchomić mpm_worker (http://httpd.apache.org/docs/2.4/mod/worker.html) lub mpm_event z mod_fastcgi lub mod_fcgid. Aplikacje uruchomione w takiej konfiguracji będą działać szybciej, ale jej instalacja będzie wymagała większego nakładu pracy.

Serwery hostingowe

PHP dzięki swojej popularności jest szeroko wspierany na serwerach hostingowych na całym świecie. Mówiąc szczerze, trudno w dzisiejszych czasach znaleźć ofertę bez wsparcia dla tego języka. Liczbę ofert godnych zainteresowania zmniejszy na pewno ważne kryterium - numer zainstalowanej wersji interpretera; ważne, aby była to jedna z ostatnich wersji.

Serwery hostingowe to rozwiązania współdzielone, co oznacza, że na jednej fizycznej maszynie może działać wiele aplikacji. Plusem takiego podejścia jest fakt, że hosting jest relatywnie tani. Minusem jest brak niezależności: zasoby serwera mogą być zajęte przez innych użytkowników, unieruchamiając bądź ograniczając dostęp do Twojej aplikacji. Inną istotną sprawą jest fakt, że inne aplikacje zainstalowane na tym samym serwerze mogą posiadać luki bezpieczeństwa, które pozwolą atakującemu uzyskać dostęp do maszyny i wykonać atak na wszystkich, nawet bezpiecznych aplikacjach. Jeżeli Twój budżet na to pozwala, powinieneś unikać serwerów hostingowych.

Na górę{.top}

Caching

PHP sam w sobie całkiem dobrze radzi sobie z wydajnością, lecz jeżeli wykonujesz operacje kosztowne czasowo (np. komunikujesz się ze zdalnymi serwerami, czy ładujesz do pamięci duże pliki), może okazać się, że te miejsca negatywnie wpływają na wydajność Twojej aplikacji. Na szczęście istnieje kilka narzędzi, które pozwalają na pozbycie się takich wąskich gardeł, lub ograniczają ilość czasu potrzebnego na ich wykonanie.

Kod bajtowy

Kiedy wykonujemy program napisany w PHP, jego kod źródłowy jest najpierw kompilowany do postaci kodu bajtowego, a następnie uruchamiany. Jeżeli między kolejnymi uruchomieniami plik z kodem nie zostaje zmodyfikowany, wynikowy kod bajtowy jest taki sam za każdym razem. Oznacza to, że kolejne jego kompilacje nie są potrzebne i powodują jedynie niepotrzebnym obciążenie procesora.

Istnieją narzędzia za pomocą których możemy ograniczyć ilość kompilacji zapamiętując wynikowy kod bajtowy, aby kolejne żądania jego wykonania odbywały się znacznie szybciej. Narzędzia te potrafią drastycznie przyspieszyć działanie aplikacji, a do tego są bardzo proste w konfiguracji.

Najbardziej znanymi narzędziami tego typu są:

Caching obiektów

Aby przyspieszyć działanie konkretnych funkcjonalności Twojej aplikacji, warto zastanowić się gdzie w kodzie następuje odwołanie do źródeł danych, których pobranie jest czasochłonne, a częstość zmian jest niska. W takich sytuacjach warto rozważyć możliwość użycia cachingu tychże danych. Caching polega na zapamiętaniu rezultatu działania określonego fragmentu kodu w taki sposób, aby później można było wielokrotnie odwołać się do niego, zamiast ponownie wykonywać czasochłonną operację. Dzięki odpowiedniemu użyciu cache’a programista może w łatwy sposób zwiększyć szybkość działania aplikacji, a także zminimalizować obciążenie serwera.

Większość narzędzi, o których pisałem w poprzednim paragrafie, ma funkcję cachingu obiektów. APC, XCache, czy WinCache oferują proste API do zapamiętywania wyników działania określonego kodu w ich wewnętrznej pamięci.

Najbardziej znanymi narzędziami do cache’owania danych w PHP jest APC i memcached. Oba oferują proste API i są łatwe w instalacji i użyciu. Istotną różnicą między nimi jest fakt, że APC, zgodnie ze swoją architekturą, znajduje się na tym samym serwerze, co kod, który jest uruchamiany, a memcached jest narzędziem sieciowym, które umożliwia dostęp z wielu różnych maszyn, co powoduje, że jest nieznacznie wolniejszy niż APC.

Wybór jest dosyć prosty: jeżeli zależy Ci na skalowaniu aplikacji, wybierz zorientowany na to memcached. Jeżeli Twoja aplikacja będzie działać na jednym serwerze, użyj APC.

Przykładowy kod wykorzystujący APC:

<?php
// sprawdź, czy istnieją dane zapisane jako 'expensive_data' w pamięci
$data = apc_fetch('expensive_data');
if (!$data)
{
    // danych nie ma w pamięci, wykonaj czasochłonną operację
    // i zapamiętaj wynik, aby można było użyć go później. 
    $data = get_expensive_data();
    apc_store('expensive_data', $data);
}

print_r($data);

Narzędzia do cachingu obiektów:

Na górę{.top}

Linki

Oficjalne strony PHP

Ludzie związani z PHP

Doradztwo

Lista dostawców PaaS

Frameworki

Aby nie odkrywać koła na nowo, wielu programistów PHP do tworzenia swoich aplikacji używa frameworków, które zajmują się niskopoziomowymi i typowymi operacjami. Dzięki temu programista może skupić się na tym, co bardziej istotne - na działaniu swojej aplikacji. Oczywiście nie każdy projekt wymaga frameworka, nieraz użycie czystego PHP jest najlepszym rozwiązaniem.

Frameworki dzielą się na trzy główne typy:

Istotą mikroframeworków jest możliwie najszybsze zmapowanie żądania HTTP na konkretną logikę (callback, kontroler, metodę). Czasem wyposażone są w podstawowe biblioteki do komunikacji z bazą danych, systemem szablonów, itp. Głównym ich zastosowaniem są małe aplikacje, API i inne serwisy HTTP.

Część frameworków, oprócz logiki związanej z mapowaniem żądań na konkretne metody, oferuje spory zestaw bibliotek przydatnych podczas budowania wszelkiego rodzaju aplikacji, takich jak ORM’y, systemy kontroli dostępu, itp. Takie frameworki określane są mianem “Full-Stack Frameworks”.

Frameworki komponentowe są kolekcją wyspecjalizowanych narzędzi oraz bibliotek, które mogą posłużyć do zbudowania frameworka idealnie dostosowanego do naszych potrzeb.

Na górę{.top}

Społeczność

Społeczność PHP, zarówno w Polsce, jak i na całym świecie, jest duża, różnorodna i chętna do pomocy młodym adeptom tego języka programowania. Jeżeli w Twojej okolicy jest grupa użytkowników PHP, rozważ wstąpienie w jej szeregi. Bierz udział w konferencjach, aby dowiedzieć się więcej o najlepszych praktykach. Możesz także odwiedzić kanał IRC #phpc na serwerze irc.freenode.org lub obserwować @phpc na Twitterze. Taka aktywność sprzyja poznawaniu nowych deweloperów, czy nauce nowych tematów.

Oficjalny kalendarz wydarzeń PHP

Grupy użytkowników PHP

Jeżeli mieszkasz w większym mieście, prawdopodobnie w jego okolicy jest grupa użytkowników PHP. Nie ma oficjalnej listy grup, ale za pomocą Google prawdopodobnie znajdziesz coś dla siebie. Jeżeli w okolicy nie ma takiej grupy, może rozważysz założenie własnej? :)

Artykuł na temat group użytkowników PHP

Konferencje PHP

Społeczność PHP organizuje liczne konferencje w wielu krajach. Można na nich spotkać wiele znanych osób, a także posłuchać ciekawych prelekcji. Oficjalną polską konferencją PHP jest PHPCon.

Lista konferencji PHP

Na górę{.top}