Search by

pradosoft / prado-wsdlgenerator

ctrlaltca

Wsdl generator used in Prado

Package info

github.com/pradosoft/prado-wsdlgenerator

pkg:composer/pradosoft/prado-wsdlgenerator

Statistics

Installs: 125 309

Dependents: 2

Suggesters: 0

Stars: 0

Open Issues: 1

1.2 2026-09-17 06:28 UTC

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.