title: php soap client validate against wsdl
body: <p>I have a problem with validation of my web services against the wsdl file.</p>
  
  <p>I use php with Laravel 5.2 framework, and i have to create a Soap web server. I've put the server and client class in a Controller(servercontroller.php, clientcontroller.php) and the class that process the data passed to the server in repositories folder.
  Then i've put my wsdl file in public folder(g1.wsdl).
  All goes well except the fact that when i try to validate the soap request made by client the server doesn't validate it against wsdl.
  for example if an element in my wsdl has minOccurs = "2" and i pass in my request only one item, the script goes on without any kind of validation response. The same problem happens with the type of the elements.</p>
  
  <p>This is my client:`</p>
  
  <pre><code>&lt;?php
  
  namespace Modules\G1Zucchetti\Http\Controllers;
  
  use Illuminate\Http\Request;
  use Illuminate\Http\Response;
  use Illuminate\Routing\Controller;
  use SoapClient;
  use SoapFault;
  
  class ClientController extends Controller
  {
  /**
   * Display a listing of the resource.
   * @return Response
   */
  public function index()
  {
  
      ini_set("soap.wsdl_cache_enabled", "0");
  
      $context = stream_context_create(array(
          'ssl' =&gt; array(
              'verify_peer' =&gt; false,
              'verify_peer_name' =&gt; false,
              'allow_self_signed' =&gt; true,
              'soap_version' =&gt; SOAP_1_2,
              'connection_timeout' =&gt; 180,
              'trace' =&gt; 1,
              'exceptions' =&gt;true,
          )
      ));
  
      try {
          $client = new SoapClient('http://promek.local/soap/base_server/g1.php?wsdl', array('stream_context' =&gt; $context));
          echo("SOAP Client creato con successo!&lt;br&gt;");
  
          //dd($gsearch-&gt;__getFunctions());
  
          $result=$client-&gt;RequestActiveLicense( array(
                  'Piva'=&gt; 'piva',
                  'CodiceFiscale' =&gt;'cf',
                  'Identificativo' =&gt; 'codiceidentificativo'
          ));
  
          //dump($client-&gt;__getTypes());
          //dd($client-&gt;__getFunctions());
  
          if($result-&gt;ReturnCode == '0000'){
              echo("Servizio Disponibile&lt;br&gt;");
  
              $resultUCS = $client-&gt;UpdateCompanySetting(
                  array(
                      'TokenCode' =&gt; $result-&gt;TokenCode,
                      'MastroCliente' =&gt; 'mc',
                      'ContoCliente' =&gt; 'cc',
                      'MerciVenMastro' =&gt; 'mvm',
                      'MerciVenConto' =&gt; 'mvc',
                      'MastroIncassoB' =&gt; 'mib',
                      'ContoIncassoB' =&gt; 'cib',
                      'MastroIncassoC' =&gt; 'mic',
                      'ContoIncassoC' =&gt; 'cic',
                      'DataInvioDati' =&gt; '2017-10-04'
                  )
              );
  
              dd($resultUCS);
  
          }else{
              echo("Problemi di autenticazione&lt;br&gt;");
              dd($result);
          }
  
      } catch (SoapFault $exception) {
          //dd(trigger_error("SOAP Fault: (faultcode: {$exception-&gt;faultcode}, faultstring: {$exception-&gt;faultstring})", E_USER_ERROR));
  
          dd($exception-&gt;getMessage());
      }
  }
  
  }
  </code></pre>
  
  <p>`</p>
  
  <p>And this is my server:`
      
  
  <pre><code>namespace Modules\G1Zucchetti\Http\Controllers;
  
  use Illuminate\Http\Request;
  use Illuminate\Http\Response;
  use Illuminate\Routing\Controller;
  use SoapServer;
  
  class ServerController extends Controller
  {
  /**
   * Display a listing of the resource.
   * @return Response
   */
  
  public function __construct() {
  
      ini_set('soap.wsdl_cache_enabled', 0);
      ini_set('soap.wsdl_cache_ttl', 0);
      ini_set('default_socket_timeout', 300);
      ini_set('max_execution_time', 0);
  }
  
  public function index() {
  
      $class = "Modules\G1Zucchetti\Repositories\G1WS";
  
      // options for ssl in php 5.6.5
      $opts = array(
          'ssl' =&gt; array(
              'ciphers' =&gt; 'RC4-SHA',
              'verify_peer' =&gt; false,
              'verify_peer_name' =&gt; false
          )
      );
  
  // SOAP 1.2 client
      $params = array(
          'encoding' =&gt; 'UTF-8',
          'verifypeer' =&gt; false,
          'verifyhost' =&gt; false,
          'soap_version' =&gt; SOAP_1_2,
          'trace' =&gt; 1,
          'exceptions' =&gt; 1,
          'connection_timeout' =&gt; 180,
          'stream_context' =&gt; stream_context_create($opts)
      );
  
      try {
  
  
          $server = new SoapServer(public_path() . "/soap/base_server/g1.wsdl", $params);
  
          $server-&gt;setClass($class);
          $server-&gt;handle();
          exit;
      }catch (\SoapFault $e){
          dd($e-&gt;getTraceAsString());
      }
  }
  
  }
  </code></pre>
  
  <p>`
   My Custom class:</p>
  
  <pre><code>&lt;?php
  /**
   * Created by PhpStorm.
   * User: francesco
   * Date: 02/10/17
   * Time: 11.54
   */
  
  namespace Modules\G1Zucchetti\Repositories;
  use Carbon\Carbon;
  use Illuminate\Support\Facades\Session;
  use Modules\G1Zucchetti\Entities\G1Users;
  use Monolog\Logger;
  use Monolog\Handler\StreamHandler;
  
  
  class G1WS {
  
  private $logger;
  private $returnCode;
  private $tokenCode = null;
  private $description;
  
  
  public function __construct()
  {
      $this-&gt;logger = new Logger('G1WS', array(new StreamHandler(public_path() . '/LOG/G1WS/ws.log', Logger::INFO)));
  }
  
  public function RequestActiveLicense($request){
  
      $this-&gt;logger-&gt;addInfo('RequestActiveLicense', array('input params' =&gt; $request));
  
      try{
          $g1User = G1Users::where('identificativo', $request-&gt;Identificativo)
              -&gt;where('partita_iva', $request-&gt;Piva)
              -&gt;where('codice_fiscale', $request-&gt;CodiceFiscale)
              -&gt;first();
  
  
          if(!$g1User){
              $this-&gt;returnCode = config('g1ws.codici.noLicense.returnCode');
              $this-&gt;description = config('g1ws.codici.noLicense.description');
          }elseif(!G1Users::where('identificativo', $request-&gt;Identificativo)
              -&gt;where('partita_iva', $request-&gt;Piva)-&gt;first()) {
              $this-&gt;returnCode = config('g1ws.codici.noMatchPivaIdentificativo.returnCode');
              $this-&gt;description = config('g1ws.codici.noMatchPivaIdentificativo.description');
          }elseif ($g1User-&gt;status &lt; 1){
              $this-&gt;returnCode = config('g1ws.codici.notValidLicense.returnCode');
              $this-&gt;description = config('g1ws.codici.notValidLicense.description');
          }else{
              $this-&gt;returnCode = config('g1ws.codici.ok.returnCode');
              $this-&gt;description = config('g1ws.codici.ok.description');
  
              if(!$g1User-&gt;token){
                  $this-&gt;tokenCode = $g1User-&gt;id_promek_user.(date('Ymdhis'));
                  $g1User-&gt;token = $this-&gt;tokenCode;
                  $g1User-&gt;data_scadenza_token = Carbon::now()-&gt;addMinutes(30);
                  $g1User-&gt;save();
              }else{
                  $this-&gt;tokenCode = $g1User-&gt;token;
              }
  
          }
  
      }catch (\Exception $e){
          $this-&gt;logger-&gt;addError('RequestActiveLicense', array('exception' =&gt; $e-&gt;getMessage()));
      }
  
  $esito = array('ReturnCode' =&gt;$this-&gt;returnCode, 'TokenCode' =&gt; $this-&gt;tokenCode, 'Description' =&gt; $this-&gt;description);
  $this-&gt;logger-&gt;addInfo('RequestActiveLicense', array('response' =&gt; $esito));
  return $esito;
  
  }
  
  public function UpdateCompanySetting($request){
  
      try {
          $g1User = G1Users::where('token', $request-&gt;TokenCode)
              -&gt;where('data_scadenza_token','&gt;=',Carbon::now())
              -&gt;first();
  
          if($g1User){
              $this-&gt;returnCode = config('g1ws.codici.ok.returnCode');
              $this-&gt;description = config('g1ws.codici.ok.description');
              $this-&gt;tokenCode = $request-&gt;TokenCode;
  
              //faccio update company setting
              $g1User-&gt;mastro_cliente = $request-&gt;MastroCliente;
              $g1User-&gt;conto_cliente = $request-&gt;ContoCliente;
              $g1User-&gt;merci_ven_mastro = $request-&gt;MerciVenMastro;
              $g1User-&gt;merci_ven_conto = $request-&gt;MerciVenConto;
              $g1User-&gt;mastro_incasso_b = $request-&gt;MastroIncassoB;
              $g1User-&gt;conto_incasso_b = $request-&gt;ContoIncassoB;
              $g1User-&gt;mastro_incasso_c = $request-&gt;MastroIncassoC;
              $g1User-&gt;conto_incasso_c = $request-&gt;ContoIncassoC;
              $g1User-&gt;data_invio_dati = $request-&gt;DataInvioDati;
              $g1User-&gt;save();
  
          }else{
              $this-&gt;returnCode = config('g1ws.codici.tokenExpired.returnCode');
              $this-&gt;description = config('g1ws.codici.tokenExpired.description');
  
              //richiamo l'utente x svuotare il token
              $g1User = G1Users::where('token', $request-&gt;TokenCode)-&gt;first();
              $g1User-&gt;token = null;
              $g1User-&gt;data_scadenza_token = null;
              $g1User-&gt;save();
  
          }
  
  
      }catch (\Exception $e){
          $this-&gt;logger-&gt;addError('UpdateCompanySetting', array('exception' =&gt; $e-&gt;getMessage()));
      }
  
      $esito = array('ReturnCode' =&gt;$this-&gt;returnCode, 'TokenCode' =&gt; $this-&gt;tokenCode, 'Description' =&gt; $this-&gt;description);
      $this-&gt;logger-&gt;addInfo('UpdateCompanySetting', array('response' =&gt; $esito));
      return $esito;
  }
  
  }
  </code></pre>
  
  <p>And then my wsdl file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
  
  &lt;wsdl:definitions
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:s="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://tempuri.org/"
      xmlns:tns="http://tempuri.org/"
      name="Webserviceaccesspoint"
  &gt;
  
  &lt;wsdl:types&gt;
      &lt;s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/"&gt;
          &lt;s:element name="CompanyInfo"&gt;
              &lt;s:complexType&gt;&lt;s:sequence&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="Piva" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="CodiceFiscale" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="Identificativo" type="s:string" /&gt;
              &lt;/s:sequence&gt;&lt;/s:complexType&gt;
          &lt;/s:element&gt;
          &lt;s:element name="Esito"&gt;
              &lt;s:complexType&gt;&lt;s:sequence&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="ReturnCode" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="TokenCode" type="s:int" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="Description" type="s:string" /&gt;
              &lt;/s:sequence&gt;&lt;/s:complexType&gt;
          &lt;/s:element&gt;
          &lt;s:element name="CompanySetting"&gt;
              &lt;s:complexType&gt;&lt;s:sequence&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="TokenCode" type="s:int" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="MastroCliente" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="ContoCliente" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="MerciVenMastro" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="MerciVenConto" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="MastroIncassoB" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="ContoIncassoB" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="MastroIncassoC" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="ContoIncassoC" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="DataInvioDati" type="s:date" /&gt;
              &lt;/s:sequence&gt;&lt;/s:complexType&gt;
          &lt;/s:element&gt;
          &lt;s:element name="UpdateCompanySettingResult"&gt;
              &lt;s:complexType&gt;&lt;s:sequence&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="ReturnCode" type="s:string" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="TokenCode" type="s:int" /&gt;
                  &lt;s:element minOccurs="1" maxOccurs="1" name="Description" type="s:string" /&gt;
              &lt;/s:sequence&gt;&lt;/s:complexType&gt;
          &lt;/s:element&gt;
      &lt;/s:schema&gt;
  &lt;/wsdl:types&gt;
  
  &lt;wsdl:message name="RequestActiveLicenseRequest"&gt;
      &lt;wsdl:part name="parameters" element="tns:CompanyInfo" /&gt;
  &lt;/wsdl:message&gt;
  &lt;wsdl:message name="RequestActiveLicenseResponse"&gt;
      &lt;wsdl:part name="parameters" element="tns:Esito" /&gt;
  &lt;/wsdl:message&gt;
  
  &lt;wsdl:message name="UpdateCompanySettingRequest"&gt;
      &lt;wsdl:part name="parameters" element="tns:CompanySetting" /&gt;
  &lt;/wsdl:message&gt;
  &lt;wsdl:message name="UpdateCompanySettingResponse"&gt;
      &lt;wsdl:part name="parameters" element="tns:UpdateCompanySettingResult" /&gt;
  &lt;/wsdl:message&gt;
  
  &lt;wsdl:portType name="RequestActiveLicensePortType"&gt;
      &lt;wsdl:operation name="RequestActiveLicense"&gt;
          &lt;wsdl:input message="tns:RequestActiveLicenseRequest" /&gt;
          &lt;wsdl:output message="tns:RequestActiveLicenseResponse" /&gt;
      &lt;/wsdl:operation&gt;
  &lt;/wsdl:portType&gt;
  
  &lt;wsdl:portType name="UpdateCompanySettingPortType"&gt;
      &lt;wsdl:operation name="UpdateCompanySetting"&gt;
          &lt;wsdl:input message="tns:UpdateCompanySettingRequest" /&gt;
          &lt;wsdl:output message="tns:UpdateCompanySettingResponse" /&gt;
      &lt;/wsdl:operation&gt;
  &lt;/wsdl:portType&gt;
  
  &lt;wsdl:binding name="RequestActiveLicenseBinding" type="tns:RequestActiveLicensePortType"&gt;
      &lt;soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /&gt;
      &lt;wsdl:operation name="RequestActiveLicense"&gt;
          &lt;soap:operation soapAction="http://promek.local/g1zucchetti/server#RequestActiveLicense" style="document" /&gt;
          &lt;wsdl:input&gt;&lt;soap:body use="literal" /&gt;&lt;/wsdl:input&gt;
          &lt;wsdl:output&gt;&lt;soap:body use="literal" /&gt;&lt;/wsdl:output&gt;
          &lt;wsdl:documentation&gt;Questo metodo deve essere utilizzato per verificare
              se la licenza di utilizzo dell'interfaccia GPE è v
              alida o
              scaduta/non esistente. E' la prima richiesta avviat
              a dal modulo di interfaccia prima di effettuare qua
              lsiasi
              richiesta successiva.  Successivamente viene utiliz
              zato il codice Identificativo per identificare l'az
              ienda.
              Il codice identificativo può essere generato dal pr
              ovider del servizio WS in modo univoco come
              identificativo di sessione. Nulla vieta di poterlo
              utilizzare per un tempo limitato mantenendo lo stes
              so.
              Successivamente, se scaduto, dovrà esserne richiest
              o uno nuovo.  &lt;/wsdl:documentation&gt;
      &lt;/wsdl:operation&gt;
  &lt;/wsdl:binding&gt;
  
  &lt;wsdl:binding name="UpdateCompanySettingBinding" type="tns:UpdateCompanySettingPortType"&gt;
      &lt;soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /&gt;
      &lt;wsdl:operation name="UpdateCompanySetting"&gt;
          &lt;soap:operation soapAction="http://promek.local/g1zucchetti/server#UpdateCompanySetting" style="document" /&gt;
          &lt;wsdl:input&gt;&lt;soap:body use="literal" /&gt;&lt;/wsdl:input&gt;
          &lt;wsdl:output&gt;&lt;soap:body use="literal" /&gt;&lt;/wsdl:output&gt;
          &lt;wsdl:documentation&gt;Questo metodo deve essere utilizzato per aggiornare
              i dati generali dell'azienda in riferimento alle
              codifiche, codici piano dei conti, etc. da utilizzare come riferimento.  &lt;/wsdl:documentation&gt;
      &lt;/wsdl:operation&gt;
  &lt;/wsdl:binding&gt;
  
  &lt;wsdl:service name="Webserviceaccesspoint"&gt;
      &lt;wsdl:port name="RequestActiveLicensePort" binding="tns:RequestActiveLicenseBinding"&gt;
          &lt;soap:address location="http://promek.local/g1zucchetti/server" /&gt;
      &lt;/wsdl:port&gt;
      &lt;wsdl:port name="UpdateCompanySettingPort" binding="tns:UpdateCompanySettingBinding"&gt;
          &lt;soap:address location="http://promek.local/g1zucchetti/server" /&gt;
      &lt;/wsdl:port&gt;
  &lt;/wsdl:service&gt;
  </code></pre>
  
  <p></p>
  
  <p>Is there any solution to validate the client request against the options setted in wsdl? </p>