まずは。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; } }
ゲッターセッターはオブジェクトに格納されたデータに検証ルールを追加するか制御することがもできます。保守性は高いです。
誤解しないでほしいのは、この方法じゃないとバリデーションができないという意味ではありません。
もちろん、データの保存時はパブリックプロパティな方法でも検証を行えます。
アプリケーションに合わせて選びましょう。
データの検索方法については下の方法があります。
執筆中です。