Ground Sunlight

Windowsで作る - PHPプログラミングの開発環境

ユーザ用ツール

サイト用ツール


apricot:usage:ja:model

差分

このページの2つのバージョン間の差分を表示します。

この比較画面にリンクする

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
次のリビジョン 両方とも次のリビジョン
apricot:usage:ja:model [2020/08/03 11:46]
tanaka [ORMの設定]
apricot:usage:ja:model [2020/08/12 10:08]
y2sunlight
行 6: 行 6:
  --- //[[http://www.y2sunlight.com|y2sunlight]] 2020-07-29//  --- //[[http://www.y2sunlight.com|y2sunlight]] 2020-07-29//
  
-[[apricot:usage:ja|Apricotの使用法 に戻る]]+[[apricot:usage:ja|Apricot ドキュメント に戻る]]
  
 目次 目次
  
 +  * [[apricot:usage:ja:features|Apricot 特徴と概要]]
   * [[apricot:usage:ja:config|Apricot 配置と構成]]   * [[apricot:usage:ja:config|Apricot 配置と構成]]
 +  * [[apricot:usage:ja:errors-logging|Apricot ログとエラー処理]]
   * [[apricot:usage:ja:http|Apricot リクエストとレスポンス]]   * [[apricot:usage:ja:http|Apricot リクエストとレスポンス]]
   * [[apricot:usage:ja:frontend|Apricot フロントエンド]]   * [[apricot:usage:ja:frontend|Apricot フロントエンド]]
行 16: 行 18:
   * [[apricot:usage:ja:middleware|Apricot ミドルウェア]]   * [[apricot:usage:ja:middleware|Apricot ミドルウェア]]
   * [[apricot:usage:ja:controller|Apricot コントローラ]]   * [[apricot:usage:ja:controller|Apricot コントローラ]]
-  * [[apricot:usage:ja:errors-logging|Apricot ログとエラー処理]] 
   * [[apricot:usage:ja:utility|Apricot ユーティリティ]]   * [[apricot:usage:ja:utility|Apricot ユーティリティ]]
  
行 30: 行 31:
 <code php idiorm.setting.php> <code php idiorm.setting.php>
 <?php <?php
 +/**
 + * This file contains Idiorm settings.
 + */
 return return
 [ [
行 79: 行 83:
 <code php idiorm.setup.php> <code php idiorm.setup.php>
 <?php <?php
-//------------------------------------------------------------------- +/** 
-// ORM(idirom)の初期設定 + * Initial setting of ORM (idirom) 
-//-------------------------------------------------------------------+ */
 return function():bool return function():bool
 { {
-    // データベースファイルの準備+    // Prepares the database files
     $db_file = config('idiorm.sqlite.db_file');     $db_file = config('idiorm.sqlite.db_file');
     if (!file_exists($db_path=dirname($db_file)))     if (!file_exists($db_path=dirname($db_file)))
     {     {
-        mkdir($db_path,null,true);+        @mkdir($db_path, null, true);
     }     }
  
-    // DBファイルの存在確認+    // Checks if DB file exists
     $new_db_file = !file_exists($db_file);     $new_db_file = !file_exists($db_file);
  
-    // データベース接続+    // Connects to database
     ORM::configure([     ORM::configure([
         'connection_string' => config('idiorm.sqlite.connection_string'),         'connection_string' => config('idiorm.sqlite.connection_string'),
行 102: 行 106:
         {         {
             // SQL debug logging             // SQL debug logging
-            \Core\Log::info("SQL",[$log_string]);+            Apricot\Log::info("SQL",[$log_string]);
         },         },
     ]);     ]);
  
     //-------------------------------------------     //-------------------------------------------
-    // テーブルの作成 (新しくDBを作った時)+    // Creates tables when creating a new DB
     //-------------------------------------------     //-------------------------------------------
     if ($new_db_file)     if ($new_db_file)
行 122: 行 126:
  
     //-------------------------------------------     //-------------------------------------------
-    // 初期ユーザの作成 (ユーザテーブルが空の時)+    // Creates initial data when a table is empty
     //-------------------------------------------     //-------------------------------------------
     $initial_data = config('idiorm.initial_data');     $initial_data = config('idiorm.initial_data');
行 131: 行 135:
             if(ORM::for_table($key)->find_one()===false)             if(ORM::for_table($key)->find_one()===false)
             {             {
 +                // SQL execution
                 if (array_key_exists('exec', $item))                 if (array_key_exists('exec', $item))
                 {                 {
-                    // SQLの実行 
                     $exec = (array)$item['exec'];                     $exec = (array)$item['exec'];
                     foreach($exec as $sql)                     foreach($exec as $sql)
行 140: 行 144:
                     }                     }
                 }                 }
 +
 +                // Creates new records
                 if (array_key_exists('rows', $item))                 if (array_key_exists('rows', $item))
                 {                 {
-                    // 新しいレコードの作成 
                     $rows = (array)$item['rows'];                     $rows = (array)$item['rows'];
                     foreach($rows as $row)                     foreach($rows as $row)
行 156: 行 161:
     }     }
  
-    // SQLログ開始+    // Starts SQL log
     ORM::configure('logging' , config('idiorm.sqlite.logging',false));     ORM::configure('logging' , config('idiorm.sqlite.logging',false));
     return true; // Must return true on success     return true; // Must return true on success
行 174: 行 179:
  
 ===== データベースの構築 ===== ===== データベースの構築 =====
->TODO+ 
 +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は楽観的ロックで使用します
  
 \\ \\
  
 ===== モデル ===== ===== モデル =====
->TODO+ 
 +ORマッパーが使えるようになったので、モデルのベースクラス( Model )を作ります。Modelクラスは必ず継承して使い、以下のメソッドを持ちます。詳しくはソースコードを参照して下さい。 
 + 
 +^メソッド名^機能^ 
 +|tableName()\\ :string|テーブル名の取得\\ テーブル名(snake_case)はクラス名(UpperCamelCase)から自動判定します。| 
 +|for_table()\\ :ORM|ORMオブジェクトの取得| 
 +|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''が持っている [[https://www.php-fig.org/psr/psr-11/|PSR-11]] に準じた ''get()'' と ''has()'' を使ってサービスを利用することができます。
 +
 +\\
 +
 +==== Providerクラス ====
 +
 +以下に、League/Container の 基本サービスプロバイダークラス( AbstractServiceProvider )を拡張したApricot独自のサービスプロバイダークラス( Provider )を以下に示します。
 +
 +{{fa>folder-open-o}} ** /apricot/app **
 +<code php 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 );
 +     }
 +}
 +</code>
 +
 +このクラスは、名前空間Appの直下に存在し、アプリケーションのモデル及びサービスのマップを提供します。現版のApricotでは、モデルはユーザモデル( User )だけで、サービスについては存在しません。モデルやサービスを追加する場合は、上例に習って適宜追加して下さい。
 +
 +現版のApricotでは、サービスは存在しませんが、サービス用として以下のフォルダが予約されています。
 +
 +<code>
 +/apricot/app/Services
 +</code>
 +
 +尚、League/Container のサービスプロバイダーについての詳細は[[https://container.thephpleague.com/3.x/service-providers/|こちら]]をご覧ください。
 +
 +\\
 +
 +==== App\Foundation\Containerクラス ====
 +
 +App\Foundation\Containerクラスは、\League\Container\Container クラスを生成し、Apricotのサービスプロバイダー(Provider)を登録したクラスで、シングルトンとして動作します。
 +
 +使用法: ** Container::{メソッド} **
 +
 +^メソッド^機能^
 +|mixed get(string $id)|識別子idでコンテナのエントリを検索して返します。|
 +|bool has(string $id)|コンテナが指定された識別子idのエントリを返すことができる場合はtrueを返します。|
 +
 +{{fa>folder-open-o}} ** /apricot/app/Foundation **
 +<code php 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;
 +    }
 +}
 +</code>
 +
 +\\
 +
 +==== サービスコンテナの使用例 ====
 +
 +=== スタブコントローラ ===
 +
 +サービスコンテナをテストするために、スタブコントローラを以下のように修正します。
 +
 +{{fa>folder-open-o}} ** /apricot/app/Controllers **
 +<code php 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]);
 +    }
 +}
 +</code>
 +
 +  * ''Container::get('user')'' でユーザモデルを生成します。
 +  * ユーザモデルの ''findAll()'' を実行して全ユーザのリストを取得します。
 +  * ユーザ数を表示するために、テンプレート変数 ''$messages'' をセットします。
 +
 +\\
apricot/usage/ja/model.txt · 最終更新: 2020/09/03 13:45 by y2sunlight