ReadBeanPHPとは
公式を見ると
require 'rb.php';
R::setup();
R::setAutoResolve( TRUE ); //Recommended as of version 4.2
$post = R::dispense( 'post' );
$post->text = 'Hello World';
$id = R::store( $post ); //Create or Update
$post = R::load( 'post', $id ); //Retrieve
R::trash( $post ); //Delete
このようなサンプルがある通り、手軽に使えるライブラリを目指して開発されたもののようです
(何も設定しない場合は、/tmp/red.dbにSQLite形式で保存されるようです)
そんなに知名度が高いライブラリでは無いと思っていたのですが、Slim マイクロフレームワークで REST アプリケーションを作成するに取り上げられているので、手軽にサンプルを作るのに丁度いい、という扱いで使用されているのではないかと思います
ただ、残念ながら開発が終了したもののようで、ロードマップを見ると、2020年にサポートも終了するようで、今から使用するには微妙な感じです
特徴
チュートリアルを試してみると、だいたいどんなものかは分かるかと思います。
$object = R::dispense(テーブル名);
で生成されたオブジェクトのプロパティに、適当に値を設定しておくと、saveした時点で数値の場合はInteger、文字列の場合にはTextで型を設定したテーブルが作成されます。
このままだとスキーマが変わっていってしまうので、チュートリアルの最後に書いてあるように
R::freeze(true);
とすると、スキーマが変わらないように出来ます。
RDBというより、NoSQLのように使えるのが特徴かと思います。
Step 6: Playing with models
ここの説明にあるクラス名が違うので、ドキュメントが古いかもしれません
class Model_Note extends RedBean_SimpleModel {// RedBean_SimpleModel -> RedBeanPHP\SimpleModel public function update() {
if ( strlen( $this->bean->note ) < 4 )
die( "Note is too short!\n" );
}
}
使ってみる
チュートリアルの通りにダウンロードしてきてもいいですが、composerでもインストールできます
$ composer require gabordemooij/redbean
<?php
require __DIR__ . '/vendor/autoload.php';
use RedBeanPHP\R;
$frozen = false;
R::setup('mysql:host=localhost;dbname=test', 'root', 'password', $frozen);
$test = R::dispense('test');
$test->name = 'bar';
$id = R::store($test);// id, nameがあるtestテーブルが作成される
$test2 = R::load('test', $id);// 今セーブしたレコードを取得
$test2->created_at = date('Y-m-d H:i:s');
R::store($test2);// testテーブルに、created_atカラムが追加されている
注意点
Conventionsの項目にあるように
$page = R::dispense('page'); //valid
$page = R::dispense( 'Page' ); //invalid: uppercase
$page = R::dispense( 'cms_page' ); //invalid: _
$page = R::dispense( '@#!' ); //invalid
- テーブル名にアンダースコアや´を使えないようです。
- プライマリキーは「id」固定
トランザクション
職業柄か、複数のデータベースを扱う事が多い為、データベース関連を見るとまず最初に2相コミットが出来るか?を調べてみたりするのですが、
だいたいこんな感じで出来るようです
// コネクションラベル, DSN, db_user, password, is_freeze
// 最後のis_freezeは、スキーマを動的に変更するような場合にfalse 通常の使い方だとtrueを指定する
R::addDatabase('test1', 'mysql:host=localhost;dbname=test', 'root', null, true);
R::addDatabase('test2', 'mysql:host=localhost;dbname=test2', 'root', null, true);
try {
//使用するデータベースを指定してからトランザクション開始
R::selectDatabase('test1');
R::begin();
$obj1 = R::dispense('test1');
$obj1->name = 'tran test1';
R::store($obj1);
//2つ目のDB指定
R::selectDatabase('test2');
R::begin();
$obj2 = R::dispense('test2');
$obj2->name = 'tran test2';
R::store($obj2);
//2つ目のDBコミットしてから、1つ目のDBをコミットする
R::commit();
R::selectDatabase('test1');
R::commit();
} catch (Exception $e) {
R::selectDatabase('test2');
R::rollback();
R::selectDatabase('test1');
R::rollback();
}
テーブルにアクセスする前にデータベースを選択するのはある意味自然な流れなのですが、少々面倒ですね
ちなみに、トランザクションにクロージャを使えるので、次のようなコードでも出き・・・そうなのですが、これはライブラリのバグで、2つ目に指定したデータベースのトランザクションが開始しないので、ロールバック時におかしな事になります。
R::selectDatabase('test1');
R::transaction(function() {
$obj = R::dispense('test1');
$obj->name = 'tran test1';
R::store($obj);
R::selectDatabase('test2');
// R::transaction内で$depthをカウントしているが、staticで持っていてコネクションに紐づいていないので
// コネクションを複数使用する場合には、後からのstartTransactionが動作しない
R::transaction(function() {
$obj = R::dispense('test2');
$obj->name = 'tran test2';
R::store($obj);
});
});
感想
PHPのSlimフレームワークがシンプルで、ちょっとしたアプリケーションのサンプルを作るのに良さそう、と思ったので、
同じくシンプルなORMを探していたら、このようなライブラリを見つけたので少し調べてみました
ただ、先述した通り、開発終了して先が長く無さそうなところが残念なところです