Tworzenie i uruchamianie projektu CakePHP w ServBay
ServBay to lokalne środowisko programistyczne wspierające macOS i Windows, które integruje interpreter PHP, Node.js, Python, Go, Java oraz usługi bazodanowe jak MySQL, PostgreSQL, MongoDB, Redis, wykorzystując serwer WWW Caddy lub Nginx. Oferuje wygodną i wydajną platformę, umożliwiającą łatwą konfigurację oraz zarządzanie lokalnymi projektami.
W tym poradniku dowiesz się, jak utworzyć, skonfigurować i uruchomić projekt CakePHP w ServBay. CakePHP to popularny framework PHP oparty o wzorzec MVC (Model-View-Controller), znany z szybkiego procesu developmentu, silnego ORM oraz wbudowanych funkcji bezpieczeństwa. Korzystając z wygody ServBay łatwo rozpoczniesz deweloperską przygodę z CakePHP.
Czym jest CakePHP?
CakePHP to otwartoźródłowy framework PHP do tworzenia aplikacji webowych, oferujący solidną strukturę do szybkiego i uporządkowanego budowania aplikacji bez utraty elastyczności. Bazuje na zasadzie „konwencja ponad konfigurację”, upraszczając wiele typowych zadań programistycznych.
Najważniejsze cechy i zalety CakePHP
- Architektura MVC: Przejrzysta struktura kodu sprzyjająca łatwemu utrzymaniu i rozbudowie projektów.
- Szybki rozwój aplikacji: Narzędzie konsolowe (Bake) wspomaga generowanie kodu i przyspiesza pracę.
- Silny ORM (Object-Relational Mapping): Upraszcza komunikację z bazą danych, obsługuje wiele typów systemów bazodanowych.
- Wbudowane mechanizmy bezpieczeństwa: Ochrona przed CSRF, SQL Injection, walidacja danych wejściowych.
- Elastyczny silnik szablonów: Obsługa różnych technologii warstwy prezentacji.
- Aktywna społeczność i bogaty ekosystem pluginów: Łatwe wsparcie i rozszerzanie funkcjonalności.
- Wyjątkowo rozbudowana dokumentacja: Szczegółowe przewodniki i odniesienia do API.
CakePHP nadaje się do budowy aplikacji webowych dowolnej skali — od prostych API po złożone systemy korporacyjne.
Tworzenie środowiska CakePHP w ServBay
ServBay zapewnia kompleksowe, zintegrowane środowisko dla developerów CakePHP:
- Preinstalowany interpreter PHP z najpopularniejszymi rozszerzeniami.
- Preinstalowany manager pakietów Composer.
- Łatwo konfigurowalny serwer WWW (Caddy/Nginx).
- Zintegrowane usługi bazodanowe (MySQL, PostgreSQL, Redis etc.).
Dzięki ServBay możesz uniknąć skomplikowanej, ręcznej instalacji i konfiguracji tych komponentów.
Wymagania wstępne
Przed rozpoczęciem upewnij się, że wykonałeś poniższe kroki:
- Instalacja ServBay: Pobierz i zainstaluj ServBay na macOS.
- Uruchomienie usług ServBay: Uruchom aplikację ServBay i upewnij się, że wymagane pakiety (np. PHP, wybrana baza danych jak MySQL lub PostgreSQL oraz usługa cache jak Redis lub Memcached) są aktywne. Zarządzaj tymi usługami przez zakładkę „Pakiety” w panelu ServBay.
- Podstawowa znajomość obsługi ServBay: Naucz się jak dodawać i konfigurować strony w ServBay. Jeśli nie znasz tych czynności, zalecamy przeczytać Podstawowe instrukcje korzystania z ServBay.
Tworzenie projektu CakePHP
ServBay rekomenduje umieszczać pliki projektów webowych w katalogu /Applications/ServBay/www, co wspiera automatyczną detekcję i zarządzanie stronami.
Otwórz Terminal
Uruchom aplikację Terminal na macOS.
Przejdź do katalogu stron ServBay
Przejdź do domyślnej lokalizacji projektów ServBay:
bashcd /Applications/ServBay/www1Utwórz katalog projektu
Utwórz nowy podkatalog dla projektu CakePHP, np.:
bashmkdir servbay-cakephp-app cd servbay-cakephp-app1
2Utwórz projekt CakePHP za pomocą Composera
Composer jest preinstalowany w ServBay. W katalogu projektu utwórz szkielet aplikacji CakePHP:
bashcomposer create-project --prefer-dist cakephp/app .1Po uruchomieniu polecenia zostanie zainstalowana ostatnia stabilna wersja CakePHP i jej zależności w obecnym katalogu (
.).Instalacja sterownika ORM (dla PostgreSQL)
Jeśli używasz bazy PostgreSQL, konieczna będzie dodatkowa instalacja sterownika ORM:
bashcomposer require cakephp/orm-pgsql1W przypadku MySQL nie trzeba instalować dodatkowych sterowników — są już dostępne w CakePHP.
Podstawowa konfiguracja
Po utworzeniu projektu należy przeprowadzić podstawową konfigurację, w szczególności ustawienie połączenia z bazą danych.
Konfiguracja zmiennych środowiskowych i bazy danych
Lokalna konfiguracja CakePHP odbywa się w pliku
config/app_local.php. Otwórz go, odszukaj sekcjęDatasourcesi skonfiguruj połączenie z bazą danych. Domyślnie nazwa użytkownika ServBay toroot, a hasło topassword.Przykład konfiguracji połączenia z MySQL:
php// config/app_local.php 'Datasources' => [ 'default' => [ 'className' => \Cake\Database\Connection::class, 'driver' => \Cake\Database\Driver\Mysql::class, // lub \Cake\Database\Driver\Postgres::class dla PostgreSQL 'persistent' => false, 'host' => '127.0.0.1', // adres serwera bazodanowego, ServBay domyślnie lokalnie //'port' => '3306', // domyślny port MySQL to 3306, PostgreSQL to 5432 'username' => 'root', // domyślna nazwa użytkownika ServBay 'password' => 'password', // domyślne hasło ServBay 'database' => 'servbay_cakephp_app', // nazwa tworzonej bazy danych 'encoding' => 'utf8mb4', 'timezone' => 'UTC', 'flags' => [], 'cacheMetadata' => true, 'log' => false, /** * Ustaw quoting identyfikatorów na true jeśli używasz nazw typu "user" jako nazw tabel. * Jeśli korzystasz z nazw typu "cake", możesz ustawić na false. * Jeśli nie jesteś pewien, ustaw na true. */ 'quoteIdentifiers' => false, /** * Ograniczenia: * - Większość sterowników nie obsługuje ustawień poziomu izolacji przez opcje PDO. * - Nie wszystkie sterowniki pozwalają na ustawienie charsetu przez opcje PDO. * - Opcje PDO nie są wspierane przez pakietowane sterowniki (np. Postgres z CakePHP). * Dla Postgres należy ustawić tylko encoding. */ 'options' => [], //'url' => env('DATABASE_URL', null), // Jeśli używasz zmiennej środowiskowej DATABASE_URL, możesz odkomentować tę linię ], ],1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36Dostosuj
driveri ewentualnieportdo wybranego silnika bazy danych (MySQL lub PostgreSQL). Upewnij się, że nazwa bazy pokrywa się z faktycznie utworzoną.
Konfiguracja serwera WWW (Tworzenie strony w ServBay)
Aby udostępnić projekt CakePHP w przeglądarce, musisz skonfigurować stronę w ServBay, wskazując na katalog projektu.
Otwórz panel ServBay
Kliknij ikonę ServBay i uruchom panel sterowania.
Przejdź do zakładki „Strony”
W panelu wybierz z menu po lewej „Strony” (poprzednio: „Hosty”).
Dodaj nową stronę
Kliknij przycisk
+aby dodać nową stronę. Wypełnij następujące pola:- Nazwa: Przykładowo
My CakePHP Dev Site. - Domena: Ustaw domenę lokalną, np.
servbay-cakephp-test.local. ServBay automatycznie przekieruje ją lokalnie. - Typ strony: Wybierz
PHP. - Wersja PHP: Dobierz wersję kompatybilną z Twoją wersją CakePHP (CakePHP 4+ wymaga przynajmniej PHP 7.4+, CakePHP 5+ zwykle PHP 8.1+), np.
8.3. - Katalog root strony: Ważne! Root serwera dla projektu CakePHP to podkatalog
webroot, nie katalog główny projektu. Ustaw na/Applications/ServBay/www/servbay-cakephp-app/webroot(zamieńservbay-cakephp-appna faktyczną nazwę katalogu projektu).
- Nazwa: Przykładowo
Zapisz i zastosuj zmiany
Po uzupełnieniu pól, kliknij „Zapisz” w prawym dolnym rogu. ServBay poprosi o zatwierdzenie zmian — potwierdź je. System automatycznie skonfiguruje serwer WWW (Caddy/Nginx) i skieruje domenę na katalog
webrootTwojego projektu CakePHP.
Szczegółowy opis dodawania strony znajdziesz w dokumentacji ServBay, sekcja Dodawanie pierwszej strony.
Weryfikacja podstawowej konfiguracji
Teraz możesz odwiedzić skonfigurowaną stronę w przeglądarce.
Otwórz adres, np. https://servbay-cakephp-test.local.
Jeśli wszystko zostało poprawnie skonfigurowane, zobaczysz domyślną stronę powitalną CakePHP. Oznacza to, że środowisko PHP, serwer WWW oraz konfiguracja ServBay działają prawidłowo.
Integracja bazy danych i serwisów cache
CakePHP posiada rozbudowany ORM oraz warstwę abstrakcji cache, ułatwiając integrację z dostępnymi w ServBay usługami bazodanowymi i cache.
Przykład z relacyjną bazą danych (MySQL / PostgreSQL)
Poniżej znajdziesz demonstrację użycia ORM CakePHP do połączenia z bazą MySQL lub PostgreSQL, utworzenia tabeli users i wykonania operacji CRUD.
Utworzenie bazy w ServBay
Przed migracją stwórz nową bazę w serwerze bazodanowym ServBay, np. za pomocą phpMyAdmin dla MySQL/MariaDB, pgAdmin dla PostgreSQL lub narzędzi takich jak Navicat/DBeaver. Połącz się z serwerem (adres:
127.0.0.1, użytkownik:root, hasło:password), a następnie utwórz bazęservbay_cakephp_app.Tworzenie pliku Model ORM
ORM CakePHP wymaga pliku Modelu określającego strukturę tabeli. Stwórz plik
UsersTable.phpdla tabeliusers.Zapisz poniższy kod jako
src/Model/Table/UsersTable.php:php<?php namespace App\Model\Table; use Cake\ORM\Table; use Cake\Validation\Validator; // Jeśli potrzebujesz reguł walidacji class UsersTable extends Table { /** * Metoda inicjalizacji * * @param array $config Konfiguracja dla tabeli. * @return void */ public function initialize(array $config): void { parent::initialize($config); $this->setTable('users'); // Określenie powiązanej nazwy tabeli $this->setDisplayField('name'); // Domyślne pole wyświetlane w asocjacjach $this->setPrimaryKey('id'); // Klucz główny // Jeśli potrzebujesz automatycznych znaczników czasowych: // $this->addBehavior('Timestamp'); } /** * Domyślne reguły walidacji * * @param \Cake\Validation\Validator $validator Instancja validatora. * @return \Cake\Validation\Validator */ public function validationDefault(Validator $validator): Validator { $validator ->scalar('name') ->maxLength('name', 255) ->requirePresence('name', 'create') ->notEmptyString('name'); $validator ->email('email') ->requirePresence('email', 'create') ->notEmptyString('email') ->add('email', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']); // Gwarancja unikalności emaila return $validator; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49Utworzenie pliku migracji za pomocą Bake
CakePHP rekomenduje korzystanie z migracji do zarządzania strukturą bazy danych. W katalogu projektu (
/Applications/ServBay/www/servbay-cakephp-app) uruchom narzędzie Bake CakePHP, tworząc migrację dla tabeliusers:bashbin/cake bake migration CreateUsers name:string email:string:unique1Polecenie utworzy plik migracji zawierający instrukcje utworzenia tabeli
usersz polaminame(string) iemail(string, unikalne).Wykonanie migracji bazy danych
Przeprowadź migrację, aby fizycznie utworzyć tabelę w swojej bazie danych:
bashbin/cake migrations migrate1Po pomyślnym wykonaniu migracji tabela
userspojawi się w bazie.Konfiguracja połączenia do bazy (jeśli nie została dokonana wcześniej)
Upewnij się, że
config/app_local.php(Datasources.default) jest właściwie skonfigurowane.Przykład konfiguracji dla MySQL:
php'Datasources' => [ 'default' => [ 'className' => \Cake\Database\Connection::class, 'driver' => \Cake\Database\Driver\Mysql::class, 'host' => '127.0.0.1', 'username' => 'root', 'password' => 'password', 'database' => 'servbay_cakephp_app', // ... pozostała konfiguracja ], ],1
2
3
4
5
6
7
8
9
10
11Przykład dla PostgreSQL:
php'Datasources' => [ 'default' => [ 'className' => \Cake\Database\Connection::class, 'driver' => \Cake\Database\Driver\Postgres::class, 'host' => '127.0.0.1', // 'port' => '5432', // domyślny port 'username' => 'root', // domyślny użytkownik ServBay 'password' => 'password', // domyślne hasło ServBay 'database' => 'servbay_cakephp_app', // ... pozostała konfiguracja ], ],1
2
3
4
5
6
7
8
9
10
11
12
Dodanie przykładowych tras oraz akcji kontrolera
Edytuj plik
config/routes.php, dodając trasy do dodawania i wyświetlania danych użytkownika:php// config/routes.php use Cake\Routing\RouteBuilder; use Cake\Routing\Router; use Cake\Routing\Route\DashedRoute; Router::defaultRouteClass(DashedRoute::class); Router::scope('/', function (RouteBuilder $routes) { // ... inne trasy $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']); // Przykładowe trasy bazy danych $routes->connect('/db-add-user', ['controller' => 'Pages', 'action' => 'dbAddUser']); $routes->connect('/db-list-users', ['controller' => 'Pages', 'action' => 'dbListUsers']); // ... inne trasy $routes->fallbacks(DashedRoute::class); });1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18Następnie zaktualizuj plik
src/Controller/PagesController.php, dodając akcje bazodanowe:php<?php namespace App\Controller; use Cake\Http\Response; use Cake\ORM\TableRegistry; use Cake\Datasource\Exception\RecordNotFoundException; // Obsługa wyjątków, gdy rekord nieznaleziony class PagesController extends AppController { /** * Wyświetla widok * * @param array ...$path Segmenty ścieżki. * @return \Cake\Http\Response|null */ public function display(...$path): ?Response { // ... domyślna metoda display return new Response(['body' => 'Hello ServBay! To jest strona domyślna.']); } /** * Przykład bazy danych: dodawanie użytkownika */ public function dbAddUser(): Response { $usersTable = TableRegistry::getTableLocator()->get('Users'); // Pobierz instancję tabeli Users // Utwórz nowy obiekt użytkownika $user = $usersTable->newEntity([ 'name' => 'ServBay Demo User', 'email' => 'servbay-demo@servbay.test' // Przykładowy email ServBay ]); // Próba zapisania użytkownika w bazie if ($usersTable->save($user)) { return new Response(['body' => 'Użytkownik dodany! ID użytkownika: ' . $user->id]); } else { // W przypadku błędu walidacji lub innych $errors = $user->getErrors(); // Pobierz informacje o błędach walidacji return new Response(['body' => 'Nie udało się dodać użytkownika. Błędy: ' . json_encode($errors)]); } } /** * Przykład bazy danych: lista użytkowników */ public function dbListUsers(): Response { $usersTable = TableRegistry::getTableLocator()->get('Users'); // Pobierz instancję tabeli Users // Pobierz wszystkich użytkowników $users = $usersTable->find()->all(); // Wyświetl wynik jako JSON return new Response(['body' => json_encode($users->toArray())]); // Użyj toArray() aby przekształcić kolekcję w tablicę } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58Przetestuj przykładowe operacje bazodanowe
Uruchom przeglądarkę:
- Wejdź na
https://servbay-cakephp-test.local/db-add-user— zostanie dodany użytkownik i pojawi się komunikat o sukcesie. - Wejdź na
https://servbay-cakephp-test.local/db-list-users— pojawi się lista wszystkich użytkowników (w tym właśnie dodany).
- Wejdź na
Wykonując te kroki, połączysz aplikację CakePHP z relacyjną bazą danych w ServBay oraz przeprowadzisz podstawowe operacje ORM.
Przykład integracji cache (Memcached / Redis)
CakePHP obsługuje uniwersalny API cache, pozwalający na łatwą zmianę silnika (np. Memcached lub Redis). ServBay domyślnie instaluje odpowiednie rozszerzenia PHP oraz udostępnia potrzebne usługi.
Najpierw upewnij się, że w panelu ServBay, w zakładce „Pakiety”, usługi Memcached lub Redis są uruchomione.
Konfiguracja połączenia cache
Otwórz plik
config/app_local.phpi skonfiguruj sekcjęCache.Przykład Memcached:
php// config/app_local.php 'Cache' => [ 'default' => [ 'className' => \Cake\Cache\Engine\MemcachedEngine::class, 'servers' => ['127.0.0.1:11211'], // Domyślna lokalizacja i port Memcached w ServBay 'prefix' => 'servbay_cakephp_', // Prefiks kluczy cache ], // ... inne konfiguracje cache ],1
2
3
4
5
6
7
8
9Przykład Redis:
php// config/app_local.php 'Cache' => [ 'default' => [ 'className' => \Cake\Cache\Engine\RedisEngine::class, 'host' => '127.0.0.1', // Domyślna lokalizacja Redis w ServBay 'port' => 6379, // Domyślny port Redis w ServBay 'password' => null, // Jeśli Redis ma hasło — wpisz je tutaj 'database' => 0, // Indeks bazy Redis 'prefix' => 'servbay_cakephp_', // Prefiks kluczy cache ], // ... inne konfiguracje cache ],1
2
3
4
5
6
7
8
9
10
11
12
Wybierz i skonfiguruj wybraną usługę.
Dodanie tras i metod kontrolera dla przykładu cache
Uzupełnij
config/routes.phpo trasy dla przykładowych akcji cache:php// config/routes.php // ... inne trasy $routes->connect('/cache-memcached', ['controller' => 'Pages', 'action' => 'cacheMemcached']); $routes->connect('/cache-redis', ['controller' => 'Pages', 'action' => 'cacheRedis']); // ... inne trasy1
2
3
4
5Uzupełnij plik
src/Controller/PagesController.php:php<?php namespace App\Controller; use Cake\Http\Response; use Cake\Cache\Cache; // Import klasy Cache // ... inne use class PagesController extends AppController { // ... inne metody (display, dbAddUser, dbListUsers) /** * Przykład cache: Memcached */ public function cacheMemcached(): Response { // Upewnij się, że w app_local.php 'default' używa MemcachedEngine $cacheKey = 'servbay_memcached_test_key'; $cachedData = Cache::read($cacheKey); // Próba odczytu z cache $responseBody = ''; if ($cachedData === false) { // Brak danych w cache $responseBody = 'Cache miss! Zapisuję "Hello Memcached!" do cache.'; $dataToCache = 'Hello Memcached!'; Cache::write($cacheKey, $dataToCache, 'default'); // Zapis do cache (konfiguracja Memcached) } else { // Trafienie w cache $responseBody = 'Cache hit! Dane z cache: ' . $cachedData; } return new Response(['body' => $responseBody]); } /** * Przykład cache: Redis */ public function cacheRedis(): Response { // Upewnij się, że w app_local.php 'default' używa RedisEngine $cacheKey = 'servbay_redis_test_key'; $cachedData = Cache::read($cacheKey); // Próba odczytu z cache $responseBody = ''; if ($cachedData === false) { // Brak danych w cache $responseBody = 'Cache miss! Zapisuję "Hello Redis!" do cache.'; $dataToCache = 'Hello Redis!'; Cache::write($cacheKey, $dataToCache, 'default'); // Zapis do cache (konfiguracja Redis) } else { // Trafienie w cache $responseBody = 'Cache hit! Dane z cache: ' . $cachedData; } return new Response(['body' => $responseBody]); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61Testowanie cache w aplikacji
Uruchom przeglądarkę:
- Jeśli skonfigurowałeś Memcached, przejdź do
https://servbay-cakephp-test.local/cache-memcached— przy pierwszym otwarciu zobaczysz „Cache miss”; po odświeżeniu „Cache hit”. - W przypadku Redis przejdź do
https://servbay-cakephp-test.local/cache-redis— analogicznie.
- Jeśli skonfigurowałeś Memcached, przejdź do
To dowodzi, że aplikacja CakePHP prawidłowo korzysta z serwisów cache dostępnych w ServBay.
Ważne uwagi
- Dane logowania do baz danych: Domyślny użytkownik i hasło (
root/password) służą tylko do lokalnego developmentu. W produkcji używaj bezpiecznych danych. - Katalog root strony: Zawsze ustaw „Katalog root strony” ServBay na
webrootprojektu CakePHP, nie na katalog główny — to zalecana praktyka. - Zgodność wersji PHP: Sprawdź, czy wybrana wersja PHP pasuje do Twojej wersji CakePHP, kierując się dokumentacją oficjalną CakePHP.
- Porty ServBay: Jeżeli domyślne porty (np. 80, 443) są zajęte przez inne programy, zmień ustawienia portów w ServBay, a następnie odpowiednio skonfiguruj plik hosts lub dodaj port do adresu strony.
Najczęściej zadawane pytania (FAQ)
- Q: Po wejściu na
servbay-cakephp-test.localpojawia się błąd „Strona nie znaleziona”?- A: Upewnij się, że „Katalog root strony” ServBay wskazuje na
/Applications/ServBay/www/servbay-cakephp-app/webroot. - Sprawdź, czy serwer WWW (Caddy/Nginx) jest uruchomiony w ServBay.
- Skontroluj, czy plik hosts systemu przekierowuje
servbay-cakephp-test.localna127.0.0.1(ServBay ustawia to automatycznie, ale warto sprawdzić). - Zweryfikuj konfigurację
.htaccessprojektu CakePHP oraz ustawienia serwera (domyślniewebroot/.htaccessjest poprawny).
- A: Upewnij się, że „Katalog root strony” ServBay wskazuje na
- Q: Problemy z połączeniem z bazą danych?
- A: Sprawdź, czy usługa bazodanowa (MySQL/PostgreSQL) jest aktywna w ServBay.
- Zweryfikuj dane połączeniowe w
config/app_local.php(host, port, username, password, database) i czy zgadzają się z konfiguracją serwera ServBay. - Upewnij się, że utworzyłeś bazę
servbay_cakephp_app.
- Q: Polecenie Composer (
bin/cake) nie działa?- A: Sprawdź, czy działasz w katalogu głównym projektu CakePHP (
/Applications/ServBay/www/servbay-cakephp-app). - Upewnij się, że pakiet PHP i Composer jest aktywny w ServBay.
- Zweryfikuj, czy terminal znajduje polecenie
php(ServBay zwykle dodaje je do PATH). Można użyć terminala zintegrowanego ServBay lub samodzielnie poprawić PATH.
- A: Sprawdź, czy działasz w katalogu głównym projektu CakePHP (
Podsumowanie
ServBay umożliwia szybką i wygodną konfigurację środowiska lokalnego dla projektów CakePHP. Dzięki preinstalowanemu PHP, Composerowi, serwerowi WWW oraz bazom danych konfiguracja jest uproszczona do minimum. W tym poradniku opisano szczegółowo etapy od tworzenia projektu, podstawowych ustawień oraz integracji serwera WWW, po pracę z relacyjną bazą danych i systemami cache, co pozwoli Ci szybko rozpocząć development w CakePHP. Wykorzystując wygodę ServBay, możesz skoncentrować się na pisaniu kodu, zamiast walczyć z konfiguracją środowiska.
