Objective
A page where we can gather our thoughts (with a view to eventually building documentation) about how the PHP SCA programming model can be used within the context of the Tuscany C++ SCA runtime. The Tuscany C++ SCA runtime provides an extension API for integrating new languages. We will use this to integrate our current PHP SCA implementation.
The following is not a statement of fact but just what I have discovered so far in looking at the code. There are very likely to be bits missing and bits that I have got wrong.
Overview
The C++ SCA runtime is made of three main overlapping parts.

Currently the C++ runtime runs within a single process. The runtime is actually very small with all the real work being done by the model and the extensions. All of the component implementations (containers) are provided as extensions to the C++ SCA runtime, even the C++ container itself.
At startup, the runtime looks for extension implementations and registers them in the model so that when "implementation.xyz" is found in the SCDL the model can associate the component with the extension that knows how to run xyz type components.
It then scans a configured (through the environment) directory structure looking for composite files and loads them, building an in-memory model as it goes. In the process of doing this, wrappers and proxies are constructed based on the software provided by the extension that supports each component.
When the time comes to process an incoming message the chain of proxies and wrappers ensures that the correct sequence of components executes.
A simple Scenario
For demonstration purposes we are going to use a very simple scenario that allows us to described the implementation of a PHP component's services, references and properties. We will also consider how SCA can be used from within non-SCA PHP scripts.

How C++ SCA Works
Taking the runtime, model and extension API that we introduced in the overview, we can draw an intial sketch of how we expect PHP SCA components to fit into C++ SCA based on what has been done for Ruby and Python.

Disclaimer - This is my understanding at present and may be factually incorrect but it's my understanding at the moment.
At runtime C++ SCA builds a model of the composite that will run (the green boxes) from the SCDL files it finds. You will notice that this in-memory models accurately reflects the SCA SCDL concepts such as components, composites, services, references, wires and conponent types. The way that these artefacts are organized matches the organization of the composites and components in the SCDL file. For C++ components all of this information comes from SCDL files, as annotations are not supported. In our PHP extension we will augment this model information from the annotations found in the PHP service implementations.
Once the model is built, the runtime starts processing messages. Messages follow the flow dictated by the model and are enacted using appropriate proxy and wrapper classes (the orange boxes at the top) as dictated by the model.
As discussed previously the SCA runtime is very small and does all of its work by loading extensions. Before the model is loaded, the SCA runtime loads extension types (in yellow at the bottom right), for example the PHP extension. This in turn provides an interface to the PHP environment (PHPImplementation) and also provides PHP-specific extensions to the model (PHPServiceBinding and PHPReferenceBinding). These reflect the message processing required by these model extensions. PHP-specific wrappers and proxies are also provided by the extension (PHPServiceWrapper and PHPServiceProxy).
How PHP SCA Works
The current PHP SCA implementation has a different view of the world of course.

There are no SCDL files here. All of of the model information is provided in annotations to the PHP class acting as the service implementation. The SCA implementation is entirely userspace PHP, and relies on the SCA Runtime script running before the component implementation script (achieved by including the SCA runtime script at the begining of the component script). The SCA runtime parses the component's annotations and creates wrappers and proxies based on the service, reference, binding and type information that it finds. Once this is done it then processes any incoming messages before terminating. When the next message arrives at our PHP component, this SCA setup processing is performed again.
Hosting
We can consider either the PHP/SCA or the CPP/SCA implementation to be providing the hosting environment.
CPP SCA Hosting
Apache -> Axis -> C++ SCA Component -> PHPServiceWrapper -> PHP SCA Component -> TuscanyMediator ->
PHPServiceProxy
Control is starting with CPP so the PHP Extension is correctly set and we rely on providing the reference name to the Mediator
.
PHP SCA Hosting
A call through a component is as follows
Apache -> PHP -> PHP SCA Component -> TuscanyMediator ->
CPP SCA PHPServiceProxy
In this case the PHP SCA component must either
- match a component in the SCDL file in which
is identified by reference name - provide a Component/Service string as
and allow CPP/SCA to find this component in its loaded composite
Control is starting with PHP so the context of the PHP Extension has not been created by the PHPExtension service wrapper. We need to use the Component or Composite locateService() approach.
We will not consider this approach in the first instance.
Component Implementation Styles
There are several ways that a PHP script can implement a component method.
- A plain script
- A script function
- A member function in a PHP class
- An annotated PHP SCA service (again a member function in a PHP class)
Services
The implementation style require different calling mechanisms in the PHP Extension.
1 (plain script) requires that parameters are marshalled into a $_REQUEST and the result is retrieved from the PHP output buffer.
2 (script function) requires a simple function call with parameters marshalled appropriately
3 (member function) requires that a class be constructed and a member function called with parameters marshalled appropriately
4 (PHP SCA Service) requires that the SCA service be instantiated and the references initialized. Then the method can be invoked as in 3.
References
When a component wants to call a referenced component two mechanisms are open. Components implemented as types 1, 2 or 3 must locate a proxy before calling it.
$proxy = SCA::getService ( [?.php | ?.wsdl | ?.smd | "referencename"] )
In the initial implementation of the PHP Extension ?.php, ?.wsdl, ?.smd will have the effect of using PHP SCA bindings. Only when a reference name is used will the result call be directed back to CPP SCA.
Components of type 4 expect the reference proxy to be provided automatically.
/**
* @service
*/
class ServiceA {
/**
* @reference
*/
public $service_b;
* @param string $an_argument
* @return string
*/
function doSomething($an_argument) {
return $this->service_b->doSomethingElse($an_argument);
}
}
Properties
TBD
Bindings
The full range of bindings deployed in the the C++/SCA runtime should be active when configured PHP-based components are called or call references. As mentioned above, the SCA PHP implementation also supports a growing list of bindings. It is not proposed in the first instance to tie these bindings into the CPP/SCA implementation; if you employ one of these bindings, such as binding.ws, in your PHP SCA script, then the PHP Extension will not be involved.
The Calculator Sample
To test the various options we need to cover the following scenarios.
- A plain script
- Called as a service (4)
- Calling a reference (4)
- A property (4)
- A script function
- Called as a service (1)
- Calling a reference (2)
- A property (4)
- A member function in a PHP class
- Called as a service (1)
- Calling a reference (2)
- A property
- An annotated PHP SCA service (a PHP class function also)
- Called as a service (3)
- Calling a reference (3)
- A property (4)
- Local bindings
- Remote (WS) bindings
- PHP Script client
We adopt and extend the calculator scenario used by the Python and Ruby extensions. Here is how it will look:

The current PHP extension implementation only supports the options marked as (1) on the previous list. To move this along we are now concentrating on the options marked as (2). We will then move onto PHP SCA annotated services (3) etc.
Bring C++ and PHP SCA Together
A combined runtime will look something like the following.

Some points of interest.
- Messages passing out of PHP through references need to go via a native PHP extension (TuscanyMediator) in order to get back into C++. This needs to tie up with the proxies provided by the C++ SCA PHP extension code. This native extension will be intialized by the PHPServiceWrapper with infomation about valid references defined in the SCDL
- In the case where SDOs are being passed into the service we can use the TuscanyMediator to remove the need to marshall the SDO into a string for passing into PHP.
- SCA for PHP parses annotations before each call. We should pull this out so that the C++ PHP extension can call this function once and arrange for generic proxies to be generated on each call. Annotation information can be committed to the C++ SCA Model.
PHP Embedding SAPI
Running a PHP component implementation involves a number of steps.
- Set up references and properties
- Marshall arguments and make the call
- Handle and calls via the component out to local and remote references
- Retrive the result and shut down the request
The PHP model of execution is one-shot in as much as the request context is configured, the PHP script runs and the request context is removed again. As we are driving PHP through the embedding SAPI we have a lot of flexibility in how we initiate and interact with the component implementation. Due to the numerous interactions that will be required with the script it seems sensible to create an interface layer as a PHP extension that can be configured from C++ and accessed from PHP. In this way we can set up the request, pass in property and reference information and handle requests coming from the running PHP script all in one place.
PHPExtensionMediator
We can invoke PHP scripts from the embedding SAPI but when these scripts want to call out to references we need to transition back into C++. We provide a PHP native extension to support this. It allows:
- method calls on references
- model data exchange
- passing of SDOs on input (SDO support in PHP is based on a native implementation)
Written as a native PHP extension this provides the bridge between a running PHP SCA component and the CPP SCA runtime.
Model Data Exchange
In the calculator example we show PHP SCA annotated classes being used as component implementations. The PHP SCA programming model has no SCDL files currently and the annotations in these files provide componentType and compositional information for the component. You will note in the calculator sample that no componentType or interface description files are provided for PHP SCA annotation-based components. There is a slight problem with the example though. We do provide a calculator composite file which duplicates the information provided in the PHP SCA annotations. We could consider that this composite file is either generated based on the annotations or that the composite file augments or overrides the annotations.
Annotation Overriding
This is a degenerate case of the PHP SCA model and is close to how C++ SCA works now. For example, consider the calculator.php file with all of the composite information removed leaving just the component type information.
calculator.php
=============
<?php
include 'SCA/SCA.php';
/**
* @service
*/
class Calculator {
/**
* @reference
*/
public $add_service;
/**
* @reference
*/
public $sub_service;
/**
* @reference
*/
public $mul_service;
/**
* @reference
*/
public $div_service;
/**
* Addition
*
* @param float $num1 (the first number)
* @param float $num2 (the second number)
* @return float The result
*/
function add($num1, $num2) {
return $this->mul_service->add($num1, $num2);
}
/**
* Subtraction
*
* @param float $num1 (the first number)
* @param float $num2 (the second number)
* @return float The result
*/
function sub($num1, $num2) {
return $this->mul_service->sub($num1, $num2);
}
/**
* Multiplication
*
* @param float $num1 (the first number)
* @param float $num2 (the second number)
* @return float The result
*/
function mul($num1, $num2) {
return $this->mul_service->mul($num1, $num2);
}
/**
* Division
*
* @param float $num1 (the first number)
* @param float $num2 (the second number)
* @return float The result
*/
function div($num1, $num2) {
return $this->div_service->div($num1, $num2);
}
}
?>
We can imagine here that the C++ SCA runtime provides the appropriate wiring information based on the composite file.
Composite Generation
In this case we expect to take the information from the PHP annotations and create the composite information in the C++ SCA model. The problem here is how to bootstrap the process. How does C++ SCA know which PHP files to use in the first place? This information would normally come from a composite file. Maybe we can go with some form of cut-down composite file to provide this information.
sample.calculator.composite
===========================
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
name="sample.calculator">
<component name="CalculatorComponent">
<implementation.php module="Calculator" scope="composite"/>
</component>
</composite>
and rely on the annotations for everything else. A better solution maybe to allow the C++ SCA runtime to search for any PHP components in the context of the top-level application composite, load them up and wire them in according to the annotations. Need some input from the C++ SCA team here.
Annotation Augmentation
This case is less clear but could be a combination of the two cases above.
Questions and Issues
- What should we do about bindings that SCA for PHP already supports? Should these be turned off when running in the C++ SCA runtime?
- Should we allow an optimization where PHP to PHP bindings are allowed to remain. Not in the first case I would have thought but possibly interesting in the future.
- Should service description generation also be turned off or can we make use of it? Would be nice to have the composite call the php component to get the WSDL file. PHP side already does this.
- How do we distinguish between a PHP file and a PHP file with a function in it? Need to look at the SAPI options a little more closely
- How do we get SDOs into a script? Need the mediator to do the work for us.
- The SDO for PHP extension has an embedded copy of the Tuscany C++ SDO library, which may be different to the one loaded by the Tuscany C++ SCA runtime. We need some version compatibility check.