LoginSignup
1
0

More than 5 years have passed since last update.

RedBeanPHPメモ

Posted at

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
test.php
<?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相コミットが出来るか?を調べてみたりするのですが、
だいたいこんな感じで出来るようです

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つ目に指定したデータベースのトランザクションが開始しないので、ロールバック時におかしな事になります。

2相コミット(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を探していたら、このようなライブラリを見つけたので少し調べてみました
ただ、先述した通り、開発終了して先が長く無さそうなところが残念なところです

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0