Praca z bazami danych ====================== Ta sekcja opisuje jak utworzyć nową stronę, która będzie wyświetlała dane krajów pobrane z tabeli bazy danych o nazwie `country`. Aby to osiągnąć, musisz skonfigurować swoje połączenie z bazą danych, utworzyć klasę [Active Record](db-active-record.md), zdefiniować [akcję](structure-controllers.md) oraz utworzyć [widok](structure-views.md) W tej sekcji nauczysz się: * konfigurowania połączenia z bazą danych, * tworzenia klasy Active Record, * tworzenia zapytań o dane przy użyciu klasy Active Record, * wyświetlania danych w widoku wraz ze stronicowaniem. Zauważ, że w celu przejścia tej sekcji należy mieć już podstawową wiedzę o bazach danych. W szczególności powinieneś wiedzieć, jak utworzyć bazę dancyh oraz jak wywołać komendę SQL używając klienta bazy danych. Przygotowanie bazy danych ---------------------- Aby rozpocząć musisz utworzyć bazę danych o nazwie `yii2basic`, z której będziesz pobierał dane do swojej aplikacji. Możesz utworzyć bazę SQLite, MySQL, PostgreSQL, MSSQL lub Oracle, ponieważ Yii posiada wbudowane wsparcie dla wielu aplikacji bazodanowych. Dla uproszczenia w naszym przykładzie wykorzystamy MySQL. Następnie, utwórz tabelę o nazwie `country` i wstaw przykładowe dane. Możesz użyc poniższej komendy: ```sql CREATE TABLE `country` ( `code` CHAR(2) NOT NULL PRIMARY KEY, `name` CHAR(52) NOT NULL, `population` INT(11) NOT NULL DEFAULT '0' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `country` VALUES ('AU','Australia',18886000); INSERT INTO `country` VALUES ('BR','Brazil',170115000); INSERT INTO `country` VALUES ('CA','Canada',1147000); INSERT INTO `country` VALUES ('CN','China',1277558000); INSERT INTO `country` VALUES ('DE','Germany',82164700); INSERT INTO `country` VALUES ('FR','France',59225700); INSERT INTO `country` VALUES ('GB','United Kingdom',59623400); INSERT INTO `country` VALUES ('IN','India',1013662000); INSERT INTO `country` VALUES ('RU','Russia',146934000); INSERT INTO `country` VALUES ('US','United States',278357000); ``` W tym miejscu masz już utworzoną bazę danych o nazwie `yii2basic`, posiadającą tabelę `country` z trzeba kolumnami. Tabela zawiera 10 wierszy danych. Konfiguracja połączenia z bazą danych --------------------------- Przed przystąpieniem do tej części, upewnij się, że masz zainstalowane rozszerzenie [PDO](http://www.php.net/manual/en/book.pdo.php) oraz sterownik PDO dla bazy danych której używasz (np. `pdo_mysql` dla MySQL). Jest to podstawowe wymaganie jeśli Twoja aplikacja używa relacyjnej bazy danych. Jeśli posiadasz zainstalowane powyższe rozszerzenia, otwórz plik `config/db.php` i zmień parametry na odpowiednie do Twojej bazy danych. Domyślnie plik zawiera poniższy fragment: ```php 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii2basic', 'username' => 'root', 'password' => '', 'charset' => 'utf8', ]; ``` Plik `config/db.php` jest typowym narzędziem [konfiguracyjnym](concept-configurations.md) opartym na plikach. Ten szczególny plik konfiguracyjny określa parametry potrzebne do utworzenia oraz zainicjalizowania instancji [[yii\db\Connection]], dzięki czemu będziesz mógł wywoływać komendy SQL dp swojej bazy przez aplikację. Powyższa konfiguracja może być dostępna z poziomu kodu aplikacji używając wyrażenia `Yii::$app->db`. > Info: Plik `config/db.php` będzie załączony do głównej konfiguracji aplikacji `config/web.php`, która określa jak instancja [aplikacji](structure-applications.md) powinna zostać zainicjalizowana. Po więcej informacji zajrzyj do sekcji [konfiguracje](concept-configurations.md) Tworzenie klasy Active Record ------------------------- Do pobrania i reprezentowania danych z tabeli `country` utwórz pochodną klasę [Active Record](db-active-record.md) o nazwie `Country`, kolejnie zapisz ją w pliku `models/Country.php`. ```php Info: Jeśli nie można dopasować tabeli do nazwy klasy, możesz nadpisać metodę [[yii\db\ActiveRecord::tableName()]] aby wskazywała na konkretną powiązaną tabelę. Używając klasy `Country` możesz w łatwy sposób manipulować danymi z tabeli `country`, tak jak pokazano w poniższych przykładach: ```php use app\models\Country; // pobiera wszystkie wiersze tabeli `country` i porządkuje je według kolumny "name" $countries = Country::find()->orderBy('name')->all(); // pobiera wiersz, którego kluczem głównym jest "US" $country = Country::findOne('US'); // wyświetla "United States" echo $country->name; // modyfikuje nazwę kraju na "U.S.A." i zapisuje go do bazy danych $country->name = 'U.S.A.'; $country->save(); ``` > Info: Active Record jest potężnym narzędziem do dostępu i manipulacji danymi w bazie danych w sposób zorientowany obiektowo. Więcej szczegółowych informacji znajdziesz w sekcji [Active Record](db-active-record.md). Alternatywnie, do łączenia się z bazą danych możesz użyć niskopoziomowej metody dostępu do danych nazwanej [Data Access Objects](db-dao.md). Tworzenie akcji ------------------ Aby przedstawić kraje użytkownikowi musisz utworzyć nową akcję. Zamiast umieszczać nową akcję w kontrolerze `site`, tak jak w poprzednich sekcjach, bardziej sensownym rozwiązaniem jest utworzenie nowego kontrolera odpowiedzialnego za wszystkie akcje dotyczące danych z tabeli `country`. Nazwij nowy kontroler `CountryController`, a następnie utwórz w nim akcję `index`, tak jak na poniższym przykładzie: ```php 5, 'totalCount' => $query->count(), ]); $countries = $query->orderBy('name') ->offset($pagination->offset) ->limit($pagination->limit) ->all(); return $this->render('index', [ 'countries' => $countries, 'pagination' => $pagination, ]); } } ``` Zapisz powyższy kod w pliku `controllers/CountryController.php`. Akcja `index` wywołuje metodę `Country::find()`, pochodzącą z klasy Active Record, która buduje zapytanie bazodanowe i wyszukuje wszystkich danych z tabeli `country`. Aby ograniczyć liczbę zwracanych krajów w każdym żądaniu, zapytanie jest stronicowane przy pomocy obiektu [[yii\data\Pagination]]. Obiekt `Pagination` służy dwóm celom: * Ustawia klauzule `offset` i `limit` do komend SQL reprezentowanych przez zapytanie tak, aby zwracały tylko jedną stronę na raz (maksymalnie 5 wierszy na stronę), * Jest używany w widoku do wyświetlania stronicowania jako listy przycisków z numerami stron, co będzie wyjaśnione w kolejnej sekcji. Na końcu akcja `index` renderuje widok o nazwie `index`, do którego przekazuje dane krajów oraz informacje o ich stronicowaniu. Tworzenie widoku --------------- W katalogu `views` utwórz nowy katalog o nazwie `country`. Będzie on używany do przechowywania wszystkich plików widoków renderowanych przez kontroler `country`. W katalogu `views/country` utwórz plik o nazwie `index.php` zawierający poniższy kod: ```php