メインメニュー
XAMPP アレンジ
IED
WSL2
-
道具箱
リポジトリ編
フレームワーク編
公開ソフトウェア
メタ
リンク
- PHP ライブラリ
- PHP 言語
apricot:usage:ja:model文書の過去の版を表示しています。
編集中
Apricot データベースとモデル
ORMの設定
Apricotでは、ORマッパーにIdiormを使用します。詳しい使い方やメソッドについてはIdiormのマニュアルを参照して下さい。
Idiormの典型的な使用例を示します:
$user = ORM::for_table('user')->find_many();
これは、userテーブルから全件を検索する例です。このように、IdiormではORMクラスの静的メソッドの呼び出しを使ってコーディングします。これはApricotのシングルトンと同じ方法で、実際にORMクラスもシングルトンです。
Idiormの設定ファイル
以下はApricotが提供している初期のIdiormの設定ファイル(
idiorm.setting.php
)です。/your-project/config/setting
- idiorm.setting.php
<?php /** * This file contains Idiorm settings. */ return [ 'sqlite' => [ 'db_file' => var_dir('db/apricot.sqlite'), 'connection_string' => 'sqlite:'.var_dir('db/apricot.sqlite'), 'caching' => true, 'logging' => true, ], 'initial_data' => [ 'user'=> [ 'exec' =>[ 'delete from sqlite_sequence where name=\'user\'', ], 'rows' => [ [ 'account' =>'root', 'password' =>password_hash('', PASSWORD_DEFAULT), 'email' =>'root@sample.com', 'note' =>'Initial User', ], ], ], ], ];
sqlite
は、Apricotのスケルトンで使用しているSQLite用の接続設定です。- sqlite.db_file — データベースファイルのパス (初期設定値は var/db/apricot.sqlite)
- sqlite.connection_string — 接続文字列
- sqlite.caching — キャッシングの有無
- sqlite.logging — ロギングの有無
sqlite.db_file は
- initial_data : 初期データ (テーブルが空の時に自動設定されます)
- {テーブル名} — ここではユーザテーブル( user )を指定しています
- exec — 実行したいSQLを記述します(複数指定可)
- rows — 行データを設定します(複数指定可)
接続設定の詳細は以下を参照して下さい:
https://idiorm.readthedocs.io/en/latest/configuration.html#id1
初期設定ファイル
データベースの設定は初期設定ファイルで行います。
/apricot/config/setup
- idiorm.setup.php
<?php /** * Initial setting of ORM (idirom) */ return function():bool { // Prepares the database files $db_file = config('idiorm.sqlite.db_file'); if (!file_exists($db_path=dirname($db_file))) { @mkdir($db_path, null, true); } // Checks if DB file exists $new_db_file = !file_exists($db_file); // Connects to database ORM::configure([ 'connection_string' => config('idiorm.sqlite.connection_string'), 'caching' => config('idiorm.sqlite.caching',false), 'logging' => false, 'logger' => function($log_string, $query_time) { // SQL debug logging Apricot\Log::info("SQL",[$log_string]); }, ]); //------------------------------------------- // Creates tables when creating a new DB //------------------------------------------- if ($new_db_file) { $sql_text = file_get_sql(assets_dir('sql/create.sql')); if (!empty($sql_text)) { foreach($sql_text as $sql) { ORM::get_db()->exec($sql); } } } //------------------------------------------- // Creates initial data when a table is empty //------------------------------------------- $initial_data = config('idiorm.initial_data'); if (isset($initial_data)) { foreach($initial_data as $key=>$item) { if(ORM::for_table($key)->find_one()===false) { // SQL execution if (array_key_exists('exec', $item)) { $exec = (array)$item['exec']; foreach($exec as $sql) { ORM::get_db()->exec($sql); } } // Creates new records if (array_key_exists('rows', $item)) { $rows = (array)$item['rows']; foreach($rows as $row) { $row = ORM::for_table($key)->create($row); $row->set_expr('created_at', "datetime('now')"); $row->set_expr('updated_at', "datetime('now')"); $row->save(); } } } } } // Starts SQL log ORM::configure('logging' , config('idiorm.sqlite.logging',false)); return true; // Must return true on success };
初期設定ファイルでは以下の事をおこないます:
- データベースの保存フォルダが存在しない場合は作成します
- データベースへの接続
- テーブルの作成 (新しくDBを作った時)
- 初期ユーザの作成 (ユーザテーブルが空の時)
- SQLログの開始 (logging設定がtrueの場合)
データベースの構築
Apricotでは以下のユーザテーブルを持っています。
テーブル名 : user
カラム名 型 主Key 属性 説明 id integer ● autoincrement ID account text unique not null アカウント password text not null パスワード email text not null Eメールアドレス note text 備考 remember_token text 自動ログイン用 created_at text not null 作成日 updated_at text not null 更新日 version_no integer default 0 not null バージョンNo - ユーザ認証は(account,password)で行います
- remember_tokenは自動ログイン用の認証トークンです
- version_noは楽観的ロックで使用します
モデル
ORマッパーが使えるようになったので、モデルのベースクラス( Model )を作ります。Modelクラスは必ず継承して使い、以下のメソッドを持ちます。詳しくはソースコードを参照して下さい。
メソッド名 機能 tableName()
:stringテーブル名の取得
テーブル名(snake_case)はクラス名(UpperCamelCase)から自動判定します。for_table()
:ORMORMオブジェクトの取得 findAll()
:array全件検索
ORMの配列を返します。findOne
(int $id):mixed主キー検索
見つかった場合は ORM を、それ以外は false を返します。create
(array $inputs=null):ORMモデルの新規作成 insert
(array $inputs):ORMレコードの挿入 update
($id, array $inputs):ORMレコードの更新
レコードが存在しない時、ApplicationExceptionが発生します。
楽観的ロック例外を検知した時、OptimissticLockExceptionが発生します。delete
($id):ORMレコードの削除
レコードが存在しない時、ApplicationExceptionが発生します。isSuccess()
:bool最新の更新結果を取得します(insert/update/delete)
サービスプロバイター
サービスコンテナを使用することで、サービスとサービス間の依存関係を登録しておいて後で取得することができます。例えば、サービスAがモデルBとモデルCを使用しているような場合、サービスコンテナにサービスAを要求すると、自動的にモデルBとCを生成し、それらをサービスAのコンストラクタに与えてサービスAを生成してくれます。
サービスプロバイターは、アプリケーション内の全てのサービスコンテナを登録し整理する方法を提供してくれます。また、サービスプロバイダーではサービスが取得された時点で遅延登録されるため、アプリケーションのパフォーマンス向上にも寄与します。
League/Container でサービスプロバイダーを構築するには以下のステップに従います。
- League/Container の 基本サービスプロバイダークラス(
AbstractServiceProvider
)を拡張して 独自のサービスプロバイダーを作ります。 - League/Container の
Container
クラスに 独自のサービスプロバイダーを登録します。
Apricotでは、独自のサービスプロバイダーとして
App\Provider
クラスを定義し、それを登録するApp\Foundation\Container
クラスをシングルトンとして実装します。サービスの使用者は、App\Foundation\Container
が持っている PSR-11 に準じたget()
とhas()
を使ってサービスを利用することができます。
Providerクラス
以下に、League/Container の 基本サービスプロバイダークラス( AbstractServiceProvider )を拡張したApricot独自のサービスプロバイダークラス( Provider )を以下に示します。
/apricot/app
- Provider.php
<?php namespace App; use League\Container\ServiceProvider\AbstractServiceProvider; /** * Provider class for service */ class Provider extends AbstractServiceProvider { /** * The provided array is a way to let the container * know that a service is provided by this service * provider. Every service that is registered via * this service provider must have an alias added * to this array or it will be ignored. * * @var array */ protected $provides = [ // Example 'user', ]; /** * This is where the magic happens, within the method you can * access the container and register or retrieve anything * that you need to, but remember, every alias registered * within this method must be declared in the `$provides` array. */ public function register() { // Example $this->getContainer()->add('user', \App\Models\User::class ); } }
このクラスは、名前空間Appの直下に存在し、アプリケーションのモデル及びサービスのマップを提供します。現版のApricotでは、モデルはユーザモデル( User )だけで、サービスについては存在しません。モデルやサービスを追加する場合は、上例に習って適宜追加して下さい。
現版のApricotでは、サービスは存在しませんが、サービス用として以下のフォルダが予約されています。
/apricot/app/Services
尚、League/Container のサービスプロバイダーについての詳細はこちらをご覧ください。
App\Foundation\Containerクラス
App\Foundation\Containerクラスは、\League\Container\Container クラスを生成し、Apricotのサービスプロバイダー(Provider)を登録したクラスで、シングルトンとして動作します。
使用法: Container::{メソッド}
メソッド 機能 mixed get(string $id) 識別子idでコンテナのエントリを検索して返します。 bool has(string $id) コンテナが指定された識別子idのエントリを返すことができる場合はtrueを返します。 /apricot/app/Foundation
- Container.php
<?php namespace App\Foundation; use Apricot\Foundation\Singleton; use App\Provider; /** * Container class for service * * @method static Container getInstance() Gets the Container instance. * @method static mixed get(string $id) Finds an entry of the container by its identifier and returns it. * @method static bool has(string $id) Returns true if the container can return an entry for the given identifier. */ class Container extends Singleton { /** * Create Container instance. * @return \League\Container\Container */ protected static function createInstance() { $container = new \League\Container\Container; $container->addServiceProvider(new Provider()); return $container; } }
サービスコンテナの使用例
スタブコントローラ
サービスコンテナをテストするために、スタブコントローラを以下のように修正します。
/apricot/app/Controllers
- StubController.php
<?php namespace App\Controllers; use App\Foundation\Container; use App\Foundation\Controller; /** * Stub Controller */ class StubController extends Controller { /** * Index Page for this controller. * * @return \Apricot\Foundation\Response */ public function index(int $no=null) { $title = "Stub {$no}"; /* * Example for Container * @var \App\Models\User $user */ $user = Container::get('user'); $userCount = count($user->findAll()); $messages[] = "Number of registered users : {$userCount}"; return render('stub',['title'=>$title,'messages'=>$messages]); } }
Container::get('user')
でユーザモデルを生成します。- ユーザモデルの
findAll()
を実行して全ユーザのリストを取得します。 - ユーザ数を表示するために、テンプレート変数
$messages
をセットします。
apricot/usage/ja/model.1597802036.txt.gz · 最終更新: 2020/08/19 10:53 by y2sunlight
コメント