Làm việc với CSDL

Phần này sẽ hướng dẫn làm thế nào để tạo mới trang có chức năng hiển thị dữ liệu các thành phố (country) và được lấy từ bảng country nằm trong cơ sở dữ liệu. Để thực hành tốt bài hướng dẫn, bạn cần cấu hình các kết nối tới CSDL, tạo class Active Record, taọ một action, và tạo mới view.

Tóm tắt những nội dung chính:

  • Cấu hình kết nối tới CSDL
  • Đinh nghĩa lớp Active Record
  • Sử dụng lớp Active Record để truy vấn dữ liệu
  • Hiển thị và phân trang dữ liệu trên view

Lưu ý để thực hiện được bài hướng dẫn này, bạn cần có kiến thức về CSDL. Riêng ở phần này, bạn cần có kiến thức về tạo mới CSDL, và làm thế nào để thực thi các câu lệnh SQL sử dụng công cụ ở phía client.

Chuẩn bị

Đầu tiên, bạn cần tạo mới CSDL tên là yii2basic, từ bây giờ bạn sẽ dùng CSDL này để lấy dữ liệu. Yii hỗ trợ nhiều CSDL trong ứng dụng, bạn có thể dùng những CSDL như SQLite, MySQL, PostgreSQL, MSSQL hoặc Oracle. Để cho đơn giản, MySQL sẽ được dùng trong bài hướng dẫn này.

Tiếp đến, tạo mới bảng vào CSDL tên là country , đồng thời chèn thêm dữ liệu. You may run the following SQL statements to do so:

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',24016400);
INSERT INTO `country` VALUES ('BR','Brazil',205722000);
INSERT INTO `country` VALUES ('CA','Canada',35985751);
INSERT INTO `country` VALUES ('CN','China',1375210000);
INSERT INTO `country` VALUES ('DE','Germany',81459000);
INSERT INTO `country` VALUES ('FR','France',64513242);
INSERT INTO `country` VALUES ('GB','United Kingdom',65097000);
INSERT INTO `country` VALUES ('IN','India',1285400000);
INSERT INTO `country` VALUES ('RU','Russia',146519759);
INSERT INTO `country` VALUES ('US','United States',322976000);

Đến đây, bạn có CSDL là yii2basic, có chứa bảng country có 3 cột và 10 trường dữ liệu.

Cấu hình kết nối tới CSDL

Trước tiên, hãy chắc chắn rằng bạn đã cài 2 gói PHP PDO và PDO driver dành cho các CSDL mà đang sử dụng(ví dụ pdo_mysql cho MySQL). Đối với các CSDL quan hệ thì những gói này cần phải có.

Sau khi những yêu cầu trên được cài đặt, mở file config/db.php và thay đổi các tham số chính xác tới CSDL. Mặc định, file sẽ có những đoạn code sau:

<?php

return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

File config/db.php là file điển hình dành cho cấu hình ứng dụng configuration. Các tham số được mô tả trong file cần thiết để tạo mới và khởi tạo các thể hiện yii\db\Connection và thực hiện các câu lệnh truy vấn

Các thông tin cấu hình về CSDL ở trên được truy cập qua ứng dụng qua câu lệnh Yii::$app->db.

Lưu ý: File config/db.php sẽ chứa các thông tin chính trong việc cấu hình ứng dụng config/web.php, Những thông tin làm thế nào để ứng dụng cần được khởi tạo. Bạn có thể tham khảo thêm trong phần cấu hình ứng dụng .

Tạo mới class Active Record

Để thể hiện và thao tác với bảng dữ liệu country, ta tạo mới classActive Record- tên là Country, và lưu vào file models/Country.php.

<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}

Lớp Country được kế thừa từ yii\db\ActiveRecord. Bạn không cần viết bất kỳ đoạn mã nào vào phần này! Chỉ với đoạn mã trên, Yii sẽ biết được tên bảng từ tên của lớp tương ứng.

Info: Nếu tên lớp không trùng với tên trong bảng dữ liệu, bạn có thể ghi đè phương thức yii\db\ActiveRecord::tableName() để miêu tả rõ ràng về tên bảng dữ liệu.

Dùng lớp Country, bạn sẽ dễ dàng hơn trong việc thao tác với bảng country, ví dụ:

use app\models\Country;

// lấy danh sách tử bảng country và sắp xếp theo thuộc tính "name"
$countries = Country::find()->orderBy('name')->all();

// lấy dữ liệu có khóa là "US"
$country = Country::findOne('US');

// in kết quả "United States"
echo $country->name;

// thay đổi tên country thành "U.S.A." và lưu vào csdl
$country->name = 'U.S.A.';
$country->save();

Lưu ý: Active Record khá là mạnh cho việc truy cập csdl theo hướng lập trình hướng đối tượng. Bạn có thể xem thêm ở mục Active Record. Cách khác, bạn có thể thao tác với csdl ở mức độ đơn giản hơn bằng việc truy cập qua đối tượng Data Access Objects.

Tạo hành động (action)

Để hiển thị dữ liệu country tới người dùng, bạn cần tạo mới hành động. Thay vì đặt các hành động ở site controller, giống như đã làm ở phần trước, thì tạo controller mới có ý nghĩa hơn đặc biệt liên quan tới dữ liệu về coutry. Tên controller là CountryController, và tạo mới hành động index ở trong đó, bạn có thể tham khảo ở phần dưới.

<?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,
        ]);
    }
}

Lưu nội dung đoạn mã trên vào file controllers/CountryController.php.

Hành động index sẽ gọi các phương thức Country::find(). Đây là phương thức nằm ở Active Record nhằm xây dựng câu lệnh truy vấn và lấy tất cả dữ liệu trong bảng country. Để hạn chế số lượng dữ liệu mỗi khi gửi yêu cầu, đối tượng yii\data\Pagination sẽ phân trang dữ liệu. Mục đích khi dùng đối tượng Pagination là:

  • Thiết lập điều kiện offsetlimit cho câu lệnh mỗi khi lấy liệu ra (mỗi lần chỉ hiển thị 5 kết quả).
  • Dữ liệu được nhúng vào view để hiển thị số trang và bao gồm danh sách các button, sẽ được giải thích ở phần sau.

Xem những dòng cuối, hành động index sẽ đổ ra view có tên là index, đồng thời gửi dữ liệu về country và thông tin về phân trang.

Tạo View

Trong thư mục views, bước một tạo thư mục con là country. Thư mực này được dùng để giữ những view được đổ ra từ controller country. Trong thư mục views/country, tạo mới file tên là index.php và chứa đoạn mã sau:

<?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]) ?>

View trên có 2 phần liên quan tới hiển thị dữ liệu về country. Phần đầu tiên, cung cấp danh sách country và in ra dưới dạng danh sách . Phần tiếp, một widget yii\widgets\LinkPager được sinh ra và dùng các thông tin truyển từ action xuống để phân trang. Đối tượng LinkPager là một widget có chức năng hiển thị danh sách các button. Mỗi khi click vào mỗi button này sẻ cập nhật lại dữ liệu country ở mỗi trang tương ứng.

Xem demo

Truy cập vào Url sau và xem kết quả:

http://hostname/index.php?r=country/index

Danh sách Country

Hãy xem, bạn sẽ thấy một trang hiển thị 4 country. Phần dưới danh sách các country, bạn sẽ thấy các nút phân trang. Nếu bạn click vào button "2", bạn sẽ thấy 5 country khác trong CSDL: trang thứ 2 trong CSDL country. Bạn để ý rằng URL trong trình duyệt cũng thay đổi.

http://hostname/index.php?r=country/index&page=2

Trong luồng xử lý này, đối tượng Pagination sẽ cung cấp tất cả những hàm cần thiết cho việc phân trang:

  • Khởi tạo, đối tượng Pagination hiển thị ở trang đầu tiên , điều này được thực hiện câu lệnh truy vấn SELECT từ country với mệnh đề LIMIT 5 OFFSET 0. Như kết quả trên, 5 country đầu tiên sẽ lấy ra và hiển thị.
  • Widget LinkPager sẽ tạo các buttons cùng với các URL( liên kết) được tạo bởi phương thức Pagination. Các URL sẽ chứa tham số page, page sẽtương ứng với số trang khác nhau trong CSDL country.
  • Nếu bạn click vào button "2", route country/index được gọi và đồng thời route sẽ được gắn và giữ. Đối tượng Pagination đọc số trang từ tham số page từ Url và thiết lập trang trang hiện tại là 2. Việc truy vấn dữ liệu country tương tự như mệnh đề LIMIT 5 OFFSET 5 và trả về tiếp 5 country để hiển thị

Tổng kết

Bài hướng dẫn này, giúp bạn tìm hiểu và làm việc với CSDL. Bạn cũng được tìm hiều đối tượng yii\data\Paginationyii\widgets\LinkPager. giúp cho việc lấy và hiển thì dữ liệu trên trang.

Trong phần tới, bạn sẽ được tìm hiểu về công cụ generate code khá mạnh, được gọi là Gii, giúp bạn nhanh chóng thực hiện một số tính năng tương tự, những hoạt động thao tác với các bảng trong CSDL như Tạo-Xem-Cập nhật-Xóa (CRUD) . Trong thực tế, những mã nguồn được viết có thể tự động generate trong Yii sử dụng công cụ Gii.