BEAR.SundayでDoctrine2のORMを使ってみた(改)
77webさんの「BEAR.SundayでDoctrine2のORMを使ってみた」を試しつつ、少しだけ改良してみます。
BEAR.Sundayのインストール
ベンダー名はMy、アプリケーション名はNoteとします。これらの指定は名前空間で使われます。
$ composer create-project bear/skeleton My.Note dev-develop
$ cd My.Note
$ composer install
なお、ここではdev-developを指定して開発ブランチ(developブランチ)をインストールしています。
Doctrineのインストール
$ composer require 'doctrine/orm:2.4.*'
データベース接続設定
BEAR.Sundayではデータベース接続設定はvar/conf/constants.phpで定義します。
具体的にはデフォルトで以下のようになっています。
var/conf/constants.php
$masterDb = $slaveDb = require __DIR__  .'/db/sqlite.php';
//list($masterDb, $slaveDb) = require __DIR__  .'/db/mysql.php';
return [
    'prod' => [
        // optional
        'master_db' => $masterDb,
        'slave_db' => $slaveDb,
    ],
    'dev' => [],
    'api' => [],
    'test' => []
];
$masterDbと$slaveDbが定義されていますが、いずれもdb/sqlite.phpが代入されています。
prod環境(本番環境)でこれらのデータベースが指定されていますが、prod環境の設定が他の環境にも引き継がれるため、デフォルトではすべての環境でのデータベース接続設定は同じになっています。
db/sqlite.phpでは具体的には以下のように定義されています。
var/db/sqlite.php
$sqlite = [
    'driver' => 'pdo_sqlite',
    'path' =>  $appDir . '/var/db/posts.sq3'
];
つまり、var/db/posts.sq3が使用されるSQLiteのデータベースファイルということになります。
ここでは、デフォルトのままにします。
Providerの作成
DoctrineのEntityManagerを返すProviderを作成します。
とりあえず、マスターとスレーブの切り替えは考慮しません。
src/Module/Provider/DoctrineORMProvider.php
<?php
namespace My\Note\Module\Provider;
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
use Ray\Di\ProviderInterface;
use Ray\Di\Di\Inject;
use Ray\Di\Di\Named;
class DoctrineORMProvider implements ProviderInterface
{
    /**
     * @param array $masterDb
     *
     * @Inject
     * @Named("masterDb=master_db")
     */
    public function __construct(array $masterDb)
    {
        $this->masterDb = $masterDb;
    }
    public function get()
    {
        $paths = [__DIR__.'/../../Entity'];
        $isDevMode = false;
        $config = Setup::createAnnotationMetadataConfiguration(
            $paths, $isDevMode
        );
        $conn = $this->masterDb;
        return EntityManager::create($conn, $config);
    }
}
コンストラクタインジェクションでデータベース接続設定のmaster_dbをプロパティに代入しています。
Providerのインストール
DoctrineORMProviderを使うようにインストールします。
My\Note\Module\AppModuleクラスのconfigure()メソッドの最後に以下を追加します。
src/Module/AppModule.php
$this->bind('Doctrine\ORM\EntityManager')->toProvider('My\Note\Module\Provider\DoctrineORMProvider');
Entityの作成
Entityを作成します。
src/Entity/Note.php
<?php
namespace My\Note\Entity;
/**
 * @Entity
 * @Table(name="note")
 */
class Note
{
    /**
     * @var int
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
    private $id;
    /**
     * @var string
     * @Column(type="text")
     */
    private $body;
    public function getId() {
        return $this->id;
    }
    public function getBody() {
        return $this->body;
    }
    public function setId($id) {
        $this->id = $id;
    }
    public function setBody($body) {
        $this->body = $body;
    }
}
doctrineコマンドを使えるようにする
cli-config.phpをプロジェクトのルートディレクトリに作成します。
<?php
error_reporting(E_ALL);
ini_set('xdebug.max_nesting_level', 300);
require __DIR__ . '/bootstrap/autoload.php';
use My\Note\Module\AppModule;
use Ray\Di\Injector;
use Doctrine\ORM\Tools\Console\ConsoleRunner;
$module = new AppModule();
$injector = Injector::create([$module]);
$entityManager = $injector->getInstance('Doctrine\ORM\EntityManager');
return ConsoleRunner::createHelperSet($entityManager);
テーブルの作成
doctrineコマンドでテーブルを作成します。
$ php vendor/bin/doctrine orm:schema-tool:create
テストデータの登録
とりあえず、sqlite3コマンドでinsertしておきます。
$ sqlite3 var/db/posts.sq3
> insert into note(body) values('test body1');
> insert into note(body) values('test body2');
> .exit
Appリソースの作成
AppリソースNoteを作成します。
src/Resource/App/Note.php
<?php
namespace My\Note\Resource\App;
use BEAR\Resource\ResourceObject;
use Doctrine\ORM\EntityManager;
use Ray\Di\Di\Inject;
class Note extends ResourceObject
{
    /**
     * @var EntityManager
     */
    private $entityManager;
    /**
     * @param EntityManager $entityManager
     * @Inject
     */
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }
    public function onGet($id)
    {
        $note = $this->entityManager->find('My\Note\Entity\Note', $id);
        $this['note'] = ['body' => $note->getBody()];
        return $this;
    }
}
コンストラクタインジェクションでEntityManagerをプロパティに代入しています。
Noteリソースの取得
CLIからNoteリソースを取得してみます。
$ php bootstrap/contexts/api.php get 'app://self/note?id=1'
200 OK
content-type: ["application\/hal+json; charset=UTF-8"]
cache-control: ["no-cache"]
date: ["Fri, 11 Jul 2014 03:48:55 GMT"]
[BODY]
note => array(
  body test body1,
),
[VIEW]
{
    "note": {
        "body": "test body1"
    },
    "_links": {
        "self": {
            "href": "http://localhost/app/note/?id=1"
        }
    }
}
うまく取得できました!
参考
Date: 2014/07/11



![徹底攻略PHP5技術者認定[上級]試験問題集  [PJ0-200]対応 徹底攻略PHP5技術者認定[上級]試験問題集  [PJ0-200]対応](http://tatsu-zine.com/images/books/164/cover_s.jpg)

