仕事でどうしてもFuelPHPでOracleを扱う必要があり、
標準のORMでは扱うことが出来なかったため他の手段を探していた。
Symfonyで使われているdoctrine2が使えれば楽だなと思い少し試した話をメモしておく。
※ データベースのテーブルは作ってある前提
doctrine2を使うためのライブラリ
調べてみると既にライブラリがあったのでそれを利用してみる。
構成
最初は以下の様な標準のディレクトリ構成にする。
yourdirectory/
core/ # fuelphpのcore
packages/ # fuelphpのpackages
app/ # fuelphpのapp
bootstrap.php
classes/
config/
views/
vendor/ # この下にライブラリを置く
インストール
composerでインストールが可能なので、まず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
何もしないと読み込まれず使えないので読み込まれるようにする。
<?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の設定もやらないと使えない。
<?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で扱うための設定をする。
都度追加するのはめんどくさいので基底クラスを作りそれを継承、継承しているものだけ許可をするようにする。
<?php
return array(
// ...
'security' => array(
'whitelisted_classes' => array(
'Fuel\\Core\\Response',
'Fuel\\Core\\View',
'Fuel\\Core\\ViewModel',
'Closure',
'Entity\\Base', // これを追加する
),
),
// ...
);
エンティティを作る
定義をyamlなどで作ってコマンドで作れる。
...が、色々工夫しないと作れず、今回はお試しなので一旦手作業で作ることにする。
今回は簡単にキャンペーンのエンティティを作るだけにする。
<?php
namespace Entity;
/**
* Viewのセキュリティ機能を通過させる為に作る基底クラス
*/
class Base
{
}
<?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;
}
}
リポジトリも作る。
メソッドはキャンペーン一覧を取得するだけ。
<?php
namespace Entity;
use Doctrine\ORM\EntityRepository;
class CampaignRepository extends EntityRepository
{
public function getCampaignList()
{
$qb = $this->createQueryBuilder('c');
return $qb->getQuery()->getResult();
}
}
Controllerから使ってみる
先ほど作ってリポジトリからキャンペーン一覧を取得するだけの簡単なものを作成。
<?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から使い表示する。
{% 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とかも試したい所だけど時間がなく断念。
以上。