4 追蹤者

使用資料庫

本節將描述如何建立一個新頁面,顯示從名為 country 的資料庫表格中取得的國家資料。為了達成這個目標,您將設定資料庫連線、建立 Active Record 類別、定義一個 動作 (action),並建立一個 視圖 (view)

透過本教學,您將學習如何

  • 設定資料庫連線,
  • 定義 Active Record 類別,
  • 使用 Active Record 類別查詢資料,
  • 以分頁方式在視圖中顯示資料。

請注意,為了完成本節,您應該具備使用資料庫的基本知識和經驗。特別是,您應該知道如何建立資料庫,以及如何使用資料庫客戶端工具執行 SQL 語句。

準備資料庫

首先,建立一個名為 yii2basic 的資料庫,您將從該資料庫中取得應用程式中的資料。您可以建立 SQLite、MySQL、PostgreSQL、MSSQL 或 Oracle 資料庫,因為 Yii 內建支援許多資料庫應用程式。為了簡化說明,以下描述將以 MySQL 為例。

資訊:雖然 MariaDB 曾經是 MySQL 的直接替代品,但現在已不再完全如此。如果您希望在 MariaDB 中使用 JSON 支援等進階功能,請查看下面列出的 MariaDB 擴充套件。

接下來,在資料庫中建立一個名為 country 的表格,並插入一些範例資料。您可以執行以下 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',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);

此時,您有一個名為 yii2basic 的資料庫,其中包含一個 country 表格,其中包含三個欄位,包含十列資料。

設定資料庫連線

在繼續之前,請確保您已安裝 PDO PHP 擴充套件和您正在使用的資料庫的 PDO 驅動程式(例如 MySQL 的 pdo_mysql)。如果您的應用程式使用關聯式資料庫,這是基本要求。

安裝完成後,開啟 config/db.php 檔案並更改參數,使其與您的資料庫相符。預設情況下,該檔案包含以下內容

<?php

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

config/db.php 檔案是一個典型的基於檔案的 設定 工具。此特定設定檔指定建立和初始化 yii\db\Connection 實例所需的參數,您可以透過該實例對底層資料庫進行 SQL 查詢。

上面設定的資料庫連線可以在應用程式程式碼中透過 Yii::$app->db 表達式存取。

資訊:config/db.php 檔案將由主應用程式設定檔 config/web.php 包含,後者指定應如何初始化 應用程式 實例。有關更多資訊,請參閱 設定 章節。

如果您需要使用 Yii 未捆綁支援的資料庫,請查看以下擴充套件

建立 Active Record

為了表示和取得 country 表格中的資料,請建立一個 Active Record 衍生類別,名為 Country,並將其儲存在 models/Country.php 檔案中。

<?php

namespace app\models;

use yii\db\ActiveRecord;

class Country extends ActiveRecord
{
}

Country 類別繼承自 yii\db\ActiveRecord。您不需要在其中編寫任何程式碼!僅使用上述程式碼,Yii 就會從類別名稱猜測相關的表格名稱。

資訊:如果無法從類別名稱直接比對到表格名稱,您可以覆寫 yii\db\ActiveRecord::tableName() 方法來明確指定相關的表格名稱。

使用 Country 類別,您可以輕鬆地操作 country 表格中的資料,如以下程式碼片段所示

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();

資訊:Active Record 是一種以物件導向方式存取和操作資料庫資料的強大方法。您可以在 Active Record 章節中找到更詳細的資訊。或者,您也可以使用稱為 資料庫存取物件 的較低層級的資料存取方法與資料庫互動。

建立動作 (Action)

為了向終端使用者公開國家資料,您需要建立一個新的動作 (action)。與前幾節中在 site 控制器中放置新動作不同,為所有與國家資料相關的動作建立一個新的控制器更有意義。將這個新的控制器命名為 CountryController,並在其中建立一個 index 動作,如下所示。

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

將上述程式碼儲存在 controllers/CountryController.php 檔案中。

首先,index 動作呼叫 Country::find()find() 方法建立一個 ActiveQuery 查詢物件,該物件提供從 country 表格存取資料的方法。

為了限制每個請求中傳回的國家數量,查詢物件藉助 yii\data\Pagination 物件進行分頁。Pagination 物件有兩個用途

  • 為查詢物件表示的 SQL 語句設定 offsetlimit 子句,使其一次只傳回一頁資料(每頁最多 5 列)。
  • 它在視圖中用於顯示由頁面按鈕列表組成的分頁器,這將在下一小節中說明。

接下來,all() 根據查詢結果傳回所有 country 記錄。

在程式碼的末尾,index 動作渲染一個名為 index 的視圖,並將傳回的國家資料以及分頁資訊傳遞給它。

建立視圖 (View)

views 目錄下,首先建立一個名為 country 的子目錄。此資料夾將用於保存由 country 控制器渲染的所有視圖。在 views/country 目錄中,建立一個名為 index.php 的檔案,其中包含以下內容

<?php
use yii\helpers\Html;
use yii\widgets\LinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->code} ({$country->name})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>

視圖有兩個部分與顯示國家資料相關。在第一部分中,提供的國家資料被遍歷並渲染為無序 HTML 列表。在第二部分中,使用從動作傳遞的分頁資訊渲染 yii\widgets\LinkPager 小部件。LinkPager 小部件顯示頁面按鈕列表。點擊其中任何一個按鈕將刷新相應頁面中的國家資料。

試用看看

要查看上述所有程式碼如何運作,請使用您的瀏覽器存取以下 URL

https://hostname/index.php?r=country%2Findex

Country List

首先,您將看到一個頁面顯示五個國家。在國家下方,您將看到一個包含四個按鈕的分頁器。如果您點擊按鈕「2」,您將看到該頁面顯示資料庫中的另外五個國家:第二頁記錄。更仔細地觀察,您會發現瀏覽器中的 URL 也變更為

https://hostname/index.php?r=country%2Findex&page=2

在幕後,Pagination 正在提供所有必要的功能來分頁資料集

  • 最初,Pagination 表示第一頁,它反映了包含子句 LIMIT 5 OFFSET 0 的國家 SELECT 查詢。因此,將取得並顯示前五個國家。
  • LinkPager 小部件使用 Pagination 建立的 URL 渲染頁面按鈕。URL 將包含查詢參數 page,它表示不同的頁碼。
  • 如果您點擊頁面按鈕「2」,將觸發並處理對路由 country/index 的新請求。Pagination 從 URL 讀取 page 查詢參數,並將目前頁碼設定為 2。因此,新的國家查詢將具有子句 LIMIT 5 OFFSET 5,並傳回接下來五個國家以供顯示。

總結

在本節中,您學習了如何使用資料庫。您還學習了如何在 yii\data\Paginationyii\widgets\LinkPager 的幫助下,以分頁方式取得和顯示資料。

在下一節中,您將學習如何使用強大的程式碼生成工具,稱為 Gii,以協助您快速實作一些常見的必要功能,例如用於處理資料庫表格中資料的建立-讀取-更新-刪除 (CRUD) 操作。事實上,您剛剛編寫的程式碼都可以使用 Gii 工具在 Yii 中自動生成。

發現錯字或您認為此頁面需要改進嗎?
在 github 上編輯 !