ある SCA コンポーネントが、別の SCA コンポーネントのサービスをコールすることができます。 コンポーネントが提供するサービスは、すべて public メソッドでできています。 SCA for PHP では現在、あるコンポーネントから他のコンポーネントをコールする方法を 二通り提供しています。ローカルに (同一の PHP ランタイム、 同一のコールスタック上で) コールする方法と、リモートにコールする方法です。 リモートにコールする場合は、コールされるコンポーネントが ウェブサービスを公開していなければなりません。
あるコンポーネントが別のコンポーネントをコールするには、 呼び出し元のコンポーネント側に呼び出し先コンポーネントへのプロキシが必要です。 このプロキシは、通常は呼び出し元コンポーネントのインスタンス変数として用意します。 しかし、後でご覧いただくように SCA::getService() でプロキシを取得することも可能です。 コンポーネントを作成する際にプロキシを作成し、 別のコンポーネントを参照するインスタンス変数にそのプロキシを "注入 (inject)" します。プロキシは、そのコンポーネントがローカルにあるかリモートにあるかにかかわらず 常に用いられます。これにより、リモートだろうがローカルだろうが同じ方法でコールできるようになります (たとえば、ローカルへのコールの際もデータは常に値渡しとなります)。 プロキシは、そのコンポーネントがある場所と、 それをコールする方法を知っています。
サービスのプロキシを保持することを意図したインスタンス変数は、 PHPDocumentor 形式のふたつのアノテーション @reference および @binding で表します。それぞれのアノテーションは、 クラスのインスタンス変数のコメント部で指定します。以下のコードを参照ください。
インスタンス変数の前にある @reference アノテーションは、 そのインスタンス変数がコンポーネントへのプロキシとして初期化されることを示します。
@binding アノテーションには二通りの形式 @binding.php および @@binding.soap があり、それぞれそのプロキシが ローカルコンポーネント用なのかウェブサービス用なのかを表します。 @binding.php および @binding.soap のいずれの場合も、 対象の URI をアノテーションで指定します。
現時点では依存性の指定をアノテーションで行っているので、 参照先を変更する唯一の方法はコンポーネント内のアノテーションを書き換えることになります。
今回の例の ConvertedStockQuote では、インスタンス変数 $exchange_rate をローカルのコンポーネント ExchangeRate へのプロキシとして初期化しています。これは、 ConvertedStockQuote のインスタンスが作成されるたびに作成されます。
例1 ローカルの PHP クラスへのプロキシの取得
<?php
/**
* 使用する為替レートサービス
*
* @reference
* @binding.php ../ExchangeRate/ExchangeRate.php
*/
public $exchange_rate;
?>
@binding.php の場合の URI は、 そのコンポーネントの実装を含むスクリプトの場所を表します。 コンポーネントはローカルにコールされます。 提供されるサービスは、コンポーネントの public メソッド群となります。 URI は、絶対パスあるいは相対パスで表す単純なパス名でなければなりません。 コンポーネントの読み込みには、PHP の include ディレクティブを使用します。 その際に、既に読み込まれていないかどうかを class_exists() で調べます。URI が相対パスの場合は、 そのアノテーションを含むコンポーネントの場所を基準としてパスを解決します。 これは、通常の PHP の振る舞いとは異なることに注意しましょう。 通常は、PHP は include_path を基準として解決します。 このようにしない理由は、複数コンポーネント間の参照関係を、 できるだけ場所の影響を受けないようにするためです。
この ExchangeRate サービスがリモートにあり、ウェブサービスとしてコールされるものだとすると、 変更するところは @binding の行だけです。PHP クラスの場所を指定するかわりに、 ウェブサービスについて記述した WSDL ファイルの場所を指定します。 今回のサンプルでは、二番目の参照でこの方式を説明しています。
例2 ウェブサービスへのプロキシの取得
<?php
/**
* 使用する株価サービス
*
* @reference
* @binding.soap ../StockQuote/StockQuote.wsdl
*/
public $stock_quote;
?>
StockQuote コンポーネントはウェブサービスへのリクエストとしてコールされます。 今回の場合は WSDL の URI が単純なパス名となっていますが、 PHP のラッパーを使用して、たとえば file:// や http:// で始めることもできます。 単純にパス指定する場合は絶対パスでも相対パスでもかまいません。 相対パスの場合は、そのアノテーションを含むコンポーネントの位置からの相対パスと解釈されます。 これは @binding.php の振る舞いと同様で、通常の PHP の挙動とは異なることに注意しましょう。 通常は、PHP は現在の作業ディレクトリからの相対パスとして探します。 作業ディレクトリは、通常はそのスクリプトがコールされた場所となります。 このようにしない理由は、複数コンポーネント間の参照関係を、 まずバインド形式の違いに影響を受けないようにすること、 そして場所の影響を受けないようにするためです。