Obtaining a proxy for another Service Component
One SCA component can call the service provided by another SCA
component. The service a component provides is made up of all of its
public methods. SCA for PHP currently provides two ways for one
component to call another: either locally (i.e. within the same PHP
run-time, and on the same call stack) or remotely if the called
component exposes a Web service binding.
In order for one component to call another, the calling
component needs a proxy for the called component. This proxy is
usually provided as an instance variable in the calling component,
though proxies can also be obtained with the SCA::getService()
call, as we shall see later. When a component is constructed,
proxies are constructed for any instance variable which refer to
another component, and these proxies are "injected" into the
instance variables. Proxies are always used, whether the
component is local or remote, in order to provide identical calling
behavior between remote and local calls (for example, local calls
are made to always pass data by-value). The proxies know how to
locate the required component and to pass the calls made on to them.
Instance variables which are intended to hold proxies for
services are indicated by the two PHPDocumentor-style
annotations, @reference and @binding. Both annotations are
placed in the documentation section for a class instance variable,
as shown by the code below.
The @reference annotation before an instance variable
indicates that that instance variable is to be initialized with a
proxy to a component.
The @binding annotation has two forms @binding.php and
@binding.soap, and indicates that the proxy is either for a local
component or for a Web service respectively. For both @binding.php
and @binding.soap, the annotation gives a target URI.
At the moment, with the annotation-based method of
specifying dependencies, the only way to alter the intended target
of a reference is to alter the annotation within the component.
In our ConvertedStockQuote example, the
$exchange_rate instance variable will be
initialized with a proxy to the local ExchangeRate component
whenever an instance of the ConvertedStockQuote is constructed.
Example #1 Obtaining a proxy for a local PHP class
<?php
/**
* The currency exchange rate service to use.
*
* @reference
* @binding.php ../ExchangeRate/ExchangeRate.php
*/
public $exchange_rate;
?>
For @binding.php, the URI identifies the location of the
script containing the implementation of the component. The
component will be called locally. The service provided is the set of
public methods of the component. The URI must be a simple pathname,
either absolute or relative. The component will be loaded with the
PHP include directive, after testing to see if it is already loaded
with
class_exists(). If the URI is a relative
path, it is resolved relative to the component containing the
annotation. Note that this is different from the normal PHP
behaviour where scripts would be looked for along the PHP
include_path, This is intended to provide some
location-independence for cross-component references.
If this ExchangeRate service were remote and to be called as a
Web service, only the @binding line changes. Instead of giving the
location of a PHP class, it gives the location of the WSDL describing
the web service. In our example component, this is illustrated by
the second reference:
Example #2 Obtaining a proxy for a web service
<?php
/**
* The stock quote service to use.
*
* @reference
* @binding.soap ../StockQuote/StockQuote.wsdl
*/
public $stock_quote;
?>
The StockQuote component will be called via a Web service
request. In this case the URI for the WSDL can be a simple pathname, or
may contain a PHP wrapper and begin, for example, with
file:// or
http://. In the event that it is a simple
pathname, it can be absolute or relative, and if relative will be
resolved relative to the component containing the annotation.
Note that this is like the behaviour for @binding.php, and
different from the normal PHP behaviour where the file would be
looked for relative to the PHP current working directory, which
would usually be the location of the first script to be called. This
behaviour is intended to give consistency across the different
bindings and to provide some location-independence for
references between components.