From 949123ba94947b55ccc5504d1f6007875429e09b Mon Sep 17 00:00:00 2001 From: Matthew Peters Date: Tue, 16 Jan 2007 13:45:53 +0000 Subject: [PATCH] First check in of Service Component Architecture (SCA) documentation git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@227387 c90b9560-bf6c-de11-be94-00142212c4b1 --- reference/sca/backup.xml | 1344 +++++++++++++++ reference/sca/constants.xml | 29 + .../SCA-LocalProxy-createDataObject.xml | 170 ++ .../SCA-SoapProxy-createDataObject.xml | 171 ++ .../sca/functions/SCA-createDataObject.xml | 167 ++ reference/sca/functions/SCA-getService.xml | 148 ++ reference/sca/reference.xml | 1513 +++++++++++++++++ reference/sca/reference_1.xml | 132 ++ 8 files changed, 3674 insertions(+) create mode 100644 reference/sca/backup.xml create mode 100644 reference/sca/constants.xml create mode 100644 reference/sca/functions/SCA-LocalProxy-createDataObject.xml create mode 100644 reference/sca/functions/SCA-SoapProxy-createDataObject.xml create mode 100644 reference/sca/functions/SCA-createDataObject.xml create mode 100644 reference/sca/functions/SCA-getService.xml create mode 100644 reference/sca/reference.xml create mode 100644 reference/sca/reference_1.xml diff --git a/reference/sca/backup.xml b/reference/sca/backup.xml new file mode 100644 index 0000000000..a4f435eb70 --- /dev/null +++ b/reference/sca/backup.xml @@ -0,0 +1,1344 @@ + + + + + + + SCA Functions + SCA + + +
+ &reftitle.intro; + + SCA for PHP makes it possible for a PHP programmer to write + reusable components, which can be called in a variety of ways, with an + identical interface and with a minimum of fuss. At present + components can call each other either locally or via Web services, + but in the future it is expected that other ways will be possible. It + provides the programmer with a way of doing this which will look as + natural as possible in PHP. + + + + SCA components use phpDocumentor-style (see + http://www.phpdoc.org/) annotations to declare dependencies on + other SCA components or Web services. The SCA for PHP runtime + resolves these dependencies at runtime on behalf of the components, + and thus allows the PHP programmer to focus on the business logic + rather than on locating and obtaining references to dependencies. + + + + The SCA for PHP programming model can be extended to support a + number of service types, such as REST and Atompub, however, Web + services (more accurately, WSDL defined, SOAP/HTTP services), are + the only type currently specified. + + + + Components also use annotations to define the interface which + they expose as a service. The SCA for PHP runtime will automatically + generate WSDL from these annotations, so that an SCA component is + easily exposed as a web service. These annotations are a natural + extension to those provided by phpDocumentor. Deploying a Web + service can be as simple as placing a PHP component under the document + root of a web server. + + + Components also use annotations to specify data structures + (expressed using XML schema complex types) which are then handled + using Service Data Objects (SDOs). + + A PHP script which is not an SCA component and which contains no + annotations can use the services of an SCA component. A PHP script or + component can make calls to a web service that is not an SCA component, + but using the same system of annotations to obtain a reference. + +
+ +
+ &reftitle.required; + If you want to use SCA to consume or produce Web services then you + need PHP 5.2.0 or later, built with the soap extension enabled. If you + just want to use local components, and do not wish to use the Web + service bindings, then this version of SCA for PHP will also run with + PHP 5.1.6. +
+ +
+ &reftitle.install; + SCA is packaged along with SDO in one combined package on PECL. + See http://www.php.net/sdo#sdo.installation for installing the + SCA_SDO package from PECL. The SCA code must be on the include path of + your PHP installation, for example if it is installed as + /usr/local/lib/php/SCA, the include_path directive must include + /usr/local/lib/php +
+ +
+ &reftitle.examples; + The examples in the subsequent sections illustrate the + following aspects of PHP for SCA: + + + + How PHP annotations are used to define PHP classes as SCA + components, and how annotations are used to define the + services. + + + How an SCA component can be exposed as a Web service + + + How an SCA component can consume a Web service, whether + provided by another SCA component or by some other service which + knows nothing of SCA + + + How an SCA component can call another SCA component locally + (within the same process and on the same call stack) + + + How a client script which is not an SCA component can use the + getService call to obtain a reference to an SCA component. + + + How data structures such as Addresses, or Puchase Orders, + are represented as Service Data Objects, and handled. + + + How SCA components are deployed, and in particular how and + when WSDL is generated for a service. + + + How parameters are always passed by value (and not by + reference) between components, even when the calls are local. + This ensures that the semantics of a call do not change depending on + the location of a component. + + + How positional parameters to a service are supported, even + when the underlying WSDL is document literal wrapped, and + naturally supports only named parameters. + + + How business and runtime exceptions are handled. + + + + + First we show a single SCA component, "ConvertedStockQuote" + which illustrates many of the features of SCA for PHP. It has one + method, "getQuote()", which given a stock "ticker" obtains a price + quote for that stock, converted to a given currency. We shall be using + this example as a basis for explaining the SCA for PHP throughout the + rest of this document. + + + + A sample SCA component + + stock_quote->getQuote($ticker); + $rate = $this->exchange_rate->getRate($currency); + return $rate * $quote; + } +} +?> +]]> + + + + + In this example, we see that an SCA component is implemented by a + script containing a PHP class and includes SCA.php. The class + contains a mixture of business logic and references to other + components or services. In the illustrated getQuote() method there + is only business logic, but it relies on the instance variables + $stock_quote and $exchange_rate having been initialized. These + are references to two other components and will be initialized by the + SCA runtime whenever this component executes. The annotations for + these two services show one to be a local component, which will be + called within the same PHP runtime, and one to be a remote component + which will be called via a SOAP request. This component also exposes + the getQuote() method both locally and as a web service, so it in turn + can be called either locally or remotely. + +
+ The structure of a Service Component + A service component is implemented by a class. To identify it + as a service component, it contains an @service annotation. The SCA + runtime will use the file name of the script to determine the + component name, by convention. The class and script file must + therefore share the same name. + + PHP SCA components always expose a service, and there is no way + for a component to be invoked other than to be called as a result of a + Web service request, or called directly from another component or + from a script. For this reason a valid PHP SCA component will always + contain an @service annotation and at least one public method. + + + Each SCA Component requires that the SCA.php script is + included. As well as containing the definition of the SCA class, + this script contains executable PHP code that will run whenever the + script is called, and which will be responsible for making the + component behave as needed. + + + + It is very important that if your file contains other + includes, they come before the include for SCA.php. If there are + includes after the include for SCA.php, they will not have been + processed when the SCA runtime runs your class. + + + The example below illustrates this overall structure + + + + + The structure of an SCA for PHP component + + + +]]> + + + +
+ +
+ Obtaining a reference to 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 reference to the called component. This + reference is usually an instance variable in the calling + component, though references 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 is a reference 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 references to + 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.ws, and indicates that the reference is either to a local + component or to a Web service respectively. For both @binding.php + and @binding.ws, the annotation identifies the instance variable + as a reference to another component and 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. + + + + Illustrating a reference to a local PHP class + + + +]]> + + + + + 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: + + + + Illustrating a reference to a web service + + +]]> + + + + + 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 cross-component references. + +
+ +
+ + Calling another Service Component + + The ConvertedStockQuote example also calls the two + components to which it has acquired references. + + + + Calling services + + +]]> + + + + + The call to the StockQuote service is a call to a local service; + the call to the ExchangeRate service is a call to a remote service. + Note that the way the call is made looks the same regardless of + whether the call is to a local service or a remote one. + The proxies which have been injected ensure that the way calls + to components look and behave are the same way regardless of whether + they are to a local or remote service, so that components are not + sensitive to whether a call is to a local or a remote service. For + example, the proxy for a local service takes copies of the arguments + and passes only those copies, to ensure that calls are made to be + pass-by-value, as they would be for a remote call. Also, the proxy + for a remote service takes the arguments from a positional + parameter list and ensures they are packaged properly in a SOAP + request and converted back to a positional parameter list at the far + end. + + In the example above, the $ticker and $currency are clearly + PHP scalar types. Components can pass the PHP scalar types string, + integer, float and boolean, but data structures on service calls + are always passed as Service Data Objects (SDOs); A later section + describes how a component can create an SDO to pass on a local or Web + service call, or how a component can create an SDO to return. The PHP + SDO project documentation describes how to work with the SDO APIs + (see http://www.php.net/sdo). + +
+ +
+ + Locating and calling services from a script which is not an + SCA Component + Within a component, components obtain references to other + components or services as instance variables annotated with + @reference, but this is not possible for a script that is not itself + also a component. A client script which is not a component must use + the SCA::getService static method to obtain a reference to a + service, either local or remote. The getService method takes a URI + as the argument. Typically this is the location of a local PHP script + containing a component, or of a wsdl file, and is used in exactly the + same way as the targets of the @binding annotations described in the + previous section; that is relative URIs are resolved against the + location of the client script and not against the PHP include_path + or current working directory. + + For example, a script that needed to obtain references to the + ExchangeRate and StockQuote services but was not a component would + use the getService method as follows: + + + + Obtaining a proxy using getService + + +]]> + + + + + Methods on services can then be called on the returned object, + just as they can in a component. + + + Making calls on the proxy + + getQuote($ticker); +$rate = $exchange_rate->getRate($currency); +?> +]]> + + + + +
+ +
+ Exposing a Service Component as a Web service + + SCA for PHP can generate WSDL from the annotations within a + service component, so that it can be easily deployed and exposed as a + Web service, and called either from another SCA component, or from a + client program that knows nothing of SCA. To provide SCA with the + information it needs to generate the WSDL, it is necessary to add the + annotation @binding.ws under the @service annotation and to + specify the parameters and return values of the methods using the + @param and @return annotations. These annotations will be read + when WSDL is generated, and the order and types of the parameters + determine the contents of the <schema> section of the WSDL. + + + SCA for PHP always generates document/literal wrapped WSDL + for components that are exposing a Web service. However, + components can consume Web services documented with WSDL written + in a different style. + + The scalar types which can be used in the @param annotation are + the four common PHP scalar types: boolean, integer, float and + string. These are simply mapped to the XML schema types of the same + name in the WSDL. The example below, which is a trivial + implementation of the StockQuote service that the + ConvertedStockQuote component calls, illustrates string and + float types. + + + + StockQuote Service + + +]]> + + + + + WSDL much like the following (though with a service location + other than 'localhost', probably) would be generated from this + service: + + + + Generated WSDL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + +
+ +
+ + Deploying an SCA component + There are no special steps needed to deploy a PHP SCA + component. It is sufficient to place the component PHP script in its + proper place under the web server document root, just like any other + PHP script. It is the SCA::initComponent() executable line within + each component that will be executed whenever the script is called, + and which will be responsible for making the component respond + appropriately to Web service calls, local calls, or requests for + WSDL. + +
+ +
+ + Obtaining the WSDL for an SCA component offering a Service as + a Web service + + SCA components that expose a Web service interface (i.e. have + an @binding.ws annotation) will return their WSDL definition in + response to an HTTP request with a get parameter of "wsdl". The usual + way to obtain this is with "?wsdl" on the end of a URL. The example + below uses file_get_contents to obtain WSDL from a service and + writes it to a temporary file before then obtaining a reference to + the service in the usual way, although you might choose to obtain the + WSDL in a browser, or by some other means, and save the file yourself. + + + + + Generated WSDL + + +]]> + + + + + + NOTE: If the wsdl requires imported xsds, these will need to be + fetched separately. + +
+ +
+ Understanding how the WSDL is generated + SCA for PHP generates WSDL for components which contain an + @binding.ws annotation after the @service annotation (do not + confuse this with the @binding.ws annotation after an @reference, + which refers to a dependency, not to exposing an interface). To + generate WSDL, the SCA runtime reflects on the component and + examines the @param and @return annotations for each public + method, as well as any @types annotations within the component. + + + These annotations are used to generate document/literal + wrapped WSDL to expose this component as a Web service. SCA for PHP + always generates document/literal wrapped WSDL for components + that are exposing a Web service; however, components can consume + Web services documented with WSDL written in a different style. + + +
+ Location attribute of the <service> element + + At the bottom of the WSDL is the <service> element + which uses the location attribute to identify the URL of the + service. For example this might look as follows: + + + + location attribute + + +]]> + + + + + Note that this location is relative to the document root of + the web server, and cannot be worked out in advance. It can only be + worked out once the component is in its proper place under a running + web server, when the hostname and port can be known and placed in the + WSDL. Detail from the URL that requests the WSDL is used, so for + example if the WSDL is generated in response to a request to + http://www.example.com:1111/ConvertedStockQuote/ConvertedStockQuote.php?wsdl, + a location of + http://www.example.com:1111/ConvertedStockQuote/ConvertedStockQuote.php + is what will be inserted into the location attribute in the WSDL. + +
+ +
+ Document/literal wrapped WSDL and positional + parameters + SCA for PHP generates WSDL in the document/literal wrapped + style. This style encloses the parameters and return types of a + method in 'wrappers' which are named after the corresponding + method. The <types> element at the top of the WSDL defines + each of these wrappers. If we consider the getQuote method of the + ConvertedStockQuote example: + + + + method with two arguments + + stock_quote->getQuote($ticker); + $rate = $this->exchange_rate->getRate($currency); + return $rate * $quote; + } +?> +]]> + + + + + + The WSDL generated to define this method will name both the + method and the parameters, and give an XML schema type for the + parameters. The types section of the WSDL looks like this: + + + + types section illustrating named parameters + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + The SCA run-time has special processing to handle how + positional parameter lists in the interface are converted to XML + containing named parameters in the soap request, and then back to + positional parameter lists again. To see why this matters, + consider how a PHP script which used a different interface to make a + SOAP call would need to construct the parameter list. A PHP script + using the PHP SoapClient, for example, would need to pass the + SoapClient a single parameter giving the values for "ticker" and + "currency", perhaps as an associative array. To insist that SCA + components construct parameter lists to make Web service calls in + this way would be to make local and remote calls look different, so a + different approach is needed. + + When SCA generates WSDL for an SCA component it includes a + comment in the WSDL which marks that WSDL as being the interface for + an SCA component. In this case, when one SCA component calls + another through a Web service, the SCA runtime on the calling end + takes the positional parameter list from the call and assigns the + values one by one to the named elements in the soap message. For + example a call to the getQuote() method defined above that passes + the values 'IBM' and 'USD' and looks like this: + + + + getQuote('IBM','USD'); + ]]> + + + + will result in a soap message containing the + following: + + + + + IBM + USD + + ]]> + + + + On the service-providing end, the SCA run-time takes the + parameters one by one from the soap message and forms a positional + parameter list from them, re-forming the argument list + ('IBM','USD') + + + + At both ends the SCA runtime relies on the order in which the + parameters appear in the soap message being the same as that in the + target method's parameter list. This is ultimately determined + by the order of the @param annotations: this determines the order + in which the parameters appear in the WSDL and thereby the order in + which they appear in the soap message. Therefore it is essential + that the order of the @param annotations matches that of the + parameters in the method's parameter list. + + +
+ +
+ +
+ Working with Data Structures + SCA components can pass and return the four PHP scalar types + boolean, integer, real and string, but to pass or return data + structures, SCA components use Service Data Objects (SDOs). + Readers familiar with SDOs will know that they are suitable for + representing the sort of structured and semi-structured data that + is frequently modeled in XML, and that they serialize very + naturally for passing between remote components, or in Web + services. SDOs are the only supported way to pass and return data + structures. It is not possible to pass or return any other sort of PHP + object, or PHP arrays. + + The SCA runtime always assures data is passed by-value, even + for local calls, so the SCA runtime copies any SDOs in the parameter + list before passing them on, just as it does for scalar types. + + +
+ How data structures are defined to SCA components + Currently the only mechanism for specifying the location of + a data structure definition is by specifying the types in an XML + schema file. However, in the future it may be possible to define + types in other ways, such as based on PHP classes or interfaces, or + based on definitions expressed as associative arrays. + + To illustrate the use of SDOs we introduce a new component. + The PortfolioMangement service below returns an SDO + representing a stock portfolio for a given customer. + + + + A Component that uses Data Structures + + createDataObject('holding'); + $holding->ticker = 'AAPL'; + $holding->number = 100.5; + $holding = $portfolio->createDataObject('holding'); + $holding->ticker = 'INTL'; + $holding->number = 100.5; + $holding = $portfolio->createDataObject('holding'); + $holding->ticker = 'IBM'; + $holding->number = 100.5; + return $portfolio; + } + +} +?> +]]> + + + + + + The @types annotation: + + + + +]]> + + + + indicates that types in the namespace + http://www.example.org/Portfolio will be found in the schema + file located by the URI PortfolioTypes.xsd. The generated WSDL + would reproduce this information with an import statement as + follows: + + + + +]]> + + + + so the URI, absolute or relative, must be one that can be + resolved when included in the schemaLocation attribute. + +
+ +
+ Creating SDOs + Readers familiar with SDOs will know that they are always + created according to a description of the permitted structure + (sometimes referred to as the 'schema' or 'model') and that, + rather than creating them directly using 'new', some form of data + factory is needed. Often, an existing data object can be used as the + data factory, but sometimes,and especially in order to get the + first data object, a different data factory is needed. + + In SCA, either the SCA runtime class or the proxies for + services, whether local or remote, can act as the data factories + for SDOs. The choice of which to use, when, is described in the next + two sections. + We switch to a new example in order to illustrate the creation + of SDOs both the pass to a service, and to be returned from a service. + +
+ +
+ Creating an SDO to pass to a service + A caller of a service which requires a data structure to be + passed in to it uses the proxy to the service as the data factory for + the corresponding SDOs. For example, suppose a component makes + use of a reference to a service provided by a local AddressBook + component. + + + + +]]> + + + + The AddressBook component that it wishes to call is defined + as follows: + + + +]]> + + + + + The AddressBook component provides a service method called + lookupAddress() which uses types from the http://addressbook + namespace. The lookupAddress method takes a personType data + structure and returns an addressType. Both types are defined in + the schema file AddressBook.xsd. + + Once the component that wishes to use the AddressBook + component has been constructed, and the $address_book instance + variable initialized, the calling component can use the + initialized proxy in $address_book to create the person SDO, as + shown below + + + + createDataObject('http://addressbook','personType'); +$william_shakespeare ->name="William Shakespeare"; +$address = $address_book->lookupAddress($william_shakespeare); +?> +]]> + + + + + Note, the use of the proxy as the means to create the SDO is not + limited to SCA Components. If a service is being called from a + general PHP script, and the reference was obtained with + getService() then the same approach is used. + + + + createDataObject('http://addressbook','personType'); +?> +]]> + + + + +
+
+ Creating an SDO to return from a component + A component that needs to create a data object for return to a + caller uses the createDataObject static method on SCA.php. The + component can only create SDOs which conform to a data structure + that is defined in an @types annotation. Hence if the AddressBook + component described above needed to create an object of type + addressType within the namespace personNS, it might do so as + follows: + + + + +]]> + + + + +
+ +
+ +
+ Error handling + This section describes how errors are handled. There are two + types of errors: + + + SCA runtime exceptions are those that signal problems in + the management of the execution of components, and in the + interaction with remote services. These might occur due to + network or configuration problems. + + + + Business exceptions are those that are defined by the + programmer. They extend the PHP Exception class, and are thrown + and caught deliberately as part of the business logic. + + + + +
+ Handling of Runtime exceptions + There are two types of SCA runtime exception: + + + + SCA_RuntimeException - signals a problem found by or + perhaps occurring within the SCA runtime. This can be thrown for + a variety of reasons, many of which can occur regardless of + whether a connection is being made to a local or a remote service: + an error in one of the annotations within a component, a missing + WSDL or php file, and so on. In the case of Web services, an + SCA_RuntimeException can also be thrown if a SoapFault is + received from a remote Web service and the fault code in the + SoapFault indicates that a retry is unlikely to be successful. + + + + + SCA_ServiceUnavailableException - this is a subclass of + SCA_RuntimeException and signals a problem in connecting to or + using a remote service, but one which might succeed if retried. + In the case of Web services, this exception is thrown if a + SoapFault is received with a fault code that indicates that a + retry might be successful. + + + +
+
+ Handling of Business exceptions + Business exceptions may be defined and thrown by a component + in the normal way, regardless of whether the component has been + called locally or remotely. The SCA runtime does not catch + business exceptions that have been thrown by a component called + locally, so they will be returned to a caller in the normal way. If a + component has been called via a Web service, on the other hand, the + SCA runtime on the service providing end does catch business + exceptions, and will ensure these are passed back to the calling + end and re-thrown. Assuming that the calling end has a definition + of the exception (that is, is able to include a file containing the + PHP class defining the exception) the re-thrown exception will + contain the same details as the original, so that the getLine() and + getFile() methods for example will contain the location where the + exception was thrown within the business logic. The exception + will be passed in the detail field of a soap fault with a fault code of + "Client". +
+ +
+ +
+ + +
+ &reftitle.classes; + Most of the interface to SCA is through the annotations within + SCA components so there are few public classes and methods. The only + SCA classes that scripts or components can call are the SCA class + itself, and the proxy classes SCA_LocalProxy and SCA_SoapProxy. + + +
+ + + <classname>SCA</classname> + + Much of the work of the SCA class is performed when the file + SCA.php is included within an SCA component. However, a PHP script + may call include SCA.php and call the getService() method on the SCA + class in order to obtain a proxy for a service. A component will not + need to do this as proxies are obtained instead by defining an + instance variable with the @reference annotation. + Components that need to create an SDO to return to a caller will + need a data factory to call. For this purpose the SCA class supports + the createDataObject method, which will create an SDO according to + the model defined by the components' @types annotations. The + arguments to the createDataObject are the same as those to SDO's XML + Data Access Service. + +
&reftitle.methods; + + + + + getService - obtain a proxy for a service + + + + + createDataObject - create an SDO + + +
+
+ +
+ + <classname>SCA_LocalProxy</classname> + + When getService is called with the target of a local PHP + component, a local proxy is returned. A local proxy is also injected + into the instance variables of a component that are defined with an + @reference and an @binding.php anotations. When the script or + component makes calls on the local proxy, they are passed on to the + target component itself. + Components that need to create an SDO to return to a caller will + need a data factory to call. For this purpose the SCA_LocalProxy + class supports the createDataObject method, which will create an + SDO according to the model defined by the components' @types + annotations. The arguments to the createDataObject are the same as + those to SDO's XML Data Access Service. + +
+ &reftitle.methods; + + + + + createDataObject - create an SDO + + +
+
+ +
+ + <classname>SCA_SoapProxy</classname> + + When getService is called with the target of a WSDL file, a SOAP + proxy is returned. A SOAP proxy is also injected into the instance + variables of a component that are defined with an @reference and an + @binding.ws anotations. When the script or component makes calls + on the SOAP proxy, they are formed into Web service SOAP requests and + passed on to the target component, with the help of the PHP Soap + extension. + Components that need to create an SDO to return to a caller will + need a data factory to call. For this purpose the SCA_SoapProxy + class supports the createDataObject method, which will create an + SDO according to the model defined within the target WSDL. The + arguments to the createDataObject are the same as those to SDO's XML + Data Access Service. + +
+ &reftitle.methods; + + + + + createDataObject - create an SDO + + +
+
+ +
+ + + +
+ + &reference.sca.functions; + +
+ \ No newline at end of file diff --git a/reference/sca/constants.xml b/reference/sca/constants.xml new file mode 100644 index 0000000000..658611b725 --- /dev/null +++ b/reference/sca/constants.xml @@ -0,0 +1,29 @@ + + + +
+ &reftitle.constants; + &extension.constants; + None +
+ + diff --git a/reference/sca/functions/SCA-LocalProxy-createDataObject.xml b/reference/sca/functions/SCA-LocalProxy-createDataObject.xml new file mode 100644 index 0000000000..78c54d9abe --- /dev/null +++ b/reference/sca/functions/SCA-LocalProxy-createDataObject.xml @@ -0,0 +1,170 @@ + + + + + + SCA_LocalProxy::createDataObject + create an SDO + + + &reftitle.description; + + void + SCA_LocalProxy::createDataObject + + string + type_namespace_uri + + + string + type_name + + + + &warn.experimental.func; + + This method is used inside either an ordinary PHP script or an SCA + component that needs to create an SDO to pass to a local service. The + parameters are the desired SDO's namespace URI and type name. The + namespace and type must be defined in the interface of the component + that is to be called, so the namespace and type must be defined in one of + the schema files which are specfied on the @types annotation within + the component for which the SCA_LocalProxy object is a proxy. + + + + &reftitle.parameters; + + + + + type_namespace_uri + + + The namespace of the type. + + + + + type_name + + + The name of the type. + + + + + + + &reftitle.returnvalues; + Returns the newly created SDO_DataObject. + + + + &reftitle.errors; + + + + + SDO_TypeNotFoundException + + + Thrown if the namespaceURI and typeName do not correspond + to a type in any of the schema files specified in the @types + annotations within the component for which the SCA_LocalProxy + object is a proxy.. + + + + + + + + + + + + + + + diff --git a/reference/sca/functions/SCA-SoapProxy-createDataObject.xml b/reference/sca/functions/SCA-SoapProxy-createDataObject.xml new file mode 100644 index 0000000000..e66d04db3f --- /dev/null +++ b/reference/sca/functions/SCA-SoapProxy-createDataObject.xml @@ -0,0 +1,171 @@ + + + + + + SCA_SoapProxy::createDataObject + create an SDO + + + &reftitle.description; + + void + SCA_SoapProxy::createDataObject + + string + type_namespace_uri + + + string + type_name + + + + &warn.experimental.func; + + This method is used inside either an ordinary PHP script or an SCA + component that needs to create an SDO to pass to a web service. The + parameters are the desired SDO's namespace URI and type name. The + namespace and type must be defined in the interface of the component + that is to be called, so the namespace and type must be defined within + the WSDL for the web service. If the web service is also an SCA component + then the types will have been defined within one of the schema files + which are specfied on the @types annotation within the component for + which the SCA_SoapProxy object is a proxy. + + + + &reftitle.parameters; + + + + + type_namespace_uri + + + The namespace of the type. + + + + + type_name + + + The name of the type. + + + + + + + &reftitle.returnvalues; + Returns the newly created SDO_DataObject. + + + + &reftitle.errors; + + + + + SDO_TypeNotFoundException + + + Thrown if the namespaceURI and typeName do not correspond + to a type found in the WSDL that was used to initialise this + SCA_SoapProxy. + + + + + + + + + + + + + + + diff --git a/reference/sca/functions/SCA-createDataObject.xml b/reference/sca/functions/SCA-createDataObject.xml new file mode 100644 index 0000000000..6fa4251605 --- /dev/null +++ b/reference/sca/functions/SCA-createDataObject.xml @@ -0,0 +1,167 @@ + + + + + + SCA::createDataObject + create an SDO + + + &reftitle.description; + + void + SCA::createDataObject + + string + type_namespace_uri + + + string + type_name + + + + &warn.experimental.func; + + This method is used inside an SCA component that needs to create + an SDO to return. The parameters are the desired SDO's namespace URI + and type name. The namespace and type must be defined in one of the + schema files which are specfied on the @types annotation within the + component. + + + + &reftitle.parameters; + + + + + type_namespace_uri + + + The namespace of the type. + + + + + type_name + + + The name of the type. + + + + + + + &reftitle.returnvalues; + Returns the newly created SDO_DataObject. + + + + &reftitle.errors; + + + + + SDO_TypeNotFoundException + + + Thrown if the namespaceURI and typeName do not correspond + to a type in any of the schema files specified in the @types + annotations. + + + + + + + + + + + + + + + diff --git a/reference/sca/functions/SCA-getService.xml b/reference/sca/functions/SCA-getService.xml new file mode 100644 index 0000000000..bb113cd56f --- /dev/null +++ b/reference/sca/functions/SCA-getService.xml @@ -0,0 +1,148 @@ + + + + + + SCA::getService + + Obtain a proxy for a service + + + + &reftitle.description; + + SCA_LocalProxy or SCA_SoapProxySCA::getService + + + + &warn.experimental.func; + + Examine the target and initialise and return a proxy of the appropriate sort. If the target is for a local PHP component the returned proxy will be an SCA_LocalProxy. If the + target is for a WSDL file, the returned proxy will be a SCA_SoapProxy. + + + + &reftitle.parameters; + + + + + target + + + An absolute or relative path to the PHP component, or to the WSDL file. A relative path, if specified, is resolved relative to the location of the script issuing the + getService call, and not against the include_path or current working directory. + + + + + + + &reftitle.returnvalues; + + The SCA_LocalProxy or SCA_SoapProxy. + + + + + + + + + + + + + + + + + + diff --git a/reference/sca/reference.xml b/reference/sca/reference.xml new file mode 100644 index 0000000000..388c5b291e --- /dev/null +++ b/reference/sca/reference.xml @@ -0,0 +1,1513 @@ + + + + + + + SCA Functions + SCA + + +
+ &reftitle.intro; + &warn.experimental; + + SCA for PHP makes it possible for a PHP programmer to write + reusable components, which can be called in a variety of ways, with an + identical interface and with a minimum of fuss. At present + components can call each other either locally or via Web services, + but in the future it is expected that other ways will be possible. It + provides the programmer with a way of doing this which will look as + natural as possible in PHP. + + + + SCA components use phpDocumentor-style (see + http://www.phpdoc.org/) annotations to declare dependencies on + other SCA components or Web services. The SCA for PHP runtime + resolves these dependencies at runtime on behalf of the components, + and thus allows the PHP programmer to focus on the business logic + rather than on locating and obtaining references to dependencies. + + + + The SCA for PHP programming model can be extended to support a + number of service types, such as REST and Atompub. However, Web + services (more accurately, WSDL defined, SOAP/HTTP services), are + the only type currently specified. + + + + Components also use annotations to define the interface which + they expose as a service. The SCA for PHP runtime will automatically + generate WSDL from these annotations, so that an SCA component is + easily exposed as a web service. These annotations are a natural + extension to those provided by phpDocumentor. Deploying a Web + service can be as simple as placing a PHP component under the document + root of a web server. + + + + Components also use annotations to specify data structures + (expressed using XML schema complex types) which are then handled + using Service Data Objects (SDOs). + + + + A PHP script which is not an SCA component and which contains no + annotations can use the services of an SCA component. A PHP script or + component can make calls to a web service that is not an SCA component, + but using the same system of calls or annotations to obtain a + reference. + + + + First we show a single SCA component, ConvertedStockQuote + which illustrates many of the features of SCA for PHP. It has one + method, + getQuote, which given a stock "ticker" + obtains a price quote for that stock, converted to a given currency. + We shall be using this example as a basis for explaining the SCA for PHP + throughout the rest of this document. + + + + + A sample SCA component + +stock_quote->getQuote($ticker); + $rate = $this->exchange_rate->getRate($currency); + return $rate * $quote; + } +} +?> +]]> + + + + + + In this example, we see that an SCA component is implemented by a + script containing a PHP class and includes + SCA.php. The class contains a mixture of + business logic and references to other components or services. In + the illustrated + getQuote method there is only business + logic, but it relies on the instance variables + $stock_quote and + $exchange_rate having been initialized. + These refer to two other components and will be initialized by the SCA + runtime with proxies for these two services, whenever this + component executes. The annotations for these two services show one + to be a local component, which will be called within the same PHP + runtime, and one to be a remote component which will be called via a + SOAP request. This component also exposes the + getQuote method both locally and as a web + service, so it in turn can be called either locally or remotely. + + +
+ +
+ &reftitle.required; + + If you want to use SCA to consume or produce Web services then you + need PHP 5.2.0 or later, built with the soap extension enabled. If you + just want to use local components, and do not wish to use the Web + service bindings, then this version of SCA for PHP will also run with + PHP 5.1.6. + +
+ +
+ &reftitle.install; + + SCA is packaged along with SDO in one combined package on PECL. + See http://www.php.net/sdo#sdo.installation for installing the + SCA_SDO package from PECL. The SCA code must be on the include path of + your PHP installation, for example if it is installed as + /usr/local/lib/php/SCA, the include_path directive must include + /usr/local/lib/php + +
+ +
+ &reftitle.examples; + + The examples in the subsequent sections illustrate the + following aspects of PHP for SCA: + + + + + + How PHP annotations are used to define PHP classes as SCA + components, and how annotations are used to define the + services. + + + + + How an SCA component can be exposed as a Web service + + + + + How an SCA component can consume a Web service, whether + provided by another SCA component or by some other service which + knows nothing of SCA + + + + + How an SCA component can call another SCA component locally + (within the same process and on the same call stack) + + + + + How a client script which is not an SCA component can use the + getService call to obtain a proxy for an SCA component. + + + + + How data structures such as Addresses, or Puchase Orders, + are represented as Service Data Objects, and handled. + + + + + How SCA components are deployed, and in particular how and + when WSDL is generated for a service. + + + + + How parameters are always passed by value (and not by + reference) between components, even when the calls are local. + This ensures that the semantics of a call do not change depending on + the location of a component. + + + + + How positional parameters to a service are supported, even + when the underlying WSDL is document literal wrapped, and + naturally supports only named parameters. + + + + + How business and runtime exceptions are handled. + + + + + +
+ The structure of a Service Component + + A service component is implemented by a class. To identify it + as a service component, it contains an @service annotation. The SCA + runtime will use the file name of the script to determine the + component name, by convention. The class and script file must + therefore share the same name. + + + + PHP SCA components always expose a service, and there is no way + for a component to be invoked other than to be called as a result of a + Web service request, or called directly from another component or + from a script. For this reason a valid PHP SCA component will always + contain an @service annotation and at least one public method. + + + + Each SCA Component requires that the SCA.php script is + included. As well as containing the definition of the SCA class, + this script contains executable PHP code that will run whenever the + script is called, and which will be responsible for making the + component behave as needed. + + + + + + It is very important that if your file contains other + includes, they come before the include for SCA.php. If there are + includes after the include for SCA.php, they will not have been + processed when the SCA runtime runs your class. + + + + + The example below illustrates this overall structure + + + + + The structure of an SCA for PHP component + + + +]]> + + + +
+ +
+ 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.ws, and indicates that the proxy is either for a local + component or for a Web service respectively. For both @binding.php + and @binding.ws, 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. + + + + + Obtaining a proxy for a local PHP class + + + +]]> + + + + + + 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: + + + + + Obtaining a proxy for a web service + + +]]> + + + + + + 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. + + +
+ +
+ + Calling another Service Component + + + The ConvertedStockQuote example also calls the proxies for + the two components to which it refers. + + + + + Calling services + +stock_quote->getQuote($ticker); +$rate = $this->exchange_rate->getRate($currency); +?> +]]> + + + + + + The call to the StockQuote service is a call to a local service; + the call to the ExchangeRate service is a call to a remote service. + Note that the way the call is made looks the same regardless of + whether the call is to a local service or a remote one. + + + + The proxies which have been injected ensure that the way calls + to components look and behave are the same way regardless of whether + they are to a local or remote service, so that components are not + sensitive to whether a call is to a local or a remote service. For + example, the proxy for a local service takes copies of the arguments + and passes only those copies, to ensure that calls are made to be + pass-by-value, as they would be for a remote call. Also, the proxy + for a remote service takes the arguments from a positional + parameter list and ensures they are packaged properly in a SOAP + request and converted back to a positional parameter list at the far + end. + + + + In the example above, the + + $ticker and + + $currency are clearly PHP scalar types. + Components can pass the PHP scalar types string, integer, float and + boolean, but data structures on service calls are always passed as + Service Data Objects (SDOs). A later section describes how a + component can create an SDO to pass on a local or Web service call, or + how a component can create an SDO to return. The PHP SDO project + documentation describes how to work with the SDO APIs (see + the SDO pages. + + +
+ +
+ + Locating and calling services from a script which is not an + SCA Component + + + SCA components obtain proxies for other components or + services as instance variables annotated with @reference, but + this is not possible for a script that is not itself also a component. + A client script which is not a component must use the + SCA::getService static method to obtain a + proxy for a service, whether local or remote. The + getService method takes a URI as the + argument. Typically this is the location of a local PHP script + containing a component, or of a wsdl file, and is used in exactly the + same way as the targets of the @binding annotations described in the + previous section: that is, relative URIs are resolved against the + location of the client script and not against the PHP include_path + or current working directory. + + + + For example, a script that needed to obtain proxies for the + ExchangeRate and StockQuote services but was not a component would + use the + getService method as follows: + + + + + Obtaining a proxy using getService + + +]]> + + + + + + Methods on services can then be called on the returned proxy, + just as they can in a component. + + + + Making calls on the proxy + +getQuote($ticker); +$rate = $exchange_rate->getRate($currency); +?> +]]> + + + + +
+ +
+ Exposing a Service Component as a Web service + + + SCA for PHP can generate WSDL from the annotations within a + service component, so that it can be easily deployed and exposed as a + Web service. To provide SCA with the information it needs to + generate the WSDL, it is necessary to add the annotation + @binding.ws under the @service annotation and to specify the + parameters and return values of the methods using the @param and + @return annotations. These annotations will be read when WSDL is + generated, and the order and types of the parameters determine the + contents of the + <schema> section of the WSDL. + + + + SCA for PHP always generates document/literal wrapped WSDL + for components that are exposing a Web service. Note that this does + not stop components from consuming Web services which are not SCA + components and which are documented with WSDL written in a + different style. + + + + The scalar types which can be used in the @param annotation are + the four common PHP scalar types: boolean, integer, float and + string. These are simply mapped to the XML schema types of the same + name in the WSDL. The example below, which is a trivial + implementation of the StockQuote service that the + ConvertedStockQuote component calls, illustrates string and + float types. + + + + + StockQuote Service + + +]]> + + + + + + WSDL much like the following (though with a service location + other than 'localhost', probably) would be generated from this + service: + + + + + Generated WSDL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + +
+ +
+ + Deploying an SCA component + + There are no special steps needed to deploy a PHP SCA + component. It is sufficient to place the component PHP script in its + proper place under the web server document root, just like any other + PHP script. It is the + SCA::initComponent executable line + within each component that will be executed whenever the script is + called, and which will be responsible for making the component + respond appropriately to Web service calls, local calls, or + requests for WSDL. + + +
+ +
+ + Obtaining the WSDL for an SCA component offering a Service as + a Web service + + + SCA components that expose a Web service interface (i.e. have + an @binding.ws annotation) will return their WSDL definition in + response to an HTTP request with a get parameter of "wsdl". The usual + way to obtain this is with "?wsdl" on the end of a URL. The example + below uses + file_get_contents to obtain WSDL from a + service and writes it to a temporary file before then obtaining a + proxy for the service in the usual way. You could of course also + obtain the WSDL in a browser, or by some other means, and save the file + yourself. + + + + + Generated WSDL + + +]]> + + + + + + + NOTE: If the wsdl requires imported xsds, these will need to be + fetched separately. + + +
+ +
+ Understanding how the WSDL is generated + + SCA for PHP generates WSDL for components which contain an + @binding.ws annotation after the @service annotation. To + generate WSDL, the SCA runtime reflects on the component and + examines the @param and @return annotations for each public + method, as well as any @types annotations within the component. The + information from the @param and @return annotations is used to + build the <types> section of the WSDL. Any @types + annotations which specify a separate schema file will result in an + <import> element for that schema within the WSDL. + + +
+ Location attribute of the <service> element + + + At the bottom of the WSDL is the <service> element + which uses the location attribute to identify the URL of the + service. For example this might look as follows: + + + + + location attribute + + +]]> + + + + + + Note that this location is relative to the document root of + the web server, and cannot be worked out in advance. It can only be + worked out once the component is in its proper place under a running + web server, when the hostname and port can be known and placed in the + WSDL. Detail from the URL that requests the WSDL is used, so for + example if the WSDL is generated in response to a request to + http://www.example.com:1111/ConvertedStockQuote/ConvertedStockQuote.php?wsdl, + a location of + http://www.example.com:1111/ConvertedStockQuote/ConvertedStockQuote.php + is what will be inserted into the location attribute in the WSDL. + +
+ +
+ Document/literal wrapped WSDL and positional + parameters + + SCA for PHP generates WSDL in the document/literal wrapped + style. This style encloses the parameters and return types of a + method in 'wrappers' which are named after the corresponding + method. The <types> element at the top of the WSDL defines + each of these wrappers. If we consider the + getQuote method of the + ConvertedStockQuote example: + + + + + method with two arguments + +stock_quote->getQuote($ticker); + $rate = $this->exchange_rate->getRate($currency); + return $rate * $quote; + } +?> +]]> + + + + + + + The WSDL generated to define this method will name both the + method and the parameters, and give an XML schema type for the + parameters. The types section of the WSDL looks like this: + + + + + types section illustrating named parameters + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + The SCA run-time has special processing to handle how + positional parameter lists in the interface are converted to XML + containing named parameters in the soap request, and then back to + positional parameter lists again. To see why this matters, + consider how a PHP script which used a different interface to make a + SOAP call would need to construct the parameter list. A PHP script + using the PHP SoapClient, for example, would need to pass the + SoapClient a single parameter giving the values for "ticker" and + "currency", perhaps as an associative array. To insist that SCA + components construct parameter lists to make Web service calls in + this way would be to make local and remote calls look different, so a + different approach is needed. + + + + When SCA generates WSDL for an SCA component it includes a + comment in the WSDL which marks that WSDL as being the interface for + an SCA component. In this case, when one SCA component calls + another through a Web service, the SCA runtime on the calling end + takes the positional parameter list from the call and assigns the + values one by one to the named elements in the soap message. For + example a call to the + getQuote method defined above that + passes the values 'IBM' and 'USD' and looks like this: + + + + +getQuote('IBM','USD'); + ]]> + + + + + will result in a soap message containing the + following: + + + + + + IBM + USD + + ]]> + + + + + On the service-providing end, the SCA run-time takes the + parameters one by one from the soap message and forms a positional + parameter list from them, re-forming the argument list + ('IBM','USD'). + + + + + + At both ends the SCA runtime relies on the order in which the + parameters appear in the soap message being the same as that in the + target method's parameter list. This is ultimately determined + by the order of the @param annotations: this determines the order + in which the parameters appear in the WSDL and thereby the order in + which they appear in the soap message. Therefore it is essential + that the order of the @param annotations matches that of the + parameters in the method's parameter list. + + + +
+ +
+ +
+ Working with Data Structures + + SCA components can pass and return the four PHP scalar types + boolean, integer, real and string, but to pass or return data + structures, SCA components use Service Data Objects (SDOs). SDOs + are described in much more detail in + the SDO pages of this manual. + Readers familiar with SDOs will know that they are suitable for + representing the sort of structured and semi-structured data that + is frequently modeled in XML, and that they serialize very + naturally for passing between remote components, or in Web + services. SDOs are presently the only supported way to pass and + return data structures. It is not possible to pass or return PHP + objects, or PHP arrays. + + + + The SCA runtime always assures data is passed by-value, even + for local calls. To do this, the SCA runtime copies any SDOs in the + parameter list before passing them on, just as it does for scalar + types. + + +
+ How data structures are defined to SCA components + + Currently the only mechanism for specifying the location of + a data structure definition is by specifying the types in an XML + schema file. However, in the future it may be possible to define + types in other ways, such as based on PHP classes or interfaces, or + based on definitions expressed as associative arrays. + + + + To illustrate the use of SDOs we introduce a new component. + The PortfolioMangement service below returns an SDO + representing a stock portfolio for a given customer. + + + + + A Component that uses Data Structures + +createDataObject('holding'); + $holding->ticker = 'AAPL'; + $holding->number = 100.5; + $holding = $portfolio->createDataObject('holding'); + $holding->ticker = 'INTL'; + $holding->number = 100.5; + $holding = $portfolio->createDataObject('holding'); + $holding->ticker = 'IBM'; + $holding->number = 100.5; + return $portfolio; + } + +} +?> +]]> + + + + + + + The @types annotation: + + + + + +]]> + + + + + indicates that types in the namespace + http://www.example.org/Portfolio will be found in the schema + file located by the URI PortfolioTypes.xsd. The generated WSDL + would reproduce this information with an import statement as + follows: + + + + + +]]> + + + + + so the URI, absolute or relative, must be one that can be + resolved when included in the schemaLocation attribute. + + +
+ +
+ Creating SDOs + + Readers familiar with SDOs will know that they are always + created according to a description of the permitted structure + (sometimes referred to as the 'schema' or 'model') and that, + rather than creating them directly using 'new', some form of data + factory is needed. Often, an existing data object can be used as the + data factory, but sometimes, and especially in order to get the + first data object, something else must act as the data factory. + + + + In SCA, either the SCA runtime class or the proxies for + services, whether local or remote, can act as the data factories + for SDOs. The choice of which to use, and when, is described in the + next two sections. + + + We switch to a new example in order to illustrate the creation + of SDOs, both to pass to a service, and to be returned from a service. + +
+ +
+ Creating an SDO to pass to a service + + A caller of a service which requires a data structure to be + passed in to it uses the proxy to the service as the data factory for + the corresponding SDOs. For example, suppose a component makes + use of a proxy for a service provided by a local AddressBook + component. + + + + + +]]> + + + + + The AddressBook component that it wishes to call is defined + as follows: + + + + +]]> + + + + + + The AddressBook component provides a service method called + + lookupAddress which uses types from the + http://addressbook namespace. The lookupAddress method takes a + personType data structure and returns an addressType. Both types + are defined in the schema file addressbook.xsd. + + + + Once the component that wishes to use the AddressBook + component has been constructed, so that the + $address_book instance variable contains + a proxy for the service, the calling component can use the proxy in + $address_book to create the person SDO, as + shown below: + + + + +createDataObject('http://addressbook','personType'); +$william_shakespeare ->name = "William Shakespeare"; +$address = $address_book->lookupAddress($william_shakespeare); +?> +]]> + + + + + + Note, the use of the proxy as the means to create the SDO is not + limited to SCA components. If a service is being called from a + general PHP script, and the proxy was obtained with + getService then the same approach is + used. + + + + +createDataObject('http://addressbook','personType'); +?> +]]> + + + + +
+
+ Creating an SDO to return from a component + + A component that needs to create a data object for return to a + caller will not have a proxy to use as a data object, In this case it + uses the + createDataObject static method on + SCA.php. Hence if the AddressBook + component described above needed to create an object of type + addressType within the namespace + http://addressbook, it might do so as follows: + + + + + +]]> + + + + +
+ +
+ +
+ Error handling + + This section describes how errors are handled. There are two + types of errors: + + + + + SCA runtime exceptions are those that signal problems in + the management of the execution of components, and in the + interaction with remote services. These might occur due to + network or configuration problems. + + + + + + Business exceptions are those that are defined by the + programmer. They extend the PHP Exception class, and are thrown + and caught deliberately as part of the business logic. + + + + + +
+ Handling of Runtime exceptions + + There are two types of SCA runtime exception: + + + + + + SCA_RuntimeException - signals a problem found by or + perhaps occurring within the SCA runtime. This can be thrown for + a variety of reasons, many of which can occur regardless of + whether a connection is being made to a local or a remote service: + an error in one of the annotations within a component, a missing + WSDL or php file, and so on. In the case of Web services, an + SCA_RuntimeException can also be thrown if a SoapFault is + received from a remote Web service and the fault code in the + SoapFault indicates that a retry is unlikely to be successful. + + + + + + SCA_ServiceUnavailableException - this is a subclass of + SCA_RuntimeException and signals a problem in connecting to or + using a remote service, but one which might succeed if retried. + In the case of Web services, this exception is thrown if a + SoapFault is received with a fault code that indicates that a + retry might be successful. + + + + +
+
+ Handling of Business exceptions + + Business exceptions may be defined and thrown by a component + in the normal way, regardless of whether the component has been + called locally or remotely. The SCA runtime does not catch + business exceptions that have been thrown by a component called + locally, so they will be returned to a caller in the normal way. If a + component has been called via a Web service, on the other hand, the + SCA runtime on the service providing end does catch business + exceptions, and will ensure these are passed back to the calling + end and re-thrown. Assuming that the calling end has a definition + of the exception (that is, is able to include a file containing the + PHP class defining the exception) the re-thrown exception will + contain the same details as the original, so that the + getLine and + getFile methods for example will contain + the location where the exception was thrown within the business + logic. The exception will be passed in the detail field of a soap + fault with a fault code of "Client". + +
+ +
+ +
+ + +
+ &reftitle.classes; + + Most of the interface to SCA is through the annotations within + SCA components so there are few public classes and methods. The only + SCA classes that scripts or components can call are the SCA class + itself, and the proxy classes SCA_LocalProxy and SCA_SoapProxy. + + +
+ + + <classname>SCA</classname> + + + Much of the work of the SCA class is performed when the file + SCA.php is included within an SCA component. However, a PHP script + may include + SCA.php and call the + getService method on the SCA class in order + to obtain a proxy for a service. A component will not need to do this as + proxies are obtained instead by defining an instance variable with + the @reference annotation. + + + Components that need to create an SDO to return to a caller will + need a data factory to call. For this purpose the SCA class supports + the + createDataObject method, which will + create an SDO according to the model defined by the component's + @types annotations. The arguments to + createDataObject are the same as those to + SDO's XML Data Access Service. + + +
&reftitle.methods; + + + + + getService - obtain a proxy for a service + + + + + + createDataObject - create an SDO + + + +
+
+ +
+ + <classname>SCA_LocalProxy</classname> + + + When + getService is called with the target of a + local PHP component, a local proxy is returned. A local proxy is also + injected into the instance variables of a component that are + defined with an @reference and an @binding.php anotation. When the + script or component makes calls on the local proxy, they are passed + on to the target component itself. + + + Components that need to create an SDO to pass to a component + will need a data factory to call. For this purpose the + SCA_LocalProxy class supports the createDataObject method, + which will create an SDO according to the model defined by the + components' @types annotations. The arguments to the + createDataObject are the same as those to SDO's XML Data Access + Service. + + +
+ &reftitle.methods; + + + + + createDataObject - create an SDO + + + +
+
+ +
+ + <classname>SCA_SoapProxy</classname> + + + When + getService is called with the target of a + WSDL file, a SOAP proxy is returned. A SOAP proxy is also injected + into the instance variables of a component that are defined with an + @reference and an @binding.ws anotations. When the script or + component makes calls on the SOAP proxy, they are formed into Web + service SOAP requests and passed on to the target component, with + the help of the PHP Soap extension. + + + Components that need to create an SDO to pass to a component + will need a data factory to call. For this purpose the SCA_SoapProxy + class supports the createDataObject method, which will create an + SDO according to the model defined within the target WSDL. The + arguments to the createDataObject are the same as those to SDO's XML + Data Access Service. + + +
+ &reftitle.methods; + + + + + createDataObject - create an SDO + + + +
+
+ +
+ + + +
+ + &reference.sca.functions; + +
+ \ No newline at end of file diff --git a/reference/sca/reference_1.xml b/reference/sca/reference_1.xml new file mode 100644 index 0000000000..4fd2bffbe8 --- /dev/null +++ b/reference/sca/reference_1.xml @@ -0,0 +1,132 @@ + + + + + + + SCA Functions + SCA + + +
+ &reftitle.intro; + SCA for PHP makes it possible for a PHP programmer to write + reusable components, which can be called in a variety of ways, with an + identical interface and with a minimum of fuss. At present + components can call each other either locally or via Web services, + but in the future it is expected that other ways will be possible. It + provides the programmer with a way of doing this which will look as + natural as possible in PHP. + + SCA components use phpDocumentor-style (see + http://www.phpdoc.org/) annotations to declare dependencies on + other SCA components or Web services. The SCA for PHP runtime + resolves these dependencies at runtime on behalf of the components, + and thus allows the PHP programmer to focus on the business logic + rather than on locating and obtaining references to dependencies. + + + The SCA for PHP programming model can be extended to support a + number of service types, such as REST and Atompub, however, Web + services (more accurately, WSDL defined, SOAP/HTTP services), are + the only type currently specified. + + Components also use annotations to define the interface which + they expose as a service. The SCA for PHP runtime will automatically + generate WSDL from these annotations, so that an SCA component is + easily exposed as a web service. These annotations are a natural + extension to those provided by phpDocumentor. Deploying a Web + service can be as simple as placing a PHP component under the document + root of a web server. + + Components also use annotations to specify data structures + (expressed using XML schema complex types) which are then handled + using Service Data Objects (SDOs). + + A PHP script which is not an SCA component and which contains no + annotations can use the services of an SCA component. A PHP script or + component can make calls to a web service that is not an SCA component, + but using the same system of annotations to obtain a reference. + +
+ +
+ Glossary + The following terms are used throughout this + document: + + + Component: the name "component" is used in this document to + refer to an implementation artifact (a PHP script containing a + PHP class) which provides a Service to other components. This is + consistent with the SCA use of the term "component" to describe a + configured instance of an implementation, since the script + contains both the implementation of the business logic, + expressed in PHP code, and the configuration information, + expressed through annotations. + + + Service: A service is a set of one or more operations made + available for calling by other components. These might be + operations which can be called locally (i.e. PHP script directly + to PHP script), or operations callable remotely via a Web + service. + + + Service Component: Used as a synonym for Component. + + + + Web service: Unless stated otherwise, the term Web service + is used to refer to a service described by WSDL and callable via + SOAP/HTTP. + + +
+ +
+ &reftitle.required; + If you want to use SCA to consume or produce Web services then + you need PHP 5.2.0 or later, built with the soap extension enabled. + If you just want to use local components, and do not wish to use the Web + service bindings, then this version of SCA for PHP will also run with + PHP 5.1.6. +
+ +
+ &reftitle.install; + See http://www.php.net/sdo#sdo.installation for + installing the SCA_SDO package from PECL. The SCA code must be on the + include path of your PHP installation, for example if it is + installed as /usr/local/lib/php/SCA, the include_path + directive must include /usr/local/lib/php +
+ + + + +
+ + + +
+ \ No newline at end of file