PHP
FuelPHP
Doctrine2

FuelPHPでdoctrine2を使ってみた

More than 3 years have passed since last update.

仕事でどうしてもFuelPHPでOracleを扱う必要があり、

標準のORMでは扱うことが出来なかったため他の手段を探していた。

Symfonyで使われているdoctrine2が使えれば楽だなと思い少し試した話をメモしておく。

※ データベースのテーブルは作ってある前提


doctrine2を使うためのライブラリ

調べてみると既にライブラリがあったのでそれを利用してみる。

https://github.com/aspendigital/fuel-doctrine2


構成

最初は以下の様な標準のディレクトリ構成にする。

yourdirectory/

core/ # fuelphpのcore
packages/ # fuelphpのpackages
app/ # fuelphpのapp
bootstrap.php
classes/
config/
views/
vendor/ # この下にライブラリを置く


インストール

composerでインストールが可能なので、まずcomposer.jsonを作る。


composer.json

{

"require": {
"aspendigital/fuel-doctrine2": "dev-master"
},
"config": {
"vendor-dir": "app/vendor"
},
"minimum-stability": "dev"
}

composerでinstallする。

$ curl -s 'http://getcomposer.org/installer' |php

$ php composer.phar install

ちゃんとインストールされれば app/vendor の下に色々置かれているはず。


doctrine2を使うための設定


autoload

何もしないと読み込まれず使えないので読み込まれるようにする。


app/bootstrap.php

<?php

// Load in the Autoloader
require COREPATH.'classes'.DIRECTORY_SEPARATOR.'autoloader.php';
class_alias('Fuel\\Core\\Autoloader', 'Autoloader');

// Bootstrap the framework DO NOT edit this
require COREPATH.'bootstrap.php';

/**
* ここから追加
*/

// app/vendor以下をautoloadする
require APPPATH.'vendor'.DIRECTORY_SEPARATOR.'autoload.php';

// EntityとRepositoryが属する\EntityネームスペースをFuelPHPのAutoloaderに追加
Autoloader::add_namespace('Entity', APPPATH.'classes'.DIRECTORY_SEPARATOR.'entity'.DIRECTORY_SEPARATOR);
/**
* ここまで
*/

Autoloader::add_classes(array(
));

// Register the autoloader
Autoloader::register();

/**
* Your environment. Can be set to any of the following:
*
* Fuel::DEVELOPMENT
* Fuel::TEST
* Fuel::STAGING
* Fuel::PRODUCTION
*/

Fuel::$env = (isset($_SERVER['FUEL_ENV']) ? $_SERVER['FUEL_ENV'] : Fuel::DEVELOPMENT);

// Initialize the framework with the config file.
Fuel::init('config.php');



db

databaseの設定もやらないと使えない。


app/config/db.php

<?php

return array(
'doctrine2' => array(
'proxy_dir' => APPPATH.'classes'.DIRECTORY_SEPARATOR.'proxy',
'proxy_namespace' => 'Proxy',
'metadata_path' => APPPATH.'classes'.DIRECTORY_SEPARATOR.'entity',
),
'default' => array(
'type' => 'pdo',
'connection' => array(
'dsn' => 'oci:dbname=yourdb', // これはoracle用の設定
'username' => 'yourdbusername',
'password' => 'yourdbpasswd',
'persistent' => false,
),
'identifier' => '',
'table_prefix' => '',
'charset' => 'utf8',
'caching' => true,
'profiling' => false,
),
);



view

EntityクラスがFuelPHPのセキュリティ機能に引っかかってしまうため、viewで扱うための設定をする。

都度追加するのはめんどくさいので基底クラスを作りそれを継承、継承しているものだけ許可をするようにする。


app/config/config.php

<?php

return array(
// ...
'security' => array(
'whitelisted_classes' => array(
'Fuel\\Core\\Response',
'Fuel\\Core\\View',
'Fuel\\Core\\ViewModel',
'Closure',
'Entity\\Base', // これを追加する
),
),
// ...
);



エンティティを作る

定義をyamlなどで作ってコマンドで作れる。

...が、色々工夫しないと作れず、今回はお試しなので一旦手作業で作ることにする。

今回は簡単にキャンペーンのエンティティを作るだけにする。


app/classes/entity/base.php

<?php

namespace Entity;

/**
* Viewのセキュリティ機能を通過させる為に作る基底クラス
*/

class Base
{
}



app/classes/entity/campaign.php

<?php

namespace Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @Entity(repositoryClass="Entity\CampaignRepository")
* @Table(name="campaigns")
*/

class Campaign extends Base
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/

protected $id;

/**
* @Column(type="string", length=512)
*/

protected $title;

public function setId($id)
{
$this->id = $id;

return $this;
}

public function setTitle($title)
{
$this->title = $title;

return $this;
}

public function getId()
{
return $this->id;
}

public function getTitle()
{
return $this->title;
}
}


リポジトリも作る。

メソッドはキャンペーン一覧を取得するだけ。


app/classes/entity/campaignrepository.php

<?php

namespace Entity;

use Doctrine\ORM\EntityRepository;

class CampaignRepository extends EntityRepository
{
public function getCampaignList()
{
$qb = $this->createQueryBuilder('c');
return $qb->getQuery()->getResult();
}
}



Controllerから使ってみる

先ほど作ってリポジトリからキャンペーン一覧を取得するだけの簡単なものを作成。


app/classes/controller/campaign.php

<?php

use \Fuel\Core\Controller;

class Controller_Campaign extends Controller
{
public function action_list()
{
$em = \Fuel\Doctrine::manager();
$campaigns = $em->getRepository('Entity\Campaign')->getCampaignList();

$this->theme
->set_template('campaign/list.html.twig')
->set(array(
'campaigns' => $campaigns,
));

return \Response::forge($this->theme);
}
}



Viewから使う

Controllerにて取得したものをViewから使い表示する。


app/views/pc/campaign/list.html.twig

{% extends 'pc/layout.html.twig' %}

{% block contents %}
<h1>キャンペーン一覧</h1>

{% if campaigns is empty %}
<p>キャンペーンはありません</p>
{% else %}
<ul>
{% for campaign in campaigns %}
<li>{{ campaign.id }} : {{ campaign.title }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock contents %}



終わり

基本のfetchできるかだけ試した。

insert,update,deleteも試したいし、paginationとかも試したい所だけど時間がなく断念。

以上。