phalcon モデルの初期設定


まずは。phalconでデータベースへアクセスする設定です。
今回、利用するデータベースはMysqlです。

サービスへ登録

まずは、必要なファイルの読み込みです。

use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;

$di = new FactoryDefault();

必要情報を登録していきます。

$di->set('db', function() use($config){
    $dbAdapter =  new DbAdapter(array(
        "host" => $config->database->host,
        "username" => $config->database->username,
        "password" => $config->database->password,
        "dbname" => $config->database->dbname,
        "charset" => $config->database->charset,
        ));
    return $dbAdapter;
});

これで設定は完了ですが、$configの説明を指定しておきましょう。
以前、チュートリアルの回で説明した方法とは少し違います。

私のフォルダ構成の紹介

今回は設定ファイルを設けました。ですので、私がよく使うフォルダ構成を紹介します。

フォルダ構成をマネする必要もありませんが、参考になればと思います。
app/config
app/controllers
app/models
app/logs
app/views
上記にのようにapp配下を設定します。

そして、app/configの中に下のファイルを作成します。
config.ini
loader.php
services.php

アプリケーションのロード時にこのconfigフォルダの中身を読み込みます。
読み込ませる方法は、publicフォルダの中のindex.phpで指定します。
このindex.phpファイルは、htaccessで一番最初に読み込むように指定されているはずです。
index.phpの中身は

<?php
error_reporting(E_ALL);

use Phalcon\Mvc\Application;
use Phalcon\Config\Adapter\Ini as ConfigIni;
try{
    define("APP_PATH", realpath('..').'/');

    //設定読み込み
    $config = new ConfigIni(APP_PATH . 'app/config/config.ini');

    //loader読み込み
    require APP_PATH . 'app/config/loader.php';

    //service読み込み
    require APP_PATH . 'app/config/services.php';

    $app = new \Phalcon\Mvc\Application($di);
    echo $app->handle()->getContent();

}catch (\Exception $e){
    echo $e->getMessage();
}
?>

まずは、Phalcon\Config\Adapter\Iniを利用してiniファイルを読み込みます。
その後ほかのファイルを読み込みます。

このiniファイルの中には、以下のように設定します。適宜、あなたのプロジェクトに合わせて置き換えてください

[database]
host = localhost
username = example_db_username
password = example_db_password
dbname = example_db_dbname
charset = utf8

[application]
controllersDir = app/controllers/
modelsDir = app/models/
viewsDir = app/views/
pluginsDir = app/plugins/
libraryDir = app/library/
formsDir = app/forms/
baseUri = /

[debug]
debug = true

loader.phpでは、ディレクトリの指定を行います。
ここで、$configは先のPhalcon\Config\Adapter\Ini で読み込んだconfig.iniの中身が参照できます。

<?php
$loader = new \Phalcon\Loader();

$loader->registerDirs(
    array(
        APP_PATH.$config->application->controllersDir,
        APP_PATH.$config->application->pluginsDir,
        APP_PATH.$config->application->libraryDir,
        APP_PATH.$config->application->modelsDir,
        APP_PATH.$config->application->formsDir,
    )
)->register();
?>

services.phpでは具体的に利用したいサービスを追加していきます。例えば、データベースの利用やセッションの利用、voltエンジンの利用などです。

ここでも、$configは利用でき、config.iniにアクセスできます。

話はそれましたが、先ほどのデータベースを利用するためのサービス登録にあった$configは理解できたとおもいます。
function内部で$configを利用する際は、use($config)をわすれずに。
詳しくは、phpマニュアル 無名関数を参考にしてください。

$di->set('db', function() use($config){
    $dbAdapter =  new DbAdapter(array(
        "host" => $config->database->host,
        "username" => $config->database->username,
        "password" => $config->database->password,
        "dbname" => $config->database->dbname,
        "charset" => $config->database->charset,
        ));
    return $dbAdapter;
});

さらに、sqlのデバッグを行いたい時が必ずあります。なぜなら、phalconでのクエリの取得方法は、モデルの利用法(findとかhasMany)のほかに、クエリビルダを使う方法、PHQLでほぼダイレクトにSQL分を書く方法などがありますが、思ったようにデータが取得できているか不安になるのがプログラマーですwww

sqlデバッグの利用

上のデータベースを利用するためのサービス登録に追加を行います。
下の必要なファイルの読み込みを追加します。

use Phalcon\Logger as Logger;
use Phalcon\Logger\Adapter\File as FileLogger;

そして、サービスを少し変更します。

//DB
$di->set('db', function() use($config){
    $dbAdapter =  new DbAdapter(array(
        "host" => $config->database->host,
        "username" => $config->database->username,
        "password" => $config->database->password,
        "dbname" => $config->database->dbname,
        "charset" => $config->database->charset,
        ));
    if ($config->debug->debug) {
        $eventsManager = new EventsManager();
        $logger = new FileLogger("./../app/logs/sql.log");
        $eventsManager->attach('db', function($event, $dbAdapter) use ($logger) {
            if ($event->getType() == 'beforeQuery') {
                $logger->log($dbAdapter->getSQLStatement(), Logger::INFO);
            }
        });
        $dbAdapter->setEventsManager($eventsManager);
    }
    return $dbAdapter;
});

これは、config.iniのdebugがtrueの時にapp/logs/sql.logというファイルにsqlを書き出します。
不要な時は、config.iniのdebugをfalseにしましょう。

モデルの作成

私はこの先、データを取得・更新するいくつかの方法を紹介していきます。
その前にphaclonのドキュメントに合わせて、robots,robots_parts,partsというテーブルを使って説明して行きます。
テーブルの定義は以下の通りです。

CREATE TABLE `robots` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(70) NOT NULL,
    `type` varchar(32) NOT NULL,
    `year` int(11) NOT NULL,
    PRIMARY KEY (`id`)
);

CREATE TABLE `robots_parts` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `robots_id` int(10) NOT NULL,
    `parts_id` int(10) NOT NULL,
    `created_at` DATE NOT NULL,
    PRIMARY KEY (`id`),
    KEY `robots_id` (`robots_id`),
    KEY `parts_id` (`parts_id`)
);

CREATE TABLE `parts` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(70) NOT NULL,
    PRIMARY KEY (`id`)
);

モデル名は、キャメルケースで表記しましょう。キャメルケースとは、簡単にいうと単語の区切る際に、1文字目を大文字にするということです。
例えば、
robots => Robots
robots_parts => RobotsParts
parts => Parts
となります。

つまりモデルのファイル名は、Robots.php, RobotsParts.php, Parts.phpで作成します。

モデルは、最低限下のように定義してあげましょう

<?php

use Phalcon\Mvc\Model;

class Robots extends Model
{

}
?>

必ず、Phalcon\Mvc\Modelを読み込み、継承しましょう。そうしないと、MVCモデルの恩恵にあやかれませんwww
デフォルトでは、ファイル名とテーブル名がリンクするようになっています。Robotsならrobotsというテーブルを参照します。

マッピングされたテーブルを変更することもできます。

class Robots extends Model
{
    public function getSource()
    {
        return "the_robots";
    }
}

または、

class Robots extends Model
{
    public function initialize()
    {
        $this->setSource("the_robots");
    }
}

のようにすると、マッピングされたテーブルはthe_robotsになりますが、わざわざマッピングを変える必要もないと思うので、テーブル名がクラス名になるように作成したほうが無難だと思います。

モデルオブジェクトのデータへのアクセス方法です。
1つ目はパブリックプロパティ

use Phalcon\Mvc\Model;

class Robots extends Model
{
    public $id;

    public $name;

    public $price;
}

のように、プロパティをパブリックにしてしまう方法です。
これは、モデルクラスがインスタンス化されたコードのどの部分からでも更新/読み取ることができます。
昔はよろしくないといわれていましたが、最近は主流な気がします。

もうひちつは、おなじみのゲッターセッターを利用します。

class Robots extends Model
{
    protected $id;

    protected $name;

    protected $price;

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

    public function setName($name)
    {
        // 名前が短すぎる?
        if (strlen($name) < 10) {
            throw new \InvalidArgumentException('The name is too short');
        }
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setPrice($price)
    {
        // マイナスの価格が許可されていません
        if ($price < 0) {
            throw new \InvalidArgumentException('Price can\'t be negative');
        }
        $this->price = $price;
    }

    public function getPrice()
    {
        // 使用する前にdouble型に変換する
        return (double) $this->price;
    }
}

ゲッターセッターはオブジェクトに格納されたデータに検証ルールを追加するか制御することがもできます。保守性は高いです。
誤解しないでほしいのは、この方法じゃないとバリデーションができないという意味ではありません。
もちろん、データの保存時はパブリックプロパティな方法でも検証を行えます。

アプリケーションに合わせて選びましょう。

データの検索方法については下の方法があります。
執筆中です。


投稿日: 2016年7月21日
カテゴリー: phalcon|php | 投稿者: