Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
# AutoDiscovery
SOAP functionality implemented within this component is intended to make all
steps required for SOAP communications more simple. SOAP is a language
independent protocol, however, which means it may be used for more than just
PHP-to-PHP communications, adding some complexity to its implementation.
There are three configurations for SOAP applications supported by zend-soap:
- SOAP server PHP application <---> SOAP client PHP application
- SOAP server non-PHP application <---> SOAP client PHP application
- SOAP server PHP application <---> SOAP client non-PHP application
In each situation, the SOAP server must expose the functionality it provides so
the client knows how to interact with it. This is done via a
[WSDL](http://www.w3.org/TR/wsdl) (Web Services Description Language) document.
The WSDL language is quite complex, making preparation of WSDL documents
difficult; this task is complicated when the API for your service changes, as
any changes then need to be synced back to the WSDL.
These problems may be solved via WSDL autodiscovery, which zend-soap provides
via its `Zend\Soap\AutoDiscover` class.
Autodiscovery in zend-soap follows the same patterns as you use for creating a
zend-soap `Server`, but uses the classes and functions attached to it to extract
the information required to generate a WSDL document.
As a refresher, zend-soap allows using either of the following to define a
server:
- PHP classes.
- PHP functions.
Each are also supported by the autodiscovery functionality. Additionally,
`AutoDiscover` supports datatype mappins from PHP to [XSD types](http://www.w3.org/TR/xmlschema-2/).
The following is a basic example demonstrating the autodiscovery functionality.
It uses similar functionality as when using [Zend\Soap\Server](server.md), but
instead of using `handle()` to handle an incoming SOAP request, it provides a
`generate()` method, which returns a [Zend\Soap\Wsdl](wsdl.md) instance. This
can then be used to return an XML representation to the client.
```php
class MySoapServerClass
{
/* ... */
}
$autodiscover = new Zend\Soap\AutoDiscover();
$autodiscover
->setClass('MySoapServerClass')
->setUri('http://localhost/server.php')
->setServiceName('MySoapService');
$wsdl = $autodiscover->generate();
// Emit the XML:
echo $wsdl->toXml();
// Or dump it to a file; this is a good way to cache the WSDL
$wsdl->dump("/path/to/file.wsdl");
// Or create a DOMDocument, which you can then manipulate:
$dom = $wsdl->toDomDocument();
```
> ### AutoDiscover !== Server
>
> `AutoDiscover` *is not a `Server` instance*; it cannot and does not act as a
> SOAP server on its own, but instead provides the WSDL used by clients that
> will interact with your SOAP server.
>
> SOAP interactions are always performed over HTTP POST requests, while
> retrieval of WSDL is performed using HTTP GET. As such, you *can* server both
> from the same script, provided you detect the incoming method and respond
> accordingly:
>
> ```php
> if ($_SERVER['REQUEST_METHOD'] == 'GET') {
> if (! isset($_GET['wsdl'])) {
> header('HTTP/1.1 400 Client Error');
> return;
> }
>
> $autodiscover = new Zend\Soap\AutoDiscover();
> $autodiscover->setClass('HelloWorldService')
> ->setUri('http://example.com/soap.php');
> header('Content-Type: application/wsdl+xml');
> echo $autodiscover->toXml();
> return;
> }
>
> if ($_SERVER['REQUEST_METHOD'] != 'POST') {
> header('HTTP/1.1 400 Client Error');
> return;
> }
>
> // pointing to the current file here
> $soap = new Zend\Soap\Server("http://example.com/soap.php?wsdl");
> $soap->setClass('HelloWorldService');
> $soap->handle();
> ```
## Class autodiscovery
If a class is used to provide SOAP server functionality, then the same class
should be provided to `Zend\Soap\AutoDiscover` for WSDL generation:
```php
$autodiscover = new Zend\Soap\AutoDiscover();
$autodiscover
->setClass('My_SoapServer_Class')
->setUri('http://localhost/server.php')
->setServiceName('MySoapService');
$wsdl = $autodiscover->generate();
```
The following rules are used during WSDL generation:
- The generated WSDL describes an RPC/Encoded style web service. If you want to
describe a document/literal server, use the `setBindingStyle()` and
`setOperationBodyStyle()` methods.
- The PHP class name is used as the web service name unless `setServiceName()`
is used explicitly to set the name. When only functions are used, the service
name has to be set explicitly or an exception will be thrown during WSDL
document generation.
- You can set the endpoint of the actual SOAP Server via the `setUri()` method.
This is a required option, and also used as the target namespace for all
service related names (including described complex types).
Complex types are generated using the following rules:
- Class methods are joined into one [Port Type](http://www.w3.org/TR/wsdl#_porttypes),
with port names using the format `<$serviceName>Port`.
- Each class method/function is registered as a corresponding port operation.
- Only the "longest" available method prototype is used for WSDL generation.
- WSDL autodiscovery utilizes PHP docblocks provided by the developer to determine the
parameter and return types. In fact, for scalar types, this is the only way to
determine the parameter types, and for return types, this is the only way to
determine them. This means that *providing correct and fully detailed
docblocks is not only best practice, but required for autodiscovery*.
## Function autodiscovery
If a set of functions are used to provide your SOAP server functionality, then
the same set should be provided to `Zend\Soap\AutoDiscovery` for WSDL
generation:
```php
$autodiscover = new Zend\Soap\AutoDiscover();
$autodiscover->addFunction('function1');
$autodiscover->addFunction('function2');
$autodiscover->addFunction('function3');
$wsdl = $autodiscover->generate();
```
The same rules apply to generation as described in the class autodiscovery section above.
## Autodiscovering Datatypes
Input/output datatypes are converted into network service types using the
following mapping:
- PHP strings &lt;-&gt; `xsd:string`.
- PHP integers &lt;-&gt; `xsd:int`.
- PHP floats and doubles &lt;-&gt; `xsd:float`.
- PHP booleans &lt;-&gt; `xsd:boolean`.
- PHP arrays &lt;-&gt; `soap-enc:Array`.
- PHP object &lt;-&gt; `xsd:struct`.
- PHP class &lt;-&gt; based on complex type strategy (See the [WSDL section on adding complex types](wsdl.md#adding-complex-type-information)).
- type\[\] or object\[\] (ie. int\[\]) &lt;-&gt; based on complex type strategy
- PHP void &lt;-&gt; empty type.
- If type is not matched to any of these types by some reason, then `xsd:anyType` is used.
Where:
- `xsd:` refers to the [http://www.w3.org/2001/XMLSchema](http://www.w3.org/2001/XMLSchema)
namespace
- `soap-enc:` refers to the [http://schemas.xmlsoap.org/soap/encoding/](http://schemas.xmlsoap.org/soap/encoding/)
namespace
- `tns:` is the "target namespace" for the service.
> ### Complex type discovery
>
> `Zend\Soap\AutoDiscover` will be created with the
> `Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType` class as its detection
> algorithm for complex types. The first parameter of the `AutoDiscover`
> constructor takes any complex type strategy implementing
> `Zend\Soap\Wsdl\ComplexTypeStrategy\ComplexTypeStrategyInterface` (or a string
> class name of an implementation). name of the class. See the
> [Zend\Soap\Wsdl documentation on adding complex types](wsdl.md#adding-complex-type-information)
> for more information.
## WSDL Binding Styles
WSDL offers different transport mechanisms and styles. This affects the
`soap:binding` and `soap:body` tags within the `Binding` section of the WSDL
document. Different clients have different requirements as to what options
really work. Therefore you can set the styles before you call either the
`setClass()` or `addFunction()` method on the `AutoDiscover` class.
```php
$autodiscover = new Zend\Soap\AutoDiscover();
// Defaults are
// - 'use' => 'encoded'
// - 'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'
$autodiscover->setOperationBodyStyle([
'use' => 'literal',
'namespace' => 'http://framework.zend.com',
]);
// Defaults are:
// - 'style' => 'rpc'
// - 'transport' => 'http://schemas.xmlsoap.org/soap/http'
$autodiscover->setBindingStyle([
'style' => 'document',
'transport' => 'http://framework.zend.com',
]);
$autodiscover->addFunction('myfunc1');
$wsdl = $autodiscover->generate();
```

View File

@@ -0,0 +1,132 @@
# Zend\\Soap\\Client
The `Zend\Soap\Client` class simplifies SOAP client development for PHP
programmers, and may be used in either WSDL or non-WSDL mode.
Under WSDL mode, `Zend\Soap\Client` uses a WSDL document to define transport
layer options.
The WSDL description is usually provided by the web service the client will
access. If the WSDL description is not made available, you may want to use
`Zend\Soap\Client` in non-WSDL mode. Under this mode, all SOAP protocol options
have to be set explicitly on the `Zend\Soap\Client` class.
## Instantiation
The `Zend\Soap\Client` constructor takes two parameters:
- `$wsdl` - the URI of a WSDL file.
- `$options` - options for modifying the behavior of the client instance.
Both of these parameters may be set later using the `setWsdl($wsdl)` and
`setOptions($options)` methods respectively.
> ### Non-WSDL mode requirements
>
> If you use `Zend\Soap\Client` component in non-WSDL mode, you **must** set the
> 'location' and 'uri' options.
The following options are recognized:
- `soap_version` (`soapVersion`) - soap version to use (`SOAP_1_1` or
`SOAP_1_2`).
- `classmap` (`classMap`) - maps WSDL types to PHP classes; option must be an
array where keys are the WSDL types, and values are the PHP class to which
to map.
- `encoding` - internal character encoding (UTF-8 is always used as an external
encoding).
- `wsdl` - specifying this option sets the client in WSDL mode. Can be set
after-the-fact using `setWsdl($wsdl)`.
- `uri` - target namespace for the SOAP service (required for non-WSDL-mode;
no-op when in WSDL mode).
- `location` - the URL to request (required for non-WSDL-mode; no-op when in
WSDL mode).
- `style` - request style (non-WSDL mode only); one of `SOAP_RPC` or
`SOAP_DOCUMENT`.
- `use` - method to use when encoding messages (non-WSDL mode only);
either `SOAP_ENCODED` or `SOAP_LITERAL`.
- `login` and `password` - login and password for HTTP authentication.
- `proxy_host`, `proxy_port`, `proxy_login`, and `proxy_password` - use when
specifying a service behind a proxy server.
- `local_cert` and `passphrase` - HTTPS client certificate authentication
options.
- `compression` - compression options; combination of
`SOAP_COMPRESSION_ACCEPT`, `SOAP_COMPRESSION_GZIP` and/or
`SOAP_COMPRESSION_DEFLATE` options.
The following demonstrate usage of compression options:
```php
// Accept response compression
$client = new Zend\Soap\Client(
'some.wsdl',
['compression' => SOAP_COMPRESSION_ACCEPT]
);
// Compress requests using gzip with compression level 5
$client = new Zend\Soap\Client(
'some.wsdl',
['compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 5]
);
// Compress requests using deflate compression
$client = new Zend\Soap\Client(
"some.wsdl",
['compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE]
);
```
## Performing SOAP Requests
After we've created a `Zend\Soap\Client` instance, we can perform SOAP requests.
Each web service method is mapped to a virtual `Zend\Soap\Client` instance
method which takes parameters with common PHP types.
As an example, given the following server:
```php
class MyClass
{
/**
* This method takes ...
*
* @param integer $inputParam
* @return string
*/
public function method1($inputParam)
{
/* ... */
}
/**
* This method takes ...
*
* @param integer $inputParam1
* @param string $inputParam2
* @return float
*/
public function method2($inputParam1, $inputParam2)
{
/* ... */
}
/* ... */
}
$server = new Zend\Soap\Server(null, $options);
$server->setClass('MyClass');
$server->handle();
```
We can write a client as follows:
```php
$client = new Zend\Soap\Client("MyService.wsdl");
// $result1 is a string
$result1 = $client->method1(10);
// $result2 is a float
$result2 = $client->method2(22, 'some string');
```

View File

@@ -0,0 +1,10 @@
<div class="container">
<div class="jumbotron">
<h1>zend-soap</h1>
<p>Create, serve, and access SOAP applications, and parse and generate WSDL.</p>
<pre><code class="language-bash">$ composer require zendframework/zend-soap</code></pre>
</div>
</div>

View File

@@ -0,0 +1,11 @@
# zend-soap
[![Build Status](https://secure.travis-ci.org/zendframework/zend-soap.svg?branch=master)](https://secure.travis-ci.org/zendframework/zend-soap)
[![Coverage Status](https://coveralls.io/repos/zendframework/zend-soap/badge.svg?branch=master)](https://coveralls.io/r/zendframework/zend-soap?branch=master)
`Zend\Soap` is a component to manage the [SOAP](http://en.wikipedia.org/wiki/SOAP)
protocol in order to design client or server PHP application.
- File issues at https://github.com/zendframework/zend-soap/issues
- Documentation is at https://zendframework.github.io/zend-soap/

View File

@@ -0,0 +1,261 @@
# Zend\\Soap\\Server
`Zend\Soap\Server` provides a wrapper around PHP's
[SoapServer](http://php.net/SoapServer) implementation with convenience
functionality for generating WSDL and registering internal handlers.
It may be used in WSDL or non-WSDL mode, and can map functionality to either PHP
classes or functions in order to define your web service API.
When in WSDL mode, it uses a prepared WSDL document to define server object
behavior and transport layer options.
WSDL documents may be auto-generated with functionality provided by the
[Zend\Soap\AutoDiscover](auto-discovery.md) component, or constructed manually
using the [Zend\Soap\Wsdl](wsdl.md) class or any other XML generation tool.
If the non-WSDL mode is used, then all protocol options must be provided via the
options mechanism.
## Zend\Soap\Server instantiation
Instantiation of `Server` instances varies based on whether or not you are using
WSDL mode.
### Instantiation for WSDL mode
When in WSDL mode, the constructor expects two optional paramters:
- `$wsdl`: the URI of a WSDL file. This may be set after-the-fact using
`$server->setWsdl($wsdl)`.
- `$options`: options to use when creating the instance. These may be set later
using `$server->setOptions($options)`.
The following options are recognized in the WSDL mode:
- `soap_version` (`soapVersion`) - soap version to use (`SOAP_1_1` or `SOAP_1_2`).
- `actor` - the actor URI for the server.
- `classmap` (`classMap`) which can be used to map some WSDL types to PHP
classes. The option must be an array with WSDL types as keys, and names of PHP
classes as values.
- `encoding` - internal character encoding (UTF-8 is always used as an external encoding).
- `wsdl` - equivalent to calling `setWsdl($wsdlValue)`.
### Instantiation for non-WSDL mode
The first constructor parameter **must** be set to `NULL` if you plan to use
`Zend\Soap\Server` functionality in non-WSDL mode.
You also have to set the `uri` option in this case (see below).
The second constructor parameter, `$options`, is an array of options for
configuring the behavior of the server; these may also be provided later using
`$server->setOptions($options)`. Options recognized in non-WSDL mode include:
- `soap_version` (`soapVersion`) - soap version to use (`SOAP_1_1` or `SOAP_1_2`).
- `actor` - the actor URI for the server.
- `classmap` (`classMap`) - an associative array used to map WSDL types to PHP
classes. The option must be an associative array using WSDL types as the
keys, and PHP class names as values.
- `encoding` - internal character encoding (UTF-8 is always used as an external
encoding).
- `uri` (required) - URI namespace for SOAP server.
## Defining your SOAP API
There are two ways to define your SOAP API in order to expose PHP functionality.
The first one is to attach a class to the `Zend\Soap\Server` object that
completely describes your API:
```php
class MyClass
{
/**
* This method takes ...
*
* @param integer $inputParam
* @return string
*/
public function method1($inputParam)
{
// ...
}
/**
* This method takes ...
*
* @param integer $inputParam1
* @param string $inputParam2
* @return float
*/
public function method2($inputParam1, $inputParam2)
{
// ...
}
/* ... */
}
$server = new Zend\Soap\Server(null, $options);
// Bind class to Soap Server:
$server->setClass(MyClass::class);
// Or bind an instance:
$server->setObject(new MyClass());
// Handle a request:
$server->handle();
```
> ### Docblocks are required
>
> You should completely describe each method using a method docblock if you plan
> to use autodiscover functionality to prepare your WSDL.
The second method for defining your API is to use one or more functions, passing
them to one or more of the `addFunction()` or `loadFunctions()` methods:
```php
/**
* This function ...
*
* @param integer $inputParam
* @return string
*/
function function1($inputParam)
{
// ...
}
/**
* This function ...
*
* @param integer $inputParam1
* @param string $inputParam2
* @return float
*/
function function2($inputParam1, $inputParam2)
{
// ...
}
$server = new Zend\Soap\Server(null, $options);
$server->addFunction('function1');
$server->addFunction('function2');
$server->handle();
```
## Request and response handling
`Zend\Soap\Server` component performs request/response processing automatically,
but allows you to intercept each in order to perform pre- or post-processing.
### Request pre- and post-processing
The `Zend\Soap\Server::handle()` method handles a request from the standard
input stream ('php://input'). It may be overridden either by supplying a request
instance to the `handle()` method, or by setting the request via the
`setRequest()` method:
```php
$server = new Zend\Soap\Server(/* ... */);
// Set request using optional $request parameter to the handle() method:
$server->handle($request);
// Set request using setRequest() method:
$server->setRequest();
$server->handle();
```
A request object may be represented using any of the following, and handled as
follows:
- `DOMDocument` (casts to XML)
- `DOMNode` (owner document is retrieved and cast to XML)
- `SimpleXMLElement` (casts to XML)
- `stdClass` (`__toString()` is called and verified to be valid XML)
- `string` (verified to be valid XML)
The last request processed may be retrieved using the `getLastRequest()` method,
which returns the XML string:
```php
$server = new Zend\Soap\Server(/* ... */);
$server->handle();
$request = $server->getLastRequest();
```
### Response post-processing
The `Zend\Soap\Server::handle()` method automatically emits the generated
response to the output stream. It may be blocked using `setReturnResponse()`
with `true` or `false` as a parameter. When set to `true`, `handle()` will
return the generated response instead of emitting it.
The returned response will be either an XML string representing the response, or
a `SoapFault` exception instance.
> #### Do not return SoapFaults
>
> SoapFault instances, when cast to a string, will contain the full exception
> stack trace. For security purposes, you do not want to return that
> information. As such, check your return type before emitting the response
> manually.
```php
$server = new Zend\Soap\Server(/* ... */);
// Get a response as a return value of handle(),
// instead of emitting it to standard output:
$server->setReturnResponse(true);
$response = $server->handle();
if ($response instanceof SoapFault) {
/* ... */
} else {
/* ... */
}
```
The last response emitted may also be retrieved for post-processing using
`getLastResponse()`:
```php
$server = new Zend\Soap\Server(/* ... */);
$server->handle();
$response = $server->getLastResponse();
if ($response instanceof SoapFault) {
/* ... */
} else {
/* ... */
}
```
## Document/Literal WSDL Handling
The document/literal binding-style/encoding pattern is used to make SOAP
messages as human-readable as possible and allow abstraction between very
incompatible languages. The .NET framework uses this pattern for SOAP service
generation by default. The central concept of this approach to SOAP is the
introduction of a Request and an Response object for every function/method of
the SOAP service. The parameters of the function are properties on the request
object, and the response object contains a single parameter that is built in the
style `<methodName>Result`
zend-soap supports this pattern in both the AutoDiscover and Server
components. You can write your service object without knowledge of the pattern.
Use docblock comments to hint the parameter and return types as usual. The
`Zend\Soap\Server\DocumentLiteralWrapper` wraps around your service object and
converts request and response into normal method calls on your service.
See the class doc block of the `DocumentLiteralWrapper` for a detailed example
and discussion.

View File

@@ -0,0 +1,312 @@
# WSDL Parsing and Generation
The `Zend\Soap\Wsdl` class is used by `Zend\Soap\Server` internally to operate
with WSDL documents. In most cases, you will not interact with it directly.
Nevertheless, you could also use functionality provided by this class for your
own needs. `Zend\Soap\Wsdl` contains both a parser and a generator for WSDL
documents.
## Instantiation
The `Zend\Soap\Wsdl` constructor takes three parameters:
- `$name` - name of the web service being described.
- `$uri` - URI where the WSDL will be available (could also be a reference to
the file in the filesystem.)
- `$strategy` - optional flag used to identify the strategy for complex types
(objects) detection. To read more on complex type detection strategies go to
the section on [adding complex types](#adding-complex-type-information).
- `$classMap` - Optional array of class name translations from PHP Type (key) to
WSDL type (value).
## addMessage() method
The `addMessage($name, $parts)` method adds a new message description to the
WSDL document (`/definitions/message` element).
Each message corresponds to methods in terms of `Zend\Soap\Server` and
`Zend\Soap\Client` functionality.
The `$name` parameter represents the message name.
The `$parts` parameter is an array of message parts which describes SOAP call
parameters, represented as an associative array of 'part name' (SOAP call
parameter name) =&gt; 'part type' pairs.
Type mapping management is performed using one of the `addTypes()` and
`addComplexType()` methods (see below).
> ### Message Typing
>
> Messages parts can use either the `element` or `type` attribute for typing (see
> [the W3C WSDL specification](http://www.w3.org/TR/wsdl#_messages)).
>
> The `element` attribute must refer to a corresponding element in the data type
> definition. A `type` attribute refers to a corresponding complexType entry.
>
> All standard XSD types have both `element` and `complexType` definitions (see
> the [SOAP encoding specification](http://schemas.xmlsoap.org/soap/encoding/)
> for details).
>
> All non-standard types, which may be added using the
> `Zend\Soap\Wsdl::addComplexType()` method, are described using the
> `complexType` node of the `/definitions/types/schema/` section of the WSDL
> document.
>
> The `addMessage()` method always uses the `type` attribute to describe types.
## addPortType() method
The `addPortType($name)` method adds a new port type to the WSDL document
(`/definitions/portType`) with the specified port type name.
In terms of the `Zend\Soap\Server` implementation, it joins a set of web service
methods into a single operation.
See [the W3C portTypes documentation](http://www.w3.org/TR/wsdl#_porttypes) for
more details.
## addPortOperation() method
The `addPortOperation($portType, $name, $input = false, $output = false, $fault
= false)` method adds new port operation to the specified port type of the WSDL
document (`/definitions/portType/operation`).
In terms of the `Zend\Soap\Server` implementation, Each port operation
corresponds to a class method (if the web service is based on a class) or
function (if the web service is based on a set of methods).
It also adds corresponding port operation messages depending on the specified
`$input`, `$output` and `$fault` parameters.
> ### Generated messages
>
> `Zend\Soap\Server` generates two messages for each port operation when
> describing operations it provides:
>
> - input message with name `<$methodName>Request`.
> - output message with name `<$methodName>Response`.
See the [W3C WSDL request/response documentation](http://www.w3.org/TR/wsdl#_request-response)
for more details.
## addBinding() method
The `addBinding($name, $portType)` method adds new binding to the WSDL document
(`/definitions/binding`).
A `binding` WSDL document node defines the message format and protocol details
for operations and messages defined by a particular portType (see the [W3C WSDL
binding documentation](http://www.w3.org/TR/wsdl#_bindings)).
The method creates a binding node and returns it; you may then fill the returned
node with data.
`Zend\Soap\Server` uses the name `<$serviceName>Binding` for the 'binding'
element in the WSDL document.
## addBindingOperation() method
The `addBindingOperation($binding, $name, $input = false, $output = false,
$fault = false)` method adds an operation to a binding element
(`/definitions/binding/operation`) with the specified name.
It takes an `XML_Tree_Node` object returned by `addBinding()` as an input
(`$binding` parameter) to add an 'operation' element with input/output/false
entries depending on the specified parameters
The `Zend\Soap\Server` implementation adds a corresponding binding entry for each web service method with
input and output entries, defining the `soap:body` element as `<soap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">`.
See the [W3C WSDL bindings documentation](http://www.w3.org/TR/wsdl#_bindings)
for more details.
## addSoapBinding() method
The `addSoapBinding($binding, $style = 'document', $transport =
'http://schemas.xmlsoap.org/soap/http')` method adds a SOAP binding
(`soap:binding`) entry to the binding element (which is already linked to some
port type) using the specified style and transport (the `Zend\Soap\Server`
implementation uses the RPC style over HTTP).
A `/definitions/binding/soap:binding` element is used to signify that the
binding is bound to the SOAP protocol format.
See the [W3C bindings documentation](http://www.w3.org/TR/wsdl#_bindings) for
more details.
## addSoapOperation() method
The `addSoapOperation($binding, $soap_action)` method adds a SOAP operation
(`soap:operation`) entry to the binding element with the specified action. The
`style` attribute of the `soap:operation` element is not used since the
programming model (RPC-oriented or document-oriented) may be using the
`addSoapBinding()` method already.
The `soapAction` attribute of `/definitions/binding/soap:operation` element
specifies the value of the SOAP action header for this operation. This attribute
is required for SOAP over HTTP and **must not** be specified for other
transports.
The `Zend\Soap\Server` implementation uses the format
`<$serviceUri>#<$methodName>` for the SOAP operation action name.
See the [W3C soap:operation documentation](http://www.w3.org/TR/wsdl#_soap:operation)
for more details.
## addService() method
The `addService($name, $port_name, $binding, $location)` method adds a
`/definitions/service` element to the WSDL document with the specified service
name, port name, binding, and location.
WSDL 1.1 allows several port types (sets of operations) per service; however,
zend-soap does not support this ability.
The `Zend\Soap\Server` implementation uses:
- `<$name>Service` as the service name.
- `<$name>Port` as the port type name.
- `tns:<$name>Binding` [1] as the binding name. (`tns:namespace` is defined as
the script URI; generally this is `'http://' . $_SERVER['HTTP_HOST'] .
$_SERVER['SCRIPT_NAME']`)
- the script URI (`'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']`)
as the service URI for the service definition.
where `$name` is either:
- a class name, for servers representing a PHP class,
- a script name, for servers representing a collection of PHP functions.
See the [W3C WSDL services documentation](http://www.w3.org/TR/wsdl#_services)
for more details.
## Type mapping
The zend-soap WSDL implementation uses the following type mappings between PHP
and SOAP types:
- PHP strings &lt;-&gt; `xsd:string`.
- PHP integers &lt;-&gt; `xsd:int`.
- PHP floats and doubles &lt;-&gt; `xsd:float`.
- PHP booleans &lt;-&gt; `xsd:boolean`.
- PHP arrays &lt;-&gt; `soap-enc:Array`.
- PHP object &lt;-&gt; `xsd:struct`.
- PHP class &lt;-&gt; based on complex type strategy (See
[the section on adding complex types](#adding-complex-type-information)).
- PHP void &lt;-&gt; empty type.
- If a type is not matched to any of the above, then `xsd:anyType` is used.
Where:
- `xsd:` refers to the [http://www.w3.org/2001/XMLSchema](http://www.w3.org/2001/XMLSchema) namespace
- `soap-enc:` refers to the [http://schemas.xmlsoap.org/soap/encoding/](http://schemas.xmlsoap.org/soap/encoding/)
namespace
- `tns:` is the "target namespace" for the service.
> ### Complex types
>
> By default, `Zend\Soap\Wsdl` will be created with the
> `Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType` class as its detection
> algorithm for complex types. The first parameter of the `AutoDiscover`
> constructor takes any complex type strategy implementing
> `Zend\Soap\Wsdl\ComplexTypeStrategy\ComplexTypeStrategyInterface`, or a string
> class name of a class implementing the interface. For backwards compatibility
> with the `$extractComplexType` setting, boolean variables are parsed the
> following way:
>
> - If `TRUE`, `Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType` is used.
> - If `FALSE`, `Zend\Soap\Wsdl\ComplexTypeStrategy\AnyType` is used.
### Retrieving type information
The `getType($type)` method may be used to retrieve the mapping for a specified
PHP type:
```php
$wsdl = new Zend\Soap\Wsdl('My_Web_Service', $myWebServiceUri);
$soapIntType = $wsdl->getType('int');
class MyClass
{
/* ... */
}
$soapMyClassType = $wsdl->getType('MyClass');
```
### Adding complex type information
The `addComplexType($type)` method is used to add complex types (PHP classes) to
a WSDL document.
The method is automatically used by the `getType()` method to add corresponding
complex types of method parameters or return types.
The detection and generation algorithm it uses is based on the currently active
detection strategy for complex types. You can set the detection strategy either
by specifying the class name as a string or providing an instance of a
`Zend\Soap\Wsdl\ComplexTypeStrategy` implementation as the third parameter to
the constructor, or by calling the `setComplexTypeStrategy($strategy)` function
of `Zend\Soap\Wsdl`.
The following detection strategies currently exist:
- `Zend\Soap\Wsdl\ComplexTypeStrategy\DefaultComplexType`: Enabled by default
(when no third constructor parameter is set). Iterates over the public
attributes of a class type and registers them as subtypes of the complex
object type.
- `Zend\Soap\Wsdl\ComplexTypeStrategy\AnyType`: Casts all complex types into the
simple XSD type `xsd:anyType`. Warning: this shortcut for complex type
detection can probably only be handled successfully by weakly typed languages
such as PHP.
- `Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence`: This strategy allows
specifying arrays of the given type, which can be any PHP scalar type (`int`,
`string`, `bool`, `float`), as well as objects or arrays of objects.
- `Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex`: This strategy allows
detecting very complex arrays of objects. Objects types are detected based on
the `Zend\Soap\Wsdl\Strategy\DefaultComplexType`, and an array is wrapped
around that definition.
- `Zend\Soap\Wsdl\ComplexTypeStrategy\Composite`: This strategy can combine all
strategies by connecting PHP complex types (classes/objects) to the desired
strategy via the `connectTypeToStrategy($type, $strategy)` method. A complete
typemap can be given to the constructor as an array with `$type` / `$strategy`
pairs. The second parameter specifies the default strategy that will be used
if an unknown type is requested for adding, and defaults to the
`Zend\Soap\Wsdl\Strategy\DefaultComplexType` strategy.
The `addComplexType()` method creates a
`/definitions/types/xsd:schema/xsd:complexType` element for each described
complex type, using the specified PHP class name.
Class properties **MUST** have a docblock section with the described PHP type in
order to be included in the WSDL description.
`addComplexType()` checks if the type is already described within types section
of the WSDL document, and prevents duplication of types. Additionally, it has
recursion detection.
See the [W3C WSDL types documentation](http://www.w3.org/TR/wsdl#_types) for
more details.
## addDocumentation() method
The `addDocumentation($input_node, $documentation)` method adds human readable
documentation using the optional `wsdl:document` element.
The `/definitions/binding/soap:binding` element is used to signify that the
binding is bound to the SOAP protocol format.
See the [W3C WSDL documentation section](http://www.w3.org/TR/wsdl#_documentation)
for more details.
## Retrieve the final WSDL document
Several methods exist for retrieving the full WSDL definition document:
- `toXML()` will generate an XML string.
- `toDomDocument()` will generate a PHP `DOMDocument` instance.
- `dump($filename = false)` will dump the XML to the specified filename, or, if
no filename is provided, return the XML string.