WSDL Generation
WSDL (Web Services Description Language) is an XML document that describes a SOAP web service. In this course, you’ll learn to automatically generate WSDL files from PHP classes using the php2wsdl library.
What is WSDL?
WSDL provides a machine-readable description of a web service, including:
Operations : Available methods/functions
Messages : Input and output parameters
Data types : Parameter types and complex structures
Bindings : Protocol and data format details
Service endpoint : URL where the service is accessible
WSDL acts as a contract between the service provider and consumer, enabling automatic client code generation.
WSDL Structure
A WSDL document contains several key sections:
<? xml version = "1.0" ?>
< definitions xmlns = "http://schemas.xmlsoap.org/wsdl/"
targetNamespace = "http://example.com/service" >
<!-- 1. Types: Data type definitions -->
< types >
< xsd:schema targetNamespace = "http://example.com/service" >
<!-- Complex type definitions -->
</ xsd:schema >
</ types >
<!-- 2. Messages: Input/output messages -->
< message name = "getPvpIn" >
< part name = "codP" type = "xsd:int" />
</ message >
< message name = "getPvpOut" >
< part name = "return" type = "xsd:float" />
</ message >
<!-- 3. Port Type: Available operations -->
< portType name = "OperacionesPort" >
< operation name = "getPvp" >
< input message = "tns:getPvpIn" />
< output message = "tns:getPvpOut" />
</ operation >
</ portType >
<!-- 4. Binding: Protocol details -->
< binding name = "OperacionesBinding" type = "tns:OperacionesPort" >
< soap:binding style = "rpc" transport = "http://schemas.xmlsoap.org/soap/http" />
<!-- Operation bindings -->
</ binding >
<!-- 5. Service: Endpoint location -->
< service name = "OperacionesService" >
< port name = "OperacionesPort" binding = "tns:OperacionesBinding" >
< soap:address location = "http://example.com/service.php" />
</ port >
</ service >
</ definitions >
Installing php2wsdl
The php2wsdl/php2wsdl library generates WSDL from PHP classes. Install it with Composer:
Add to composer.json
{
"require" : {
"php2wsdl/php2wsdl" : "^0.6.1"
}
}
Verify installation
composer show php2wsdl/php2wsdl
Creating a Service Class
To generate WSDL, create a PHP class with properly documented methods. The @soap annotation is crucial:
<? php
namespace Clases ;
require '../vendor/autoload.php' ;
use Clases\ { Producto , Stock , Familia };
class Operaciones
{
/**
* Obtiene el PVP de un producto a partir de su codigo
* @soap
* @param int $codP
* @return float
*/
public function getPvp ( $codP )
{
$producto = new Producto ();
$producto -> setId ( $codP );
$precio = $producto -> getPrecio ();
$producto = null ;
return $precio ;
}
/**
* Devuelve el numero de unidades que existen en una tienda de un producto
* @soap
* @param int $codP Product code
* @param int $codT Store code
* @return int
*/
public function getStock ( $codP , $codT )
{
$stock = new Stock ();
$stock -> setProducto ( $codP );
$stock -> setTienda ( $codT );
$uni = $stock -> getUnidadesTienda ();
$stock = null ;
return $uni ;
}
/**
* Devuelve un array con los codigos de todas las familias
* @soap
* @return string[]
*/
public function getFamilias ()
{
$familas = new Familia ();
$valores = $familas -> getFamilias ();
$familas = null ;
return $valores ;
}
/**
* Devuelve un array con los nombres de los productos de una familia
* @soap
* @param string $codF Family code
* @return string[]
*/
public function getProductosFamilia ( $codF )
{
$productos = new Producto ();
$datos = $productos -> productoFamila ( $codF );
$productos = null ;
return $datos ;
}
}
Key Documentation Requirements
Critical annotations for WSDL generation:
@soap : Marks the method for inclusion in WSDL (required)
@param type $name : Documents each parameter type
@return type : Specifies the return type
Method description: First line of the docblock
Without these annotations, methods won’t appear in the generated WSDL!
Generating the WSDL
Create a script to generate the WSDL file:
<? php
require '../vendor/autoload.php' ;
use PHP2WSDL\ PHPClass2WSDL ;
// Configure your service URL
$host = "dwcs.localhost" ;
$urlrelativo = "/TEMA-06/TAREA-06-anterior/servidorSoap" ;
$uri = "http://" . $host . $urlrelativo ;
$url = $uri . "/servicio.php" ;
// Specify the class to generate WSDL from
$class = "Clases \\ Operaciones" ;
// Create WSDL generator instance
$wsdlGenerator = new PHPClass2WSDL ( $class , $url );
// Generate and save WSDL
$wsdlGenerator -> generateWSDL ( true );
$fichero = $wsdlGenerator -> save ( '../servidorSoap/servicio.wsdl' );
echo "WSDL generated successfully at: $fichero " ;
Configure service URL
Set the host and path where your SOAP service will be deployed.
Specify the class
Provide the fully qualified class name (with namespace).
Generate WSDL
Call generateWSDL(true) to create the WSDL structure.
Save to file
Use save() to write the WSDL to a file.
Running the Generator
php public/generarWsdl.php
This creates servicio.wsdl with all your service definitions.
Understanding the Generated WSDL
Here’s an excerpt from the generated WSDL for the getPvp operation:
<? xml version = "1.0" ?>
< definitions xmlns = "http://schemas.xmlsoap.org/wsdl/"
name = "Clases.Operaciones"
targetNamespace = "http://dwcs.localhost/TEMA-06/TAREA-06-anterior/servidorSoap/servicio.php" >
<!-- Message definitions -->
< message name = "getPvpIn" >
< part name = "codP" type = "xsd:int" />
</ message >
< message name = "getPvpOut" >
< part name = "return" type = "xsd:float" />
</ message >
<!-- Port type (interface) -->
< portType name = "Clases.OperacionesPort" >
< operation name = "getPvp" >
< documentation > Obtiene el PVP de un producto a partir de su codigo </ documentation >
< input message = "tns:getPvpIn" />
< output message = "tns:getPvpOut" />
</ operation >
<!-- Other operations... -->
</ portType >
<!-- Binding (implementation details) -->
< binding name = "Clases.OperacionesBinding" type = "tns:Clases.OperacionesPort" >
< soap:binding style = "rpc" transport = "http://schemas.xmlsoap.org/soap/http" />
< operation name = "getPvp" >
< soap:operation soapAction = "http://dwcs.localhost/.../servicio.php#getPvp" />
< input >
< soap:body use = "encoded" encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" />
</ input >
< output >
< soap:body use = "encoded" encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" />
</ output >
</ operation >
</ binding >
<!-- Service endpoint -->
< service name = "Clases.OperacionesService" >
< port name = "Clases.OperacionesPort" binding = "tns:Clases.OperacionesBinding" >
< soap:address location = "http://dwcs.localhost/TEMA-06/TAREA-06-anterior/servidorSoap/servicio.php" />
</ port >
</ service >
</ definitions >
Type Mapping
PHP types are mapped to XML Schema types:
PHP Type XSD Type Example intxsd:int@param int $codPfloatxsd:float@return floatstringxsd:string@param string $codFboolxsd:boolean@return boolarraysoap-enc:Array@return string[]objectComplex type @return Producto
Array Types
Specify array types in PHPDoc:
/**
* Get all product names
* @soap
* @return string[] Array of product names
*/
public function getProductNames () {
return [ 'Product 1' , 'Product 2' , 'Product 3' ];
}
Creating the SOAP Server
Once you have the WSDL, create a server to handle requests:
<? php
require '../vendor/autoload.php' ;
$host = "dwcs.localhost" ;
$urlrelativo = "/TEMA-06/TAREA-06-anterior/servidorSoap" ;
$uri = "http://" . $host . $urlrelativo ;
$url = $uri . "/servicio.wsdl" ;
$parametros = [ 'uri' => $url ];
try {
// Create SOAP server with WSDL
$server = new SoapServer ( NULL , $parametros );
// Register the service class
$server -> setClass ( 'Clases \\ Operaciones' );
// Handle incoming requests
$server -> handle ();
} catch ( SoapFault $f ) {
die ( "Error in server: " . $f -> getMessage ());
}
WSDL vs Non-WSDL Mode:
WSDL mode : new SoapServer('servicio.wsdl') - Uses WSDL file
Non-WSDL mode : new SoapServer(NULL, ['uri' => $url]) - No WSDL file required
WSDL mode is recommended for better client compatibility and automatic code generation.
Project Structure
Typical SOAP project organization:
TEMA-06/TAREA-06-anterior/
├── composer.json
├── vendor/
│ └── php2wsdl/
├── src/
│ ├── Conexion.php
│ ├── Operaciones.php # Service class
│ ├── Producto.php
│ ├── Stock.php
│ └── Familia.php
├── servidorSoap/
│ ├── servicio.php # SOAP server endpoint
│ └── servicio.wsdl # Generated WSDL
└── public/
├── generarWsdl.php # WSDL generator script
├── generarClases.php # Client class generator
└── cliente.php # SOAP client
Testing the WSDL
After generating the WSDL, test it:
Browser
PHP Client
Command Line
Navigate to the WSDL URL in your browser: http://dwcs.localhost/TEMA-06/TAREA-06-anterior/servidorSoap/servicio.wsdl
You should see the XML document. If you see an error, check:
File permissions
Path configuration
PHP SOAP extension enabled
<? php
$url = "http://dwcs.localhost/TEMA-06/TAREA-06-anterior/servidorSoap/servicio.wsdl" ;
try {
$client = new SoapClient ( $url );
// Get available functions
$functions = $client -> __getFunctions ();
print_r ( $functions );
// Get types
$types = $client -> __getTypes ();
print_r ( $types );
} catch ( SoapFault $f ) {
echo "Error: " . $f -> getMessage ();
}
# View WSDL content
curl http://dwcs.localhost/TEMA-06/TAREA-06-anterior/servidorSoap/servicio.wsdl
# Validate XML
xmllint --noout servicio.wsdl && echo "Valid WSDL"
Common Issues and Solutions
Problem : Methods don’t appear in WSDLSolution : Ensure every public method has @soap in its docblock:/**
* Method description
* @soap
* @param int $id
* @return string
*/
Problem : Namespace doesn’t match your project structureSolution : Check the class name passed to PHPClass2WSDL includes the full namespace:$class = "Clases \\ Operaciones" ; // Double backslash in string
Problem : Changes to PHP class don’t reflect in WSDLSolution : Delete the old WSDL file and regenerate:rm servidorSoap/servicio.wsdl
php public/generarWsdl.php
Problem : SOAP client can’t connect to serviceSolution : Verify the URLs in both generator and server match:// generarWsdl.php
$url = $uri . "/servicio.php" ;
// servicio.php
$url = $uri . "/servicio.wsdl" ;
Best Practices
Comprehensive documentation : Write detailed docblocks for all methods
Consistent naming : Use clear, descriptive method names
Version control : Include WSDL in version control for client reference
Namespace organization : Use PSR-4 autoloading structure
Type safety : Always specify parameter and return types
Error handling : Document possible exceptions in docblocks
Versioning : Include version in service name or namespace when making breaking changes
Next Steps
Now that you can generate WSDL files, learn to consume them:
Consuming Services Build SOAP clients to call web services
SOAP Introduction Review SOAP fundamentals