search
LoginSignup
18

More than 5 years have passed since last update.

posted at

updated at

FuelPHPでdoctrine2を使ってみた

仕事でどうしても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を作る。

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とかも試したい所だけど時間がなく断念。

以上。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
18