diff --git a/docs/guide-ru/start-databases.md b/docs/guide-ru/start-databases.md new file mode 100644 index 0000000..f167e0e --- /dev/null +++ b/docs/guide-ru/start-databases.md @@ -0,0 +1,252 @@ +Работа с базами данных +====================== + +Этот раздел расскажет о том, как создать новую страницу, отображающую данные по странам, полученные из таблицы `countries` базы данных. Для достижения этой цели вам будет необходимо настроить подключение к базе данных, создать класс [Active Record](db-active-record.md), определить [action](structure-controllers.md), и создать [view](structure-views.md). + +Изучив эту часть, вы научитесь: + +* Настраивать подключение к БД +* Определять класс Active Record +* Запрашивать данные, используя класс Active Record +* Отображать данные в виде с использованием пагинации + +Обратите внимание, чтобы усвоить этот раздел, вы должны иметь базовые знания и навыки использования баз данных. +В частности, вы должны знать, как создать базу данных, и как выполнять SQL запросы, используя клиентские инструменты для работы с БД. + +Подготавливаем базу данных <a name="preparing-database"></a> +---------------------- + +Для начала, создайте базу данных под названием `yii2basic`, из которой вы будете получать данные в вашем приложении. +Вы можете создать базу данных SQLite, MySQL, PostgreSQL, MSSQL или Oracle, так как Yii имеет встроенную поддержку для многих баз данных. Для простоты, в дальнейшем описании будет подразумеваться MySQL. + +После этого создайте в базе данных таблицу `country`, и добавьте в неё немного демонстрационных данных. Вы можете запустить следующую SQL инструкцию, чтобы сделать это: +```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); +``` + +На данный момент у вас есть база данных под названием `yii2basic`, и внутри неё таблица `country` с тремя столбцами, содержащими десять строк данных. + +Настраиваем подключение к БД <a name="configuring-db-connection"></a> +--------------------------- + +Before proceeding, make sure you have installed both the [PDO](http://www.php.net/manual/en/book.pdo.php) PHP extension and +the PDO driver for the database you are using (e.g. `pdo_mysql` for MySQL). This is a basic requirement +if your application uses a relational database. + +With those installed, open the file `config/db.php` and change the parameters to be correct for your database. By default, +the file contains the following: + +```php +<?php + +return [ + 'class' => 'yii\db\Connection', + 'dsn' => 'mysql:host=localhost;dbname=yii2basic', + 'username' => 'root', + 'password' => '', + 'charset' => 'utf8', +]; +``` + +The `config/db.php` file is a typical file-based [configuration](concept-configurations.md) tool. This particular configuration file specifies the parameters +needed to create and initialize a [[yii\db\Connection]] instance through which you can make SQL queries +against the underlying database. + +The DB connection configured above can be accessed in the application code via the expression `Yii::$app->db`. + +> Info: The `config/db.php` file will be included by the main application configuration `config/web.php`, + which specifies how the [application](structure-applications.md) instance should be initialized. + For more information, please refer to the [Configurations](concept-configurations.md) section. + + +Creating an Active Record <a name="creating-active-record"></a> +------------------------- + +To represent and fetch the data in the `country` table, create an [Active Record](db-active-record.md)-derived +class named `Country`, and save it in the file `models/Country.php`. + +```php +<?php + +namespace app\models; + +use yii\db\ActiveRecord; + +class Country extends ActiveRecord +{ +} +``` + +The `Country` class extends from [[yii\db\ActiveRecord]]. You do not need to write any code inside of it! With just the above code, +Yii will guess the associated table name from the class name. + +> Info: If no direct match can be made from the class name to the table name, you can +override the [[yii\db\ActiveRecord::tableName()]] method to explicitly specify the associated table name. + +Using the `Country` class, you can easily manipulate data in the `country` table, as shown in these snippets: + +```php +use app\models\Country; + +// get all rows from the country table and order them by "name" +$countries = Country::find()->orderBy('name')->all(); + +// get the row whose primary key is "US" +$country = Country::findOne('US'); + +// displays "United States" +echo $country->name; + +// modifies the country name to be "U.S.A." and save it to database +$country->name = 'U.S.A.'; +$country->save(); +``` + +> Info: Active Record is a powerful way to access and manipulate database data in an object-oriented fashion. +You may find more detailed information in the [Active Record](db-active-record.md) section. Alternatively, you may also interact with a database using a lower-level data accessing method called [Data Access Objects](db-dao.md). + + +Creating an Action <a name="creating-action"></a> +------------------ + +To expose the country data to end users, you need to create a new action. Instead of placing the new action in the `site` +controller, like you did in the previous sections, it makes more sense to create a new controller specifically +for all actions related to the country data. Name this new controller `CountryController`, and create +an `index` action in it, as shown in the following. + +```php +<?php + +namespace app\controllers; + +use yii\web\Controller; +use yii\data\Pagination; +use app\models\Country; + +class CountryController extends Controller +{ + public function actionIndex() + { + $query = Country::find(); + + $pagination = new Pagination([ + 'defaultPageSize' => 5, + 'totalCount' => $query->count(), + ]); + + $countries = $query->orderBy('name') + ->offset($pagination->offset) + ->limit($pagination->limit) + ->all(); + + return $this->render('index', [ + 'countries' => $countries, + 'pagination' => $pagination, + ]); + } +} +``` + +Save the above code in the file `controllers/CountryController.php`. + +The `index` action calls `Country::find()`. This Active Record method builds a DB query and retrieves all of the data from the `country` table. +To limit the number of countries returned in each request, the query is paginated with the help of a +[[yii\data\Pagination]] object. The `Pagination` object serves two purposes: + +* Sets the `offset` and `limit` clauses for the SQL statement represented by the query so that it only + returns a single page of data at a time (at most 5 rows in a page). +* It's used in the view to display a pager consisting of a list of page buttons, as will be explained in + the next subsection. + +At the end of the code, the `index` action renders a view named `index`, and passes the country data as well as the pagination +information to it. + + +Creating a View <a name="creating-view"></a> +--------------- + +Under the `views` directory, first create a sub-directory named `country`. This folder will be used to hold all the +views rendered by the `country` controller. Within the `views/country` directory, create a file named `index.php` +containing the following: + +```php +<?php +use yii\helpers\Html; +use yii\widgets\LinkPager; +?> +<h1>Countries</h1> +<ul> +<?php foreach ($countries as $country): ?> + <li> + <?= Html::encode("{$country->name} ({$country->code})") ?>: + <?= $country->population ?> + </li> +<?php endforeach; ?> +</ul> + +<?= LinkPager::widget(['pagination' => $pagination]) ?> +``` + +The view has two sections relative to displaying the country data. In the first part, the provided country data is traversed and rendered as an unordered HTML list. +In the second part, a [[yii\widgets\LinkPager]] widget is rendered using the pagination information passed from the action. +The `LinkPager` widget displays a list of page buttons. Clicking on any of them will refresh the country data +in the corresponding page. + + +Trying it Out <a name="trying-it-out"></a> +------------- + +To see how all of the above code works, use your browser to access the following URL: + +``` +http://hostname/index.php?r=country/index +``` + + + +At first, you will see a page showing five countries. Below the countries, you will see a pager with four buttons. +If you click on the button "2", you will see the page display another five countries in the database: the second page of records. +Observe more carefully and you will find that the URL in the browser also changes to + +``` +http://hostname/index.php?r=country/index&page=2 +``` + +Behind the scenes, [[yii\data\Pagination|Pagination]] is providing all of the necessary functionality to paginate a data set: + +* Initially, [[yii\data\Pagination|Pagination]] represents the first page, which reflects the country SELECT query + with the clause `LIMIT 5 OFFSET 0`. As a result, the first five countries will be fetched and displayed. +* The [[yii\widgets\LinkPager|LinkPager]] widget renders the page buttons using the URLs + created by [[yii\data\Pagination::createUrl()|Pagination]]. The URLs will contain the query parameter `page`, which + represents the different page numbers. +* If you click the page button "2", a new request for the route `country/index` will be triggered and handled. + [[yii\data\Pagination|Pagination]] reads the `page` query parameter from the URL and sets the current page number to 2. + The new country query will thus have the clause `LIMIT 5 OFFSET 5` and return the next five countries + for display. + + +Summary <a name="summary"></a> +------- + +In this section, you learned how to work with a database. You also learned how to fetch and display +data in pages with the help of [[yii\data\Pagination]] and [[yii\widgets\LinkPager]]. + +In the next section, you will learn how to use the powerful code generation tool, called [Gii](tool-gii.md), +to help you rapidly implement some commonly required features, such as the Create-Read-Update-Delete (CRUD) +operations for working with the data in a database table. As a matter of fact, the code you have just written can all +be automatically generated in Yii using the Gii tool.