PHP i Windows - Przyspieszanie aplikacji PHP
Autor: Maciej Wilgucki
Opublikowano: 2011-07-19
Każdy programista PHP napotkał (lub napotka) w swojej karierze taki projekt, który bez cache’u długo nie podziała. Do dyspozycji mamy kilka mechanizmów cache’owania, jednak w przypadku systemów operacyjnych z rodziny Windows najlepiej sprawdzi się Windows Cache Extension for PHP działające na serwerze IIS.
Instalacja
Podobnie jak w przypadku większości instalowanych w tej serii aplikacji, Windows Cache Extension for PHP instalujemy za pomocą Web Platform Installera. Jeśli posiadacie Web PI w polskiej wersji językowej, nie uda wam się znaleźć wspomnianego rozszerzenia, ponieważ zostało przetłumaczone na Rozszerzenie pamięci podręcznej systemu Windows dla programu PHP 5.3 (rys. 1). Istnieje również wersja dla języka PHP w wersji 5.2. Rozszerzenie to znajdziemy w kategorii Produkty w sekcji Struktury. Instalacja sprowadza się do kliknięcia w przycisk Dodaj znajdujący się obok nazwy oraz potwierdzenia chęci instalacji przyciskiem Zainstaluj.
Rys. 1. Instalacja Windows Cache Extension for PHP.
W celu potwierdzenia, że cache został poprawnie zainstalowany, wykonajmy prosty test. Stwórzmy plik php, a w nim umieśćmy następujący kod:
print_r(wincache_ocache_fileinfo());
Jeśli wszystko poprawnie się zainstalowało, po uruchomieniu pliku w przeglądarce, powinniśmy zobaczyć coś takiego (poszczególne wartości mogą się różnić):
Array
(
[total_cache_uptime] => 0
[is_local_cache] =>
[total_file_count] => 1
[total_hit_count] => 0
[total_miss_count] => 1
[file_entries] => Array
(
[1] => Array
(
[file_name] =>c:\sciezka\do\pliku.php
[add_time] => 0
[use_time] => 0
[last_check] => 0
[hit_count] => 0
[function_count] => 0
[class_count] => 0
)
)
)
Szczypta teorii
Dlaczego Windows Cache Extension for PHP jest taki dobry? Ponieważ my, jako programiści, nie musimy nic robić, aby nasze aplikacje działały szybciej. Jest to możliwe, gdyż cache przechowuje w pamięci opcode, skompilowaną wersję skryptu PHP, dzięki czemu kolejne wywołania tego samego skryptu nie wymagają jego parsowania, tylko odwołują się do opcode’u z pamięci.
W przypadku dużej ilości plików dołączanych do naszej aplikacji na podstawie względnych ścieżek, PHP może zauważalnie zwolnić. Dzięki mechanizmom wbudowanym w cache, relatywne ścieżki mapowane są na ścieżki bezwzględne, przyspieszając tym samym proces dołączania plików.
Kolejne usprawnienia to cache’owanie danych wskazanych przez programistę (np. wynik czasochłonnej operacji) i współdzielenie ich między wywołaniami skryptów oraz danych sesji. W obu przypadkach cache przechowywany jest w pamięci.
Od teorii do praktyki
Pamiętacie, w jaki sposób sprawdziliśmy, czy cache został poprawnie zainstalowany? Wykonaliśmy funkcję wincache_ocache_fileinfo. Funkcja ta zwraca w odpowiedzi metadane opisujące cache. Dowiemy się z nich jak długo działa cache, ile było „trafień” w cache oraz znajdziemy informacje na temat wszystkich plików przechowywanych w cache. W przypadku plików poznamy również czas, przez jaki dany plik znajduje się w cache’u, ile zawiera klas i funkcji, kiedy ostatni raz nastąpiło odwołanie do pliku oraz kiedy sprawdzana była wersja pliku (w poszukiwaniu zmian w kodzie). Drugą ważną funkcją dotyczącą opcode’u jest wincache_ocache_meminfo. Funkcja ta zwraca w postaci tablicy informacje na temat zużycia pamięci przez cache.
Jakkolwiek powyższe funkcje dostarczają ważnych informacji, nie można nie zauważyć, że niewiele można z nimi zrobić od strony programistycznej. Znacznie ciekawsze z punktu widzenia programisty są funkcje pozwalające na manipulowanie danymi przechowywanymi w cache’u. Zacznijmy od prostego przykładu:
if(!wincache_ucache_exists('klucz')) {
/*
* tutaj wykonujemy operacje, których wynik chcemy zapisać do cache'u
*/
$wynik_operacji = 'abc';
wincache_ucache_set('klucz', $wynik_operacji, 3600);
}
$dane_z_cache = wincache_ucache_get('klucz', $cache_wczytany);
if($cache_wczytany) {
echo $dane_z_cache;
}
else {
throw new Exception('Błąd podczas wczytywania danych z cache');
}
Powyższy kod jest jednym z najczęstszych scenariuszy. Najpierw sprawdzamy, czy cache istnieje. Jeśli nie, wykonujemy operacje, których wynik chcemy zapisać w cache’u. W innej części aplikacji odczytujemy cache i w przypadku błędu zgłaszamy wyjątek.
Podczas zapisywania danych do cache’u wykorzystana została funkcja wincache_ucache_set. Działa ona w taki sposób, że w przypadku podania klucza, który już istnieje w cache’u, dane zostaną nadpisane. Jeśli chcemy uniknąć takiej sytuacji, powinniśmy skorzystać z funkcji wincache_ucache_add.
W przypadku funkcji wincache_ucache_get, powinniśmy zawsze korzystać z drugiego parametru, określającego, czy wczytanie danych z cache’u się powiodło. Jeśli skorzystamy ze zwracanej wartości, która przyjmuje wartość false w przypadku niepowodzenia, może się okazać, że nasza aplikacja nie działa jak należy. Może być to spowodowane faktem, iż do cache’u zapisujemy wartość false, którą w późniejszym czasie chcemy pobrać. W takiej sytuacji nie jesteśmy w stanie określić, czy funkcja zwróciła nam przechowywaną zawartość, czy nie była w stanie nic zwrócić.
Usuwanie danych z cache jest tak samo proste, jak ich dodanie:
wincache_ucache_delete('klucz');
W ten sposób usuniemy konkretną wartość z cache’u. Jeśli chcemy wyczyścić cały cache, powinniśmy skorzystać z funkcji wincache_ucache_clear:
wincache_ucache_clear();
Ciekawą funkcjonalność prezentują dwie kolejne funkcje – wincache_ucache_inc oraz wincache_ucache_dec. Pierwsza odpowiada za inkrementowanie wartości przechowywanej w cache’u, druga za jej dekrementację. Po co jest to nam potrzebne? Przede wszystkim w przypadku pracy na bardzo dużych zbiorach danych. Zamiast po każdej operacji ponownie obliczać ilość elementów w takim zbiorze, lepiej zmienić wartość w cache’u za pomocą wspomnianych funkcji.
Podsumowanie
W dzisiejszym artykule omówiliśmy sposób na przyspieszenie naszych aplikacji działających na serwerze IIS. Zastosowanie Windows Cache Extension for PHP może znacząco zwiększyć szybkość działania aplikacji. Warto zapoznać się też z opisem tego rozszerzenia, znajdującym się w oficjalnym manualu PHP pod adresem http://www.php.net/manual/pl/book.wincache.php.