pradosoft / prado-wsdlgenerator
Wsdl generator used in Prado
Requires
- php: >=8.1.0
- ext-dom: *
- ext-pcre: *
- ext-spl: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10
Suggests
- ext-soap: Used by the SOAP server the generated WSDL describes
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-21 14:48:11 UTC
README
Generates a WSDL document from a SOAP provider class by reading its doc comments.
It backs TSoapService, and runs on its own.
Installation
composer require pradosoft/prado-wsdlgenerator
Requires PHP 8.1 and ext-dom. See CHANGELOG.md for what changed between releases.
Usage
use Prado\Wsdl\WsdlGenerator; echo WsdlGenerator::generate(MyProvider::class, 'https://example.com/soap', 'UTF-8');
generate() reflects on the provider, reads the tags below, and returns the
document. It throws an InvalidArgumentException if the encoding is not an XML
encoding name, and a RuntimeException if the document does not parse or the
parser objects to it, which a service name that is not a class name can cause.
Doc tags
| Tag | Placed on | Effect |
|---|---|---|
@soapmethod |
a public method | The method becomes a WSDL operation. Its @param and @return types become the request and response parts. |
@soapproperty |
a property | The property becomes an element of its class's complexType. The type comes from the property's @var tag. |
@soaptype |
the provider class | The named class is written to the WSDL <types> section even when no operation signature refers to it. |
@soaptype covers methods that return mixed results: the operation declares mixed, and each
shape the method can return is declared separately so the client knows all of them.
/** * @soaptype Person * @soaptype Address[] */ class MyProvider { /** * Look up a record. * @param string $key the key to look up * @return mixed a Person or an array of Address * @soapmethod */ public function lookup($key) { /* ... */ } }
A [] suffix declares the array form, which also declares the element type. A type is named as
@param and @return name it: a global class by its name, and a namespaced class by its fully
qualified name, with or without the leading backslash. A short name resolves in the global
namespace, not in the namespace of the provider.
@soapproperty supports nillable, minOccurs and maxOccurs, written in braces after the
variable name:
/** * @soapproperty * @var int $zip {nillable=1, minOccurs=0} */ public $zip;
Where a tag is read
A doc comment that discusses a tag does not carry it, so prose about the generator does not declare anything.
@soapmethod and @soapproperty take no argument, so each is read wherever it
ends its line:
/** @soapmethod */ // carries the tag /** Adds two numbers. @soapmethod */ // carries the tag /** Set @soapmethod to export this.*/ // does not: the line continues
@soaptype takes a class name, which reads exactly like the next word of a
sentence. Position separates the two instead, so it is read at the start of a
line or directly after the opening of the comment:
/** @soaptype Person */ // declares Person /** * @soaptype Person // declares Person * Prefer @soaptype Address for this // does not: the tag is mid-line */
Namespaced classes
A namespace separator is valid in neither a URI nor an NCName, and the class
name is written into both. The generator reflects on the class name as given and
writes it with each separator replaced by a dot, keeping the full name so two
classes sharing a short name do not collide. For App\Soap\QuoteProvider:
| Written as | |
|---|---|
targetNamespace |
urn:App.Soap.QuoteProviderwsdl |
wsdl:service |
App.Soap.QuoteProviderService, and the portType, binding and port likewise |
@return App\Soap\Quote |
tns:App.Soap.Quote, declared as the complexType App.Soap.Quote |
@return App\Soap\Quote[] |
tns:App.Soap.QuoteArray, an unbounded sequence of App.Soap.Quote |
Wsdl::documentName() is the mapping. A global class name holds nothing the
mapping touches, so the document of a global provider is what every earlier
release produced.
Binding style
The generator emits remote procedure calls with SOAP encoding, as WSDL 1.1 and SOAP 1.1 define it. WS-I Basic Profile 1.1 prohibits SOAP encoding (R2706), so a document following the profile is generated by opting in:
use Prado\Wsdl\Wsdl; use Prado\Wsdl\WsdlGenerator; echo WsdlGenerator::generate(MyProvider::class, $uri, 'UTF-8', Wsdl::STYLE_DOCUMENT);
STYLE_RPC (default) |
STYLE_DOCUMENT |
|
|---|---|---|
| Binding style | rpc |
document |
| Body | use="encoded", SOAP encoding |
use="literal", no encodingStyle |
| Message | one part per parameter, typed | one part naming a wrapper element |
| Wrapper elements | none | <operation> and <operation>Response |
Untyped array |
soap-enc:Array |
xsd:anyType |
Both styles read the same doc tags and declare the same complex types. The rpc style is what every earlier release produced and remains the default; a later major release may change that.
Limitations
- A short type name resolves in the global namespace, not in the namespace of the provider. A namespaced type is named by its fully qualified name.
Development
composer fix # apply the code style
composer stan # static analysis
composer unittest # the unit tests
composer fulltest # all three
composer coverage # the unit tests, with a coverage summary
composer coverage-gate # the unit tests, failing below 100% coverage
Coverage needs Xdebug. Continuous integration runs the gate on PHP 8.3, and the unit tests alone on 8.1 and 8.2.