Help us understand the problem. What is going on with this article?

FuelPHPでdoctrine2を使ってみた

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

以上。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした