このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン 次のリビジョン 両方とも次のリビジョン | ||
apricot:usage:ja:model [2020/08/21 17:21] y2sunlight |
apricot:usage:ja:model [2020/08/21 19:29] y2sunlight [サービス] |
||
---|---|---|---|
行 22: | 行 22: | ||
モデルはデータベース上のテーブルと1対1に対応したクラスで、データベースからデータを取得または設定するためのメソッドを持っています。モデルのベースクラスは[[https:// | モデルはデータベース上のテーブルと1対1に対応したクラスで、データベースからデータを取得または設定するためのメソッドを持っています。モデルのベースクラスは[[https:// | ||
- | Apricotは比較的小規模なアプリケーション開発をターゲットにしているので、コントローラとモデルによってアプリケーションの作成が可能であると仮定しています。しかし、2つ以上のモデルを操作するような少し複雑なトランザクションが必要な場合は、それをサービスとして実装する必要があるかもしれません。サービスに関しては実装に関する若干のヒントを示すに留めます。 | + | Apricotは比較的小規模なアプリケーション開発をターゲットにしているので、コントローラとモデルによってアプリケーションの作成が可能であると仮定しています。しかしながら、2つ以上のモデルを操作するような少し複雑なトランザクションが必要な場合は、それをサービスとして実装する必要があるかもしれません。現状のApricotではサービスの実装はアプリケーションの問題であるとする立場でなので、本章では、サービスの実装に関する若干のヒントを示すにだけに留めます。 |
\\ | \\ | ||
行 124: | 行 124: | ||
</ | </ | ||
- | 新しいORMオブジェクトにはモデルのフィールドがありません。モデルに初期値を設定するには以下のようにします。 | + | 上の例では、新しいORMオブジェクトにはモデルのフィールドはありません。モデルに初期値を設定するには以下のようにします。 |
<code php> | <code php> | ||
行 143: | 行 143: | ||
=== update() === | === update() === | ||
- | 指定されたモデルデータでテーブルを更新します。このメソッドはORMオブジェクトを返します。レコードが存在しない時、'' | + | 指定されたモデルデータでテーブルを更新します。このメソッドはORMオブジェクトを返します。レコードが存在しない時、'' |
<code php> | <code php> | ||
行 188: | 行 188: | ||
以下はもっとも簡単なModelの継承の例です。Modelを継承するだけで、Modelクラスのメソッドが利用でき、簡単なモデルなら直ぐにアクションの実装に取り掛かれます。 | 以下はもっとも簡単なModelの継承の例です。Modelを継承するだけで、Modelクラスのメソッドが利用でき、簡単なモデルなら直ぐにアクションの実装に取り掛かれます。 | ||
+ | {{fa> | ||
<code php User.php> | <code php User.php> | ||
<?php | <?php | ||
行 252: | 行 253: | ||
===== サービス ===== | ===== サービス ===== | ||
- | ==== DIコンテナ ==== | + | Apricotではサービスの実装に関する具体的で明確な指針を提供してはいませんが、その代わりに1つの例題を提供しています。この例題は、''/ |
- | ApricotではDIコンテナに [[https:// | + | {{fa> |
- | + | <code php SampleServices.php> | |
- | DIコンテナを使用することで、サービスとその依存関係を登録しておいて後で取得することができます。例えば、サービスAがモデルBとモデルCを使用しているような場合、サービスコンテナにサービスAを要求すると、自動的にモデルBとCを生成し、それらをサービスAのコンストラクタに与えてサービスAを生成してくれます。これがDIコンテナです。 | + | |
- | + | ||
- | > | + | |
- | + | ||
- | \\ | + | |
- | + | ||
- | ==== Providerクラス ==== | + | |
- | + | ||
- | サービスプロバイターは、アプリケーション内の全てのDIコンテナを登録し整理する方法を提供してくれます。また、サービスプロバイダーではサービスが取得された時点で遅延登録されるため、アプリケーションのパフォーマンス向上にも寄与します。 | + | |
- | + | ||
- | このサービスプロバイターを作るには、League/ | + | |
- | + | ||
- | {{fa> | + | |
- | <code php Provider.php> | + | |
<?php | <?php | ||
- | namespace App; | + | namespace App\Services; |
- | + | ||
- | use League\Container\ServiceProvider\AbstractServiceProvider; | + | |
/** | /** | ||
- | | + | |
*/ | */ | ||
- | 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 | + | |
*/ | */ | ||
- | | + | |
- | // Example | + | |
- | ' | + | |
- | ]; | + | |
/** | /** | ||
- | | + | |
- | * 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 | + | |
{ | { | ||
- | | + | $this->count = count($user->findAll()); |
- | | + | |
- | } | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | このクラスは、名前空間Appの直下に存在し、アプリケーションのモデル及びサービスのマップを提供します。現版のApricotでは、モデルはユーザモデル( User )だけで、サービスについては存在しません。モデルやサービスを追加する場合は、上例に習って適宜追加して下さい。 | + | |
- | + | ||
- | 現版のApricotでは、サービスは存在しませんが、サービス用として以下のフォルダが予約されています。 | + | |
- | + | ||
- | < | + | |
- | / | + | |
- | </ | + | |
- | + | ||
- | 尚、League/ | + | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | 、それを登録する '' | + | |
- | + | ||
- | \\ | + | |
- | + | ||
- | ==== Providerクラス ==== | + | |
- | + | ||
- | 以下に、League/ | + | |
- | + | ||
- | + | ||
- | + | ||
- | \\ | + | |
- | + | ||
- | ==== App\Foundation\Containerクラス ==== | + | |
- | + | ||
- | App\Foundation\Containerクラスは、\League\Container\Container クラスを生成し、Apricotのサービスプロバイダー(Provider)を登録したクラスで、シングルトンとして動作します。 | + | |
- | + | ||
- | 使用法: ** Container:: | + | |
- | + | ||
- | ^メソッド^機能^ | + | |
- | |mixed get(string | + | |
- | |bool has(string $id)|コンテナが指定された識別子idのエントリを返すことができる場合はtrueを返します。| | + | |
- | + | ||
- | {{fa> | + | |
- | <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-> | + | |
- | return $container; | + | |
} | } | ||
- | } | ||
- | </ | ||
- | \\ | ||
- | |||
- | ==== サービスコンテナの使用例 ==== | ||
- | |||
- | === スタブコントローラ === | ||
- | |||
- | サービスコンテナをテストするために、スタブコントローラを以下のように修正します。 | ||
- | |||
- | {{fa> | ||
- | <code php StubController.php> | ||
- | <?php | ||
- | namespace App\Controllers; | ||
- | |||
- | use App\Foundation\Container; | ||
- | use App\Foundation\Controller; | ||
- | |||
- | /** | ||
- | * Stub Controller | ||
- | */ | ||
- | class StubController extends Controller | ||
- | { | ||
/** | /** | ||
- | | + | |
- | * | + | |
- | * @return \Apricot\Foundation\Response | + | |
*/ | */ | ||
- | public function | + | public function |
{ | { | ||
- | $title = "Stub {$no}"; | + | |
- | + | ||
- | /* | + | |
- | * Example for Container | + | |
- | * @var \App\Models\User $user | + | |
- | */ | + | |
- | $user = Container:: | + | |
- | $userCount = count($user->findAll()); | + | |
- | $messages[] = " | + | |
- | + | ||
- | return render(' | + | |
} | } | ||
} | } | ||
</ | </ | ||
- | * '' | + | サービスの構造は[[apricot:usage:ja: |
- | * ユーザモデルの | + | |
- | * ユーザ数を表示するために、テンプレート変数 '' | + | |
+ | これらの問題を解決する為に、Apricotのコアが使用している [[https:// | ||
+ | Apricotでは League/ | ||
- | Apricotではサービスに関する明確な指針を提供してはいませんが、Apricotのコアが使用している [[https:// | + | === Auto Wiring === |
+ | Auto Wiring とは、コンストラクター引数の型ヒントを調べることにより、オブジェクトとそのすべての依存関係を再帰的に自動的に解決する機能です。これによってコントローラーにモデルやサービスのコンストラクタインジェクションが実現できます。詳しくは「[[apricot: | ||
- | これらのツールを利用してアプリケーション | + | === サービスプロバイダー === |
+ | サービスプロバイダーを利用して、サービスをシングルトンとしてアプリケーションに登録することができます。詳しくは、「[[apricot: | ||
\\ | \\ |