Ground Sunlight

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

ユーザ用ツール

サイト用ツール


apricot:usage:ja:model

差分

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

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

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
apricot:usage:ja:model [2020/08/21 17:21]
y2sunlight
apricot:usage:ja:model [2020/09/03 13:45] (現在)
y2sunlight [Apricot モデルとサービス]
行 15: 行 15:
   * [[apricot:usage:ja:middleware|Apricot ミドルウェア]]   * [[apricot:usage:ja:middleware|Apricot ミドルウェア]]
   * [[apricot:usage:ja:controller|Apricot コントローラ]]   * [[apricot:usage:ja:controller|Apricot コントローラ]]
 +  * [[apricot:usage:ja:validation|Apricot バリデーション]]
   * [[apricot:usage:ja:provider|Apricot サービスプロバイダー]]   * [[apricot:usage:ja:provider|Apricot サービスプロバイダー]]
 +  * [[apricot:usage:ja:authentication|Apricot ユーザ認証]]
   * [[apricot:usage:ja:utility|Apricot ユーティリティ]]   * [[apricot:usage:ja:utility|Apricot ユーティリティ]]
  
行 22: 行 24:
 モデルはデータベース上のテーブルと1対1に対応したクラスで、データベースからデータを取得または設定するためのメソッドを持っています。モデルのベースクラスは[[https://github.com/j4mie/idiorm|Idiorm]]を使用して作成しています。 モデルはデータベース上のテーブルと1対1に対応したクラスで、データベースからデータを取得または設定するためのメソッドを持っています。モデルのベースクラスは[[https://github.com/j4mie/idiorm|Idiorm]]を使用して作成しています。
  
-Apricotは比較的小規模なアプリケーション開発をターゲットにしているので、コントローラとモデルによってアプリケーションの作成が可能であると仮定しています。しかし、2つ以上のモデルを操作するような少し複雑なトランザクションが必要な場合は、それをサービスとして実装する必要があるかもしれません。サービスに関しては実装に関する若干のヒントを示すに留めます。+Apricotは比較的小規模なアプリケーション開発をターゲットにしているので、コントローラとモデルによってアプリケーションの作成が可能であると仮定しています。しかしながら、2つ以上のモデルを操作するような少し複雑なトランザクションが必要な場合は、それをサービスとして実装する必要があるかもしれません。現状のApricotではサービスの実装アプリケーションの問題であるとする立場でなので、本章では、サービスの実装に関する若干のヒントを示すにだけに留めます。
  
 \\ \\
行 124: 行 126:
 </code> </code>
  
-新しいORMオブジェクトにはモデルのフィールドありません。モデルに初期値を設定するには以下のようにします。+上の例では、新しいORMオブジェクトにはモデルのフィールドありません。モデルに初期値を設定するには以下のようにします。
  
 <code php> <code php>
行 143: 行 145:
 === update() === === update() ===
  
-指定されたモデルデータでテーブルを更新します。このメソッドはORMオブジェクトを返します。レコードが存在しない時、''ApplicationException'' がスローされ、また、楽観的ロック例外を検知した時は、''OptimissticLockException'' がスローされます。これらの例外については [[apricot:usage:ja:errors-logging#アプリの例外クラス]] も参照して下さい。+指定されたモデルデータでテーブルを更新します。このメソッドはORMオブジェクトを返します。レコードが存在しない時、''ApplicationException'' がスローされ、また、楽観的ロック例外を検知した時は、''OptimissticLockException'' がスローされます。これらの例外については[[apricot:usage:ja:errors-logging#アプリの例外クラス]]も参照して下さい。
  
 <code php> <code php>
行 188: 行 190:
 以下はもっとも簡単なModelの継承の例です。Modelを継承するだけで、Modelクラスのメソッドが利用でき、簡単なモデルなら直ぐにアクションの実装に取り掛かれます。 以下はもっとも簡単なModelの継承の例です。Modelを継承するだけで、Modelクラスのメソッドが利用でき、簡単なモデルなら直ぐにアクションの実装に取り掛かれます。
  
 +{{fa>folder-open-o}} ** /your-project/app/Models **
 <code php User.php> <code php User.php>
 <?php <?php
行 252: 行 255:
 ===== サービス ===== ===== サービス =====
  
-==== DIコンテナ ====+Apricotではサービスの実装に関する具体的で明確な指針を提供してはいませんが、その代わりに1つの例題を提供しています。この例題は、''/your-project/app/Services'' に配置されています。この配置場所は規則ではありませんので、必要に応じて変更して下さい。
  
-ApricotではDIコンテナに [[https://github.com/thephpleague/container|League/Container]] を使用しています。 +{{fa>folder-open-o}} ** /your-project/app/Services ** 
- +<code php SampleServices.php>
-DIコンテナを使用することで、サービスとその依存関係を登録しておいて後で取得することができます。例えば、サービスAがモデルBとモデルCを使用しているような場合、サービスコンテナにサービスAを要求すると、自動的にモデルBとCを生成し、それらをサービスAのコンストラクタに与えてサービスAを生成してくれます。これがDIコンテナです。 +
- +
->ここでは、League/Container の慣例に従いDIコンテナと呼んでますが、サービスコンテナと呼んでも何の問題もありません。 +
- +
-\\ +
- +
-==== Providerクラス ==== +
- +
-サービスプロバイターは、アプリケーション内の全てのDIコンテナを登録し整理する方法を提供してくれます。また、サービスプロバイダーではサービスが取得された時点で遅延登録されるため、アプリケーションのパフォーマンス向上にも寄与します。 +
- +
-このサービスプロバイターを作るには、League/Container が提供している基本サービスプロバイダークラス( ''AbstractServiceProvider'' )を拡張して独自のサービスプロバイダーを作ります。Apricotでは、独自のサービスプロバイダーとして ''App\Provider'' クラスを定義しています。以下にApricotのスケルトンで初期実装されているProviderクラスを示します。 +
- +
-{{fa>folder-open-o}} ** /your-project/app ** +
-<code php Provider.php>+
 <?php <?php
-namespace App+namespace App\Services;
- +
-use League\Container\ServiceProvider\AbstractServiceProvider;+
  
 /** /**
- Provider class for service+ Sample Service
  */  */
-class Provider extends AbstractServiceProvider+class SampleService
 { {
     /**     /**
-     * The provided array is a way to let the container +     * The number of users 
-     * know that a service is provided by this service +     * @var int
-     * 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 +    private $count 0;
-        // Example +
-        'user', +
-    ];+
  
     /**     /**
-     This is where the magic happens, within the method you can +     Creates a sample service.
-     * 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()+    public function __construct(\App\Models\User $user)
     {     {
-        // Example +        $this->count count($user->findAll());
-        $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''が持っている [[https://www.php-fig.org/psr/psr-11/|PSR-11]] に準じた ''get()'' と ''has()'' を使ってサービスを利用することができます。 +
- +
-\\ +
- +
-==== Providerクラス ==== +
- +
-以下に、League/Container の 基本サービスプロバイダークラスAbstractServiceProvider )を拡張したApricot独自のサービスプロバイダークラス( Provider )を以下に示します。 +
- +
- +
- +
-\\ +
- +
-==== 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 $idFinds 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. +     Get the number of users
-     * +
-     * @return \Apricot\Foundation\Response+
      */      */
-    public function index(int $no=null)+    public function getUserCount()
     {     {
-        $title = "Stub {$no}"; +        return $this->count;
- +
-        /* +
-         * 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> </code>
  
-  * ''Container::get('user')'' でユザモデルを生成します。 +サービスの構造は[[apricot:usage:ja:controller#コントロラ]]に似ています。クラス間の依存性を疎にする為に、コンストラクタモデルや他オブジェクトを受ける場合、コンストラクタインジェクションが必要になるかもせん、サービスがコントローラ、ミドルウェア、テンプレートなどの様々な場所から呼び出される場合は、シングルンが要求されるかもせん
-  * ユモデルの ''findAll()'' を実行して全ユーザのリストを取しま +
-  * ユーザ数を表示するめに、テンプレート変数 ''$messages'' をセットしま+
  
 +これらの問題を解決する為に、Apricotのコアが使用している [[https://github.com/thephpleague/container|League/Container]] が利用できます。これはサービスに関する強力なツールになるはずです。
  
 +Apricotでは League/Container を利用した以下の機能が使用できます。
  
-Apricotではサービスに関する明確な指針を提供してはいませんが、Apricotのコアが使用している [[https://github.com/thephpleague/container|League/Container]] はサービスに関する強力なツールを提供するはずです。+=== Auto Wiring ===
  
 +Auto Wiring とは、コンストラクター引数の型ヒントを調べることにより、オブジェクトとそのすべての依存関係を再帰的に自動的に解決する機能です。これによってコントローラーにモデルやサービスのコンストラクタインジェクションが実現できます。詳しくは「[[apricot:usage:ja:controller#auto_wiring]]」を参照して下さい。
  
-これらのツルを利用してアリケション+=== サビスロバイダー ===
  
 +サービスプロバイダーを利用して、サービスをシングルトンとしてアプリケーションに登録することができます。詳しくは、「[[apricot:usage:ja:provider|League/Container]]」を参照して下さい。
  
 \\ \\
apricot/usage/ja/model.1597998117.txt.gz · 最終更新: 2020/08/21 17:21 by y2sunlight