RedBeanPHP-CodeFirst PHPフレームワーク

Redbeanphp

この投稿では、非常に興味深いORMフレームワークRedBeanPHPについて説明します。 データベース構造をその場で作成できることが主な特徴です。 さらに、このフレームワークは2ペニーとして簡単に使用できます。 私の物語は3つのパートに分かれます。

第二部では、主なテーマはモデルです。 第三に-フレームワークのロジックの変更。



投稿を書く前に、私は一生懸命働いて、15,000エントリのテストアプリケーションを作成しました。 結局のところ、特に開発の初期段階で、この作品の無意味さをひどく認識していくつかの場所でフィールドを処方するのはおそらく私だけではないでしょう。 最後に、.NETのEntity Framework Code Firstに類似したものが登場しました。 順番に。



起源



この奇跡は、同様に素晴らしい名前ガボールを持つ男によって書かれました。 ガボールは、認知心理学を学んだ失敗した学生です。 失敗は、これらの専門家に対する平凡な需要不足のために発生しましたが、ガボールは非常に優れた心理学者であることを認める準備ができています。 フレームワークを使用する場合、何が起こっているのかが単純で明白な感覚が私を離れません。



開始する



接続するには、すべてのコードを含む1つのファイルのみを追加する必要があります。



require('rb.php');
      
      





とても簡単ですね。 内部を見てみましょう。データファイルの重量は260 KBであり、多くのファイルから組み立てられたフレームワークのバージョンであることがわかります。 GitHubでは、約40個のファイルの通常バージョンをダウンロードできます。 この場合、接続するには次のコードが必要です。



 require('redbean.inc.php');
      
      





構造



このフレームワークには、適切に構成されたクラス構造があります。 構造には、PDOおよびOracle用のドライバーが含まれます。 これは、RedBeanPHPが幅広いデータベースをサポートすることを意味します。 ドキュメントには、MySQL 5、SQLite、PostgreSQL、CUBRID、Oracleのデータベースのサポートが記載されています。 後者のサポートはrb.phpには含まれていません。GitHubから個別にダウンロードする必要があります。 ただし、RedBean_Driverクラスを継承する独自のドライバーを作成することを誰も気にしません。

また、フレームワークの内部ロジックを変更するには、独自のバージョンのQueryWriterを作成する必要があります。 このトピックについては、レビューの第3部で詳しく説明します。

フレームワークはプラグインをサポートし、すべてのデータベースフレームワークリクエストを画面に表示するためのシンプルなLoggerクラスを持っています。 ファイル内にエントリが見つかりませんでしたが、自分のクラスを継承しても問題はありません。

提供されるロガーのコードは次のとおりです。



 class RedBean_Logger_Default implements RedBean_Logger { public function log() { if (func_num_args() > 0) { foreach (func_get_args() as $argument) { if (is_array($argument)) echo print_r($argument,true); else echo $argument; echo "<br>\n"; } } } }
      
      





すべてのファイルは、PHPDocsを使用して十分に文書化されています。 IDEのツールチップは、テーブルの列に関連付けられたオブジェクトのフィールドを除き、正常に機能します。



使用する



接続するには、PDO形式の文字列を指定する必要があります。



 R::setup('mysql:host=localhost;dbname=mydatabase', 'user','password'); //mysql R::setup('pgsql:host=localhost;dbname=mydatabase', 'user','password'); //postgresql R::setup('sqlite:/tmp/dbfile.txt', 'user','password'); //sqlite
      
      





新しいレコードと新しいテーブルが存在しない場合の作成例(流動モードのみ):



 //   (bean)    book $book = R::dispense( 'book' ); //   ,          $book->title = 'Gifted Programmers'; $book->author = 'Charles Xavier'; $book->price = 99.99; //,   id   $id = R::store($book);
      
      





そして、既存の「bean」がロードされます。



 $book = R::load('book', $id);
      
      





著者は、データを含むBeanオブジェクト(bin-インゲンマメ植物)を呼び出します。 このオブジェクトはモデルではなく、単にデータを保存し、データベース内のレコードを操作することを目的としています。 ビジネスロジックを含むモデルをそれらに接続する方法レビューの後半で説明します。



オブジェクトのidフィールドの存在によるフレームワークは、レコードの作成または更新を決定します。 このロジックを変更する方法については、第3部で説明します。



Beanは、WHERE句を指定して検索されます。



 $needles = R::find('needle', ' haystack = :haystack ORDER BY :sortorder', array( ':sortorder'=>$sortorder, ':haystack'=>$haystack ) );
      
      





同じ場所の2番目のパラメーターで、ORDER BYおよびLIMIT構文を指定できます。



コミュニケーションズ



リレーショナルデータベースの操作は、テーブル間のリレーションシップの存在を意味します。 RedBeanPHPは、必要なすべてのタイプのリンクをサポートしています。 1対多の関係を作成するために、独自のプレフィックスを持つプロパティを使用します。



 //  bean    village $village = R::dispense('village'); //  bean'    building list($mill,$tavern) = R::dispense('building',2); //      bean     own $village->ownBuilding = array($mill,$tavern); R::store($village);
      
      





構築テーブルがデータベースに作成されます。 village_idフィールドは、村のテーブルのidフィールドを指す建物テーブルに追加されます。 親テーブルへのリンクも作成され、必要なインデックスが作成されます。 リンクには、カスケードデータの更新と削除のプロパティがあります。



接続の反対側を見ると、次の方法で親オブジェクトにアクセスできます。



 $village = $mill->village
      
      





RedBeanPHPは、「遅延読み込み」の概念をサポートしています。 つまり、オブジェクトのフィールドにアクセスするときに関連データのロードが発生します。



 //    building   $village = R::load('village',$id); //    building $buildings = $village->ownBuilding;
      
      





自分のフィールドは連想配列なので、別のオブジェクトを置き換えることができます。



 $village->ownBuilding[$id] = $house;
      
      





オブジェクト間の接続を削除するには、次のコードを呼び出す必要があります(オブジェクト自体は削除されません)。



 unset($village->ownBuilding[$someID]); R::store($village);
      
      





Beanとそれに関連する親オブジェクトを削除するには:



 R::trash( $book ); //     R::trashAll( $books );
      
      





テーブルをクリアするには:



 R::wipe( 'book' );
      
      





多対多の関係を作成するには、共有プレフィックスを持つプロパティを使用します。



 $army = R::dispense('army'); $village->sharedArmy[] = $army; $village2->sharedArmy[] = $army;
      
      





その結果、追加のarmy_villageテーブルが作成され、リンクとインデックスが作成されます。 それ以外の場合、共有リストの操作は独自のリストに似ています。



通常、Beanタイプはオブジェクトフィールドの名前で示されます。



 // $village   village $village = $building->village
      
      





ただし、この規則に従わないオブジェクトのフィールドにBeanを割り当てる必要がある場合があります。



 list($teacher,$student) = R::dispense('person',2); $project->student = $student; $project->teacher = $teacher;
      
      





保存するとき、フレームワークはdispenceで指定されたBeanタイプによってガイドされ、両方の子オブジェクトがpersonテーブルに保存され、student_idおよびteacher_idフィールドがプロジェクトテーブルに作成されます。

この場合、フレームワークは$ project-> studentおよび$ project-> teacherフィールドのタイプを判別できないため、データベースからBeanをフェッチするときにあいまいな状況が発生する可能性があります。 この場合、タイプはfetchAsを呼び出すことで示されます。



 $teacher = $project->fetchAs('person')->teacher;
      
      





木々


フレームワークは、1対多、多対多の循環リンクをサポートします。

たとえば、カテゴリツリーの作成:



 //$subbean  $bean   category $subbean = R::dispense('category'); $subbean->title = $title; $subbean->url = $url; $subbean->parent = $bean; R::store($subbean);
      
      





parent_idフィールドと必要な関係とインデックスがテーブルに作成されます。



性能



Frameforkには、流動モードと凍結モードの2つの操作モードがあります。 流動モードでは、RedBeanPHPはテーブル自体の構造を処理し、パフォーマンスを犠牲にします。 開発が完了したら、フレームワークをフリーズモードから移動することで生産性を向上できます。



 R::freeze( true );
      
      





データベースリクエスト



ORMはSQLクエリをサポートしています。



 R::exec( 'update page set title="test" where id=1' );
      
      





クエリビルダーもあります。



 R::$f->begin() ->select('*')->from('bean') ->where(' field1 = ? ')->put('a')->get('row');
      
      







モデルの概要



後半では少し実行し、RedBeanPHPでモデルがどのように作成されるかを説明します。



最初は、モデルを使用せずにBeanを操作します。 モデルが必要な場合、Model_UserなどのModel_BeanName型のクラスを作成し、そこで追加のロジックを記述します。 Beanとモデルのバインドは自動です。



 $user = R::dispence('user'); $user->modelMethod();
      
      





つまり、ActiveRecordから始め、必要に応じてモデルに展開します。 著者はこのアプローチをFUSEと呼んでいます。



第二部では、日々の仕事のためのフレームワークの機能に関する議論を続けます。



3番目のパートでは、RedBeanPHPの追加機能について説明します。





資源



公式サイトRedBeanPHP



All Articles