FuelPHPでMongoDBを使う
FuelPHP Advent Calendar 2011、9日目です。
前日は@ounziw さんの「FuelPHP の view に PHPTAL デザインテンプレートを使う」でした。
FuelPHPはMongoDBも扱えるということで触ってみました。FuelPHP1.1-RC1を使ってます。
まずはMongoDBとPHPドライバ pecl mongoをインストールした状態から始めます。
pecl mongoは下記コマンドで一発インストール可能です。
pecl install mongo
ちょっと古いバージョンのpecl mongoだとセグメンテーションエラーが出たりするので、古いのが入っている人は最新版にするのをおすすめします。私が作ったPeclMongoの新バージョンがあればツイートするボットをフォローしてもらえると、すぐにアップデートタイミングがわかります :)
https://twitter.com/pecl_mongo_bot
MongoDBは最初にDBやテーブルを作らなくても、insert操作が発生した時に自動的に生成します。
Fuelから扱う場合も、特に最初にテーブルは作らなくても問題ありません。
では、最初にどのデータベースを扱うかの定義から。ここではblogというDBを利用する宣言をします。
app/config/db.php
return array( 'active' => 'default', 'mongo' => array( 'default' => array( 'hostname' => '127.0.0.1', 'port' => 27017, 'database' => 'blog', ) ), );
FuelでのMongoDB操作は、Mongo_Dbインスタンスを生成してメソッドを呼ぶだけなのでお手軽です。
Mongo_DbのAPIドキュメントはここにあります。
http://docs.fuelphp.com/classes/mongo/methods.html
下記では、postsテーブルからデータをfindして取得しています。
$mongodb = \Mongo_Db::instance(); $results = $mongodb->get('posts');
ORMとの連携は特にないので、RDBで使ってる\ORM\Modelのメソッドなどは利用できません。
これ使えばいけるかもしれません(未検証)
https://github.com/philsturgeon/fuel-mongo-odm
データ保存は
$mongodb = \Mongo_Db::instance(); $results = $mongodb->insert('posts', array('name' => 'ichi', 'body' => 'test'));
のように、配列でデータを入れます。
MongoDBはカラムの中にさらに配列を入れることも可能です。
$mongodb = \Mongo_Db::instance(); $results = $mongodb->insert('posts', array('name' => 'ichi', 'body' => array('aa','bb')));
とりあえず作ったサンプルアプリのコードをはっておきます。
まずはモデル
app/classes/model/blog.php
<?php use \Model_Crud; class Model_Blog extends Model_Crud { protected static $_table_name = 'posts'; public static function findMongo() { $table = self::$_table_name; $mongodb = \Mongo_Db::instance(); return $mongodb->get($table); } public static function insertMongo($data) { $table = self::$_table_name; $mongodb = \Mongo_Db::instance(); return $mongodb->insert($table, $data); } }
つぎにコントローラ
app/classes/controller/blog.php
<?php class Controller_Blog extends Controller_Template { public function action_index() { $results = Model_Blog::findMongo(); $this->template->title = 'Blog Index'; $this->template->content = View::forge('blog/index') ->set('results', $results); } public function action_insert() { $data = array( 'title' => 'aaa', 'body' => 'eee', 'date' => date('Y-m-d H:i:s'), 'sub' => array(1,2,3) ); Model_Blog::insertMongo($data); $this->response->redirect('/blog'); } }
そしてview
app/views/blog/index.php
<p>Index</p> <?php foreach($results as $post): ?> <br/> id: <?php echo $post['_id']; ?><br/> title: <?php echo $post['title']; ?><br/> body: <?php echo $post['body']; ?><br/> date: <?php echo $post['date']; ?><br/> sub: <?php var_dump($post['sub']); ?> <hr> <?php endforeach; ?>
これで、
/blog/insertにアクセスするとデータが保存されて、
/blogにアクセスすると保存データが見えます。subというカラムには配列データが保存されます。
#しかしなぜViewだけapp/classes/viewsじゃなくてapp/viewsにおくのだろうか。。。
明日は、@kenji_sさんの「FuelPHP での Migration の使い方」です!