シムノート

PHPフレームワークSymfonyの学習帳

ユーザ用ツール

サイト用ツール


サイドバー

メニュー



このエントリーをはてなブックマークに追加

blog:2015-12-12:超入門_symfony3_doctrine_orm_前篇

超入門 Symfony3 : (6) Doctrine ORM【前編】

Symfonyではデータベース(以下、DB)とデータをやり取りするのに、DoctrineというORMを使います。ORMとはDBのデータとPHPのクラスをマッピングして変換する技法のことです。

ここでは、おみくじの運勢をDBに格納し、Doctrineを使って操作するようにアプリケーションを変更します。

※ 上記画像はSymfony公式サイトより

データベースの設定

まずは、DBの設定を行います。ここでは、簡単に利用できるSQLiteを使用します。下記のように設定ファイルを修正します。

...
# Doctrine Configuration
doctrine:
    dbal:
        # pdo_sqliteに変更します
        driver:   pdo_sqlite
        # 追加します
        path:     "%database_path%"
...

parameters:
    ...
    # You should uncomment this if you want use pdo_sqlite
    # コメントアウトしてパスを変更します
    database_path: "%kernel.root_dir%/../var/data.db3"
    ...

parameters:
    # 追加します
    database_path: "%kernel.root_dir%/../var/data.db3"
    ....

2015/12/05 20:22

SQLiteのDBファイルを作成します。

$ touch var/data.db3

EntityとRepositoryの作成

DoctrineではPHPのクラスを作成してから、それを基にしてDBのテーブルを作成します。DBのテーブルにマッピングするクラスをEntityと言います。

consoleコマンドを使って、Unseiエンティティを生成します。

$ php bin/console doctrine:generate:entity

The Entity shortcut name: AppBundle:Unsei [Enter]
Configuration format (yml, xml, php, or annotation) [annotation]: [Enter]
New field name (press <return> to stop adding fields): [Enter]

> Generating entity class src/AppBundle/Entity/Unsei.php: OK!
> Generating repository class src/AppBundle/Repository/UnseiRepository.php: OK!

Unsei.phpと一緒にUnseiRepository.phpも作成されました。後者のクラスをリポジトリと言います。リポジトリとは一般的に何かを保管している所という意味です。DBで例えると、リポジトリがDBテーブルで、エンティティがDBテーブルの行(row)にあたります。Unseiエンティティを取得するときには、UnseiRepositoryに問い合わせてUnseiエンティティを取得することになります。

EntityとRepositoryはMVCパターンに当てはめるとModelの位置付けになります。

マッピング情報

Unsei.phpの中身を見てみましょう。

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM; // (a)

/**
 * Unsei
 *
 * // ①
 * @ORM\Table(name="unsei")
 * // ②
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UnseiRepository")
 */
class Unsei
{
    /**
     * @var int
     *
     * // ③
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id; // ④


    /**
     * Get id
     *
     * @return int
     */
    public function getId() // ⑤
    {
        return $this->id;
    }
}

① アノテーションを使って、UnseiクラスをDBのunseiテーブルにマッピングしています。(a)でDoctrine\ORM\MappingクラスをインポートしてORMという別名を付けています。Doctrine関連のアノテーションは全て@ORM\XXXXとなります。

② Unseiエンティティに対するRepositoryを定義しています。先ほど一緒に作成されたUnseiRepositoryが定義されています。

③ idプロパティとDBテーブルのカラムをマッピングしています。マッピング先がinteger型のidカラムであり、ID(プライマリーキー)であること、自動で値を割り当てることが定義されています。

④ idプロパティが生成されています。Entityはオブジェクトを一意に識別する為にidプロパティを持ちます。

⑤ idのGetterも生成されています。

@ORMアノテーションを使って、EntityとDBのテーブルクラスをマッピングする。
Entityはオブジェクトを一意に識別する為のidを持つ。

GetterとSetterの生成

Unseiクラスにnameプロパティを追加します。

...
class Unsei
{
    ...
    private $id;

    /**
     * @ORM\Column(name="name", type="string") // ①
     */
    private $name;

    ...
}

① nameプロパティを追加し、DBテーブルのstring型のnameカラムにマッピングしました。DBテーブルのカラム名がプロパティ名と同じでよければ、name="name"の部分は省略できます。マッピング設定の詳細はBasic Mappingを参照してください。

ここで、consoleコマンドを使って、nameプロパティのGetterとSetterを追加します。

$ php bin/console doctrine:generate:entities AppBundle/Entity/Unsei

...
class Unsei
{
    ...

    public function setName($name)
    {
        ...
    }

    public function getName()
    {
        ...
    }
}

GetterとSetterが追加されました。

Getter、Setterの内容は修正しても構いません。console doctrine:generate:entitiesコマンドは既に存在するGetter, Setterは上書きしない為、何度でも実行できます。

Entityを生成するコマンドと、GetterとSetterを生成するコマンドが似ているのて注意してください。

doctrine:generate:entity    Entityを生成するコマンド
doctrine:generate:entities  GetterとSetterの生成するコマンド

bin/consoleで実行できるコマンド一覧の表示、ヘルプの表示は以下のように行います。 詳細は「consoleコマンド」を参照してください。

$ php bin/console list | grep doctrine:ent
  generate:doctrine:entities    Generates entity classes and method stubs from your mapping information
  generate:doctrine:entity      Generates a new Doctrine entity inside a bundle

$ php bin/console generate:doctrine:entities --help
Usage:
  doctrine:generate:entities [options] [--] <name>
  generate:doctrine:entities

Arguments:
  name                  A bundle name, a namespace, or a class name

テーブルスキーマの作成

Unseiエンティティが完成したので、その内容でDBテーブルを作成します。

$ php bin/console doctrine:schema:update --force

データーベースの中身を確認してみます。

$ sqlite3 var/data.db3 

sqlite> .table
unsei

sqlite> .schema
CREATE TABLE unsei (id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id));

Unseiエンティティのマッピング情報から、unseiテーブルを作成できました。

SQLを使って、データを格納します。

sqlite> INSERT INTO unsei (name) VALUES ("大吉");
sqlite> INSERT INTO unsei (name) VALUES ("中吉");
sqlite> INSERT INTO unsei (name) VALUES ("小吉");
sqlite> INSERT INTO unsei (name) VALUES ("末吉");
sqlite> INSERT INTO unsei (name) VALUES ("凶");

sqlite> select * from unsei;
id          name      
----------  ----------
1           大吉    
2           中吉    
3           小吉    
4           末吉    
5           凶       

アプリケーションの修正

エンティティとレポジトリが出来たので、これらを使うようにアプリケーションを修正します。

まず、Controllerを修正します。

...
use AppBundle\Entity\Unsei;                // (a)
use AppBundle\Repository\UnseiRepository;  // (b)

class OmikujiController extends Controller
{
    ...
    public function omikujiAction(Request $request, $yourname)
    {
//         $omikuji = ['大吉', '中吉', '小吉', '末吉', '凶'];

        /** @var UnseiRepository */
        $repository = $this->getDoctrine()->getRepository(Unsei::class); // ①
        $omikuji = $repository->findAll(); // ②

        $number = rand(0, count($omikuji) - 1);

        return $this->render('omikuji/omikuji.html.twig', [
            'name' => $yourname,
            'unsei' => $omikuji[$number], // ③
        ]);
    }
}

Umseiエンティティに対応するリポジトリ、すなわちUnseiRepositoryを取得しています。
UnseiRepositoryから全てのエンティティを取得しています。ここで返ってくるのはUnseiエンティティのオブジェクトの配列です。
③ ランダムにピックアップしたUnseiエンティティをテンプレートに渡します。以前は文字列を渡していましたが、今回はUnseiエンティティのオブジェクトを渡していることに注意してください。テンプレート内での扱いが違ってきます。
(a)(b)のクラスのインポートもお忘れなく!

次に、Viewを修正します。

{% extends 'base.html.twig' %}

{% block title %}おみくじ{% endblock %}

{% block body %}
    {# {{ name }}さんの運勢は {{ unsei }} です。※コメントアウト #}
    {{ name }}さんの運勢は {{ unsei.name }} です。 {# ① #}
{% endblock %}

① 以前は文字列変数としてのunseiを表示していましたが、今回はunseiオブジェクトのnameプロパティを表示するように修正しました。twig内で、オブジェクトのプロパティにアクセスするには、“.”(ドット)を使います。

http://localhost:8000/omikuji/Agent_Dunham にアクセスして動作確認を行います。「Agent_Dunhamさんの運勢は XX です」と表示されます。


Comments



99 +5 = ?
blog/2015-12-12/超入門_symfony3_doctrine_orm_前篇.txt · 最終更新: 2015/12/27 19:01 by tsubo