4 フォロワー

データベースの操作

このセクションでは、country という名前のデータベーステーブルからフェッチされた国データを表示する新しいページを作成する方法について説明します。この目標を達成するために、データベース接続を構成し、アクティブレコードクラスを作成し、アクションを定義し、ビューを作成します。

このチュートリアルを通して、次のことを学びます。

  • DB 接続を構成する
  • アクティブレコードクラスを定義する
  • アクティブレコードクラスを使用してデータをクエリする
  • ページネーション付きのビューでデータを表示する

このセクションを完了するには、データベースを使用する基本的な知識と経験が必要であることに注意してください。特に、データベースを作成する方法、および DB クライアントツールを使用して SQL ステートメントを実行する方法を知っている必要があります。

データベースの準備

まず、アプリケーションでデータをフェッチする yii2basic という名前のデータベースを作成します。Yii は多くのデータベースアプリケーションを組み込みでサポートしているため、SQLite、MySQL、PostgreSQL、MSSQL、または Oracle データベースを作成できます。説明を簡単にするため、以下では 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 という名前のデータベースと、その中に 3 つの列を持つ country テーブルがあり、10 行のデータが含まれています。

DB 接続の構成

始める前に、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クエリを実行できます。

上記で設定されたDB接続は、アプリケーションコード内でYii::$app->dbという式を介してアクセスできます。

情報: config/db.phpファイルは、メインアプリケーションの設定ファイルであるconfig/web.phpによってインクルードされます。これは、アプリケーションインスタンスをどのように初期化するかを指定します。詳細については、設定セクションを参照してください。

Yiiにバンドルされていないデータベースを操作する必要がある場合は、以下の拡張機能を確認してください。

アクティブレコードの作成

countryテーブルのデータを表現および取得するには、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();

情報: アクティブレコードは、オブジェクト指向の方法でデータベースデータにアクセスし操作するための強力な方法です。詳細については、アクティブレコードセクションを参照してください。または、データベースアクセスオブジェクトと呼ばれる低レベルのデータアクセス方法を使用してデータベースと対話することもできます。

アクションの作成

国データをエンドユーザーに公開するには、新しいアクションを作成する必要があります。前のセクションで行ったように、新しいアクションを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オブジェクトは、2つの目的を果たします。

  • クエリオブジェクトで表されるSQLステートメントにoffsetおよびlimit句を設定し、一度に1ページ分のデータのみを返すようにします(1ページあたり最大5行)。
  • 次のサブセクションで説明するように、ページボタンのリストで構成されるページャを表示するために、ビューで使用されます。

次に、all()は、クエリ結果に基づいてすべてのcountryレコードを返します。

コードの最後に、indexアクションはindexという名前のビューをレンダリングし、返された国データとページネーション情報を渡します。

ビューの作成

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

ビューには、国データを表示することに関連する2つのセクションがあります。最初の部分では、提供された国データがトラバースされ、順序なしHTMLリストとしてレンダリングされます。2番目の部分では、アクションから渡されたページネーション情報を使用してyii\widgets\LinkPagerウィジェットがレンダリングされます。LinkPagerウィジェットは、ページボタンのリストを表示します。いずれかをクリックすると、対応するページの国データが更新されます。

試してみる

上記のすべてのコードがどのように機能するかを確認するには、ブラウザを使用して次のURLにアクセスしてください。

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

Country List

最初に、5つの国を表示するページが表示されます。国の下に、4つのボタンがあるページャーが表示されます。「2」ボタンをクリックすると、データベース内の別の5つの国、つまりレコードの2ページ目がページに表示されます。注意深く観察すると、ブラウザのURLも次のように変化していることがわかります。

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

舞台裏では、Paginationが、データセットをページ分割するために必要なすべての機能を提供しています。

  • 最初は、Paginationは、LIMIT 5 OFFSET 0句を含む国SELECTクエリを反映した最初のページを表します。その結果、最初の5つの国がフェッチされ表示されます。
  • LinkPagerウィジェットは、Paginationによって作成されたURLを使用してページボタンをレンダリングします。URLには、異なるページ番号を表すクエリパラメータpageが含まれます。
  • ページボタン「2」をクリックすると、ルートcountry/indexの新しいリクエストがトリガーされ、処理されます。Paginationは、URLからpageクエリパラメータを読み取り、現在のページ番号を2に設定します。したがって、新しい国クエリには、LIMIT 5 OFFSET 5句が含まれ、表示のために次の5つの国が返されます。

まとめ

このセクションでは、データベースを操作する方法を学びました。yii\data\Paginationyii\widgets\LinkPagerを使用して、データをページでフェッチおよび表示する方法も学びました。

次のセクションでは、Giiと呼ばれる強力なコード生成ツールを使用して、データベーステーブル内のデータを操作するためのCreate-Read-Update-Delete(CRUD)操作など、一般的に必要とされる機能を迅速に実装する方法を学びます。実際、今書いたコードはすべて、Giiツールを使用してYiiで自動的に生成できます。

タイプミスを見つけたり、このページを改善する必要があると思われる場合は?
githubで編集 !