Categories
PHP

Automatically Generating WSDL

As mentioned previously, current Web Services almost always use WSDL (Web Services Description Language) to describe the operations and parameters of your service. Writing WSDL files manually is a real pain and error-prone, but most serious Web Services implementations for PHP can automatically create WSDL.

For this tutorial, we use a library, PHP2WSDL, that can automatically generate WSDL from PHP classes and methods. To use PHP2WSDL library, you need to install it using Composer:

composer require php2wsdl/php2wsdl
Installing php2wsdl library using Composer:
composer require php2wsdl/php2wsdl

Next, you need to create a PHP class that defines your web service. For example, you can create a file called Mathematics.php with the following code:

<?php
 // this page can be accessed by http://locahost/Mathematics.php
 class Mathematics {
  /**
   * Add two numbers
   * @soap
   * @param float $a
   * @param float $b
   * @return float
  */
  public function sum($a, $b) {
   return $this->_sum($a, $b);
  }

  /**
   * Subtract two numbers
   * @soap
   * @param float $a
   * @param float $b
   * @return float
  */
  public function subtract($a, $b) {
   return $a - $b;
  }

  /**
   * Multiply two numbers
   * @soap
   * @param float $a
   * @param float $b
   * @return float
  */
  public function multiply($a, $b) {
   return $a * $b;
  }

  protected function _sum($a, $b) {
   return $a + $b;
  }
 }

The PHP2WSDL library uses the PHPDoc comments to understand the types and names of the parameters and return values of each method. You must also use annotation @soap for all public methods (required by the library).

Next, create a PHP script that will use the PHP2WSDL library to generate the WSDL file. For example, you can create a file called wsdl_maker.php with the following code:

<?php
 // wsdl_maker.php
 require_once 'vendor/autoload.php';
 require_once 'Mathematics.php'; // Service Class
 
 // The class that contains the web service methods.
 $serviceClass = 'Mathematics';

 // The name of the service.
 $serviceName = 'MathematicsService';

 // The location of the service
  $serviceUri = "http://localhost/soap_server.php";
 
 // Create a new instance of PHPClass2WSDL.
 $wsdlGenerator = new PHP2WSDL\PHPClass2WSDL($serviceClass, $serviceUri);

 // Generate and save the WSDL file.
 $wsdlGenerator->generateWSDL(true);
 
 // Save file to the disk
 $wsdlGenerator->save('Mathematics.wsdl');

Running the wsdl_make.php script from the browser will create the Mathematics.wsdl file in the current directory. You can open this file with any text editor or XML viewer and see the generated WSDL.

<?xml version="1.0"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://localhost/soap_server.php" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="Mathematics" targetNamespace="http://localhost/soap_server.php">
  <types>
    <xsd:schema targetNamespace="http://localhost/soap_server.php">
      <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
    </xsd:schema>
  </types>
  <portType name="MathematicsPort">
    <operation name="sum">
      <documentation>Add two numbers</documentation>
      <input message="tns:sumIn"/>
      <output message="tns:sumOut"/>
    </operation>
    <operation name="subtract">
      <documentation>Subtract two numbers</documentation>
      <input message="tns:subtractIn"/>
      <output message="tns:subtractOut"/>
    </operation>
    <operation name="multiply">
      <documentation>Multiply two numbers</documentation>
      <input message="tns:multiplyIn"/>
      <output message="tns:multiplyOut"/>
    </operation>
  </portType>
  <binding name="MathematicsBinding" type="tns:MathematicsPort">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="sum">
      <soap:operation soapAction="http://localhost/soap_server.php#sum"/>
      <input>
        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/soap_server.php"/>
      </input>
      <output>
        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/soap_server.php"/>
      </output>
    </operation>
    <operation name="subtract">
      <soap:operation soapAction="http://localhost/soap_server.php#subtract"/>
      <input>
        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/soap_server.php"/>
      </input>
      <output>
        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/soap_server.php"/>
      </output>
    </operation>
    <operation name="multiply">
      <soap:operation soapAction="http://localhost/soap_server.php#multiply"/>
      <input>
        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/soap_server.php"/>
      </input>
      <output>
        <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/soap_server.php"/>
      </output>
    </operation>
  </binding>
  <message name="sumIn">
    <part name="a" type="xsd:float"/>
    <part name="b" type="xsd:float"/>
  </message>
  <message name="sumOut">
    <part name="return" type="xsd:float"/>
  </message>
  <message name="subtractIn">
    <part name="a" type="xsd:float"/>
    <part name="b" type="xsd:float"/>
  </message>
  <message name="subtractOut">
    <part name="return" type="xsd:float"/>
  </message>
  <message name="multiplyIn">
    <part name="a" type="xsd:float"/>
    <part name="b" type="xsd:float"/>
  </message>
  <message name="multiplyOut">
    <part name="return" type="xsd:float"/>
  </message>
  <service name="MathematicsService">
    <port name="MathematicsPort" binding="tns:MathematicsBinding">
      <soap:address location="http://localhost/soap_server.php"/>
    </port>
  </service>
</definitions>

Communicating with Servers: