Dashboard > PHP Community > ... > SCA with PHP > PHP and SCA White Paper
Log In   View a printable version of the current page.
PHP and SCA White Paper
Added by Simon Laws, last edited by Simon Laws on Oct 06, 2006
Labels: 
(None)


Service Component Architecture for PHP

Like SDO for PHP, this is the first time the SCA technology has been mapped to a weakly and dynamically typed scripting language. The design and implementation must therefore focus very heavily on ensuring a natural fit with the unique requirements of that environment.

The initial scope of SCA for PHP is to provide a means for a PHP programmer to write reusable components, which can be called either locally, or remotely via Web services, with an identical interface and with a minimum of fuss.

Developing a Web service is made simple by automatically generating WSDL as needed from annotations within the component script. These annotations are a natural extension to those provided by phpDocumentor. Deploying a Web service is like deploying any other script.

To help illustrate this, lets consider the AccountService from the SCA BigBank scenario. In this scenario an AccountService is exposed as a Web service with a single operation called, "getAccountReport". This operation takes a customer id as input, and returns a set of account summaries (account name, type and balance). To develop this Web service in SCA for PHP, the developer specifies two things; the XML schema describing the data structures, and an annotated class for the service implementation.

The XML schema for the BigBank AccountService is relatively simple and is as follows:

<xsd:schema
	targetNamespace="http://www.bigbank.com/AccountService/"
	xmlns:acc="http://www.bigbank.com/AccountService/"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="customerID" type="xsd:string" />
  <xsd:element name="getAcountReportResponse" type="tns:AccountReport" />

  <xsd:complexType name="AccountReport">
    <xsd:sequence>
      <xsd:element name="accountSummaries" type="acc:tAccountSummary" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="AccountSummary">
    <xsd:sequence>
      <xsd:element name="accountNumber" type="xsd:string"/>
      <xsd:element name="accountType" type="xsd:string"/>
      <xsd:element name="balance" type="xsd:float"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

The example below shows how the shell of the service implementation might look.

/**
 * @service
 * @binding.ws
 * @types http://www.bigbank.com/AccountService AccountService.xsd
 *
 */
class AccountService {

	/**
	 * Returns an account report (a set of account summaries) for a given customer.
	 *
	 * @param string $customerID
	 * @return AccountReport http://www.bigbank.com/AccountService
	 *
	 */
	function getAccountReport($customerID) {
		...
	}

}

We can see from the code above that the implementation is based around an annotated PHP class. Some of the annotations are standard phpDocumentor tags (e.g. @param), but others are specific to SCA.  These are:

  • @service - identifies this class as a service component.
  • @binding.ws - states that the component is to be exposed as a Web service.
  • @types - identifies namespace and location information for data structures used by this service component.

Notice how the @return annotation has some additional information. In addition to the type name, the annotation also contains a namespace (from the XML schema). In the future, class definitions and @package/subpackage annotations for specifying the complex types may also be supported.

The combination of the class definition and these annotations give SCA all it requires to be able to generate a WSDL definition and expose the component as a Web service.

Components can also use annotations to declare dependencies on other components or Web services.  SCA resolves these dependencies at runtime on behalf of the components, and thus allows the programmer to focus on the component logic rather than the 'plumbing'.

Again, let's use the BigBank scenario to illustrate this.  The AccountService makes use of a StockQuote service in order to provide an up to date balance for stock accounts.  SCA uses the annotations approach to declare this dependency as follows:

/**
 * ...
 */
class AccountService {

    /**
     * @reference
     * @binding.ws StockQuoteService.wsdl
     */
    public $stockService;

        ...
        function getAccountReport($customerID) {
            $price = $stockService->getQuote("NYX");
            ...
        }
        ...
}

The above code declares a property of the AccountService to be a reference to a another service (the @reference annotation) and that the reference will target a Web service described by StockQuoteService.wsdl (the @binding.ws annotation).  At runtime, SCA will 'inject' a proxy into the property, $stockService, which will allow the AccountService code to call the Web service.  We can see this in the snippet of code in the getAccountReport method.  The code simply uses the Web service without having to first create a proxy.

References are not limited to just Web services.  Components (classes) can also declare dependencies on other local components using an annotation of the form, @binding.php component_script_name.  In this case, the component name is actually the class name in the target script.  For example, in the BigBank scenario, the AccountService makes use of a local AccountDataServiceComponent.  We could implement this component as a PHP class called AccountDataServiceComponent and then reference it from the AccountService as, "@binding.php AccountDataServiceComponent.php".

Next steps

A prototype implementation of the above capabilities is now available for download. We expect the design and implementation to evolve as a result of feedback gathered via the prototype and community activity. Support for additional bindings, such as REST services, will be added in the coming months.

Support for loose-coupling will be added by allowing references to be externally overridden.  The approach outlined above lays much of the ground-work for this by the use of declarative references and proxy 'injection'.  This combination means that external configuration could be used to specify a different target and inject a proxy to that new target.  The component implementation would be unaware of this change.

Resources

The prototype implementation, documentation and samples are available for download at the SOA PHP pages. There is a phpsoa Google Group to discuss problems, requirements and provide feedback.

Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.4.5 Build:#708 Apr 12, 2007) - Bug/feature request - Contact Administrators