Search code examples
zend-frameworksoapwsdlzend-soap

Missing SOAP headers in envelope (Zend_Soap_Client, wsdl mode)


I am struggling with creating a proper SOAP envelope in a Zend Soap Client instance.

Here is a sample of an expected envelope, generated from the WSDL file:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                      xmlns:v1="http://coc.gov/xsd/ESB/SupplementalData/V1" 
                      xmlns:ns="http://schemas.calgary.ca/xsd/familycommunitysurvey/2012/08" 
                      xmlns:ns1="http://schemas.calgary.ca/xsd/familycommunitysurveycdm/2012/08">
   <soapenv:Header>
      <v1:SupplementalData>
         <v1:SourceName>CFS</v1:SourceName>
         <v1:ServiceProvider>
            <v1:Name>FamilyCommunitySurvey</v1:Name>
            <v1:OperationName>GetCodeLookupByName</v1:OperationName>
         </v1:ServiceProvider>
         <v1:CorrelationID>23451235634</v1:CorrelationID>
      </v1:SupplementalData>
   </soapenv:Header>

   <soapenv:Body>
      <ns:GetCodeLookupByNameRequest>
         <ns1:Name>Country</ns1:Name>
      </ns:GetCodeLookupByNameRequest>
   </soapenv:Body>
</soapenv:Envelope>

The properties I need to set are 'SourceName', 'CorrelationID' in the header, and 'Name' in the body. Here is how I'm doing it:

    $fsiiConnect = new Zend_Soap_Client($wsdl, array('soap_version' => SOAP_1_1));

    $fsiiConnect->setLocation($endPoint);
    $fsiiConnect->setHttpLogin($userName);
    $fsiiConnect->setHttpPassword($password);

    $data=array(
       'SourceName' => 'CFS',
       'CorrelationID' => '1234251435632',
       'Name' => 'Country'
   );

   try {
     $results = $fsiiConnect->GetCodeLookupsByName($data);
   }
   catch (Exception $e) {
     print $fsiiConnect->getLastRequest();
   }

And the contents of getLastRequest() are:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:ns1="http://schemas.calgary.ca/xsd/familycommunitysurveycdm/2012/08" 
                   xmlns:ns2="http://schemas.calgary.ca/xsd/familycommunitysurvey/2012/08">
   <SOAP-ENV:Body>
      <ns2:GetCodeLookupByNameRequest>
         <ns1:Name>Country</ns1:Name>
      </ns2:GetCodeLookupByNameRequest>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

So that it's only setting properties to objects in the body, not the header. Any ideas why would be greatly appreciated!


Solution

  • I needed to use addSoapInputHeader to set header properties. Everything else goes to the body. It's a bit of a multi-step process, so I thought I'd document it here in case anyone else finds it useful:

    1. Use StdClass to create multi-level structure

    $headerObj = new StdClass();
    $headerObj->ServiceProvider = array(
            'Name'          => 'FamilyCommunitySurvey',
            'OperationName' => 'GetCodeLookupByName'
            );
    $headerObj->SourceName = 'foo';
    $headerObj->CorrelationID = 'bar';
    

    2. Use SoapHeader to create appropriate XML structure

     $header = new SoapHeader('http://coc.gov/xsd/ESB/SupplementalData/V1','SupplementalData',$headerObj);
    

    The first argument is the namespace, as defined in the WSDL document. The second argument is the top-level element. The last element is our formatted SOAP header.

    3. Use addSoapInputHeader to add the header to the Zend_Soap_Client instance

    $connect->addSoapInputHeader($header);
    

    This, in combination with the above code produces a request that looks as expected:

    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                       xmlns:ns1="http://schemas.calgary.ca/xsd/familycommunitysurveycdm/2012/08" 
                       xmlns:ns2="http://schemas.calgary.ca/xsd/familycommunitysurvey/2012/08" 
                       xmlns:ns3="http://coc.gov/xsd/ESB/SupplementalData/V1">
       <SOAP-ENV:Header>
          <ns3:SupplementalData>
             <ns3:SourceName>CFS</ns3:SourceName>
             <ns3:ServiceProvider>
                <ns3:Name>FamilyCommunitySurvey</ns3:Name>
                <ns3:OperationName>GetCodeLookupByName</ns3:OperationName>
             </ns3:ServiceProvider>
             <ns3:CorrelationID>1352758058</ns3:CorrelationID>
          </ns3:SupplementalData>
       </SOAP-ENV:Header>
       <SOAP-ENV:Body>
          <ns2:GetCodeLookupByNameRequest>
             <ns1:Name>Country</ns1:Name>
          </ns2:GetCodeLookupByNameRequest>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>