7

Alright, this problem is driving me up the wall. I'm unsuccessfully trying to connect to a web service using PHP and SOAP. I can't figure out what's wrong, and what's more this is a brand new service and their "documentation" is POOR. So I have no idea if the problem isn't actually on their end, but I don't have enough experience with SOAP to be able to know that for sure. I pray someone can help me.

I have been able to connect to the service by putting the XML directly into SOAP UI, but whenever I try to use the SoapClient it breaks down. The XML structure I am looking to send looks like

<Envelope xmlns:ns1="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://a.uri" xmlns:ns3="http://tempuri.org/">
 <Body>
    <GetAuthorization>
        <ns1:registrationObj ns1:type="ns2:RegistrationAuthorization">
            <ns2:Company>####</ns2:Company>
            <ns2:Computer>####</ns2:Computer>
            <ns2:Facility>####</ns2:Facility>
        </ns1:registrationObj> 
    </GetAuthorization>
</Body>
</Envelope>

I have tried approaches too numerous to list. Using __soapCall, and $client->method(), SoapVar, and SoapParam. On the whole I find the documentation for PHP's SoapClient to be a bit sparse. But I can't even get the structure of the call to match what I want it to (dumped via __getLastRequest())

One thing I have noticed is the client keeps dropping the first element of my array (on those instances when I try to pass the parameters in as a plain array. So:

$params = array("Company" => "abc",
                "Computer" => "def",
                "Facility" => "ghi");
$result = $soap_client->__soapCall('GetAuthorization',$params);

returns

<env:Body>
    <ns1:GetAuthorization/>
    <param1>def</param1>
    <param2>ghi</param2>
</env:Body>

note how in this instance the GetAuthorization self closed AND dropped the first array element. I have experienced both separately as well (and it is worth noting that I have gotten the paramaters to be named correctly also. I have gone through so many iterations I can't remember what attempts yield which results. Nonetheless, SOAP is NOT behaving like I would expect it to. It fails to encapsulate data properly and/or drops random elements.

$parameters = 
array("ra" => new SoapVar(array(
    "CompanyId" => new SoapVar("####", SOAP_ENC_OBJECT, 'guid', 'http://schemas.microsoft.com/2003/10/Serialization/', 'CompanyId', 'http://schemas.datacontract.org/x/y/z.xx'),
    "ComputerId" => new SoapVar("{####}", SOAP_ENC_OBJECT, 'string', 'http://www.w3.org/2001/XMLSchema', 'ComputerId', 'http://schemas.datacontract.org/x/y/z.xx'),
    "FacilityId" => new SoapVar("####", SOAP_ENC_OBJECT, 'guid', 'http://schemas.microsoft.com/2003/10/Serialization/', 'FacilityId', 'http://schemas.datacontract.org/x/y/z.xx')
), SOAP_ENC_OBJECT, 'RegistrationAuthorization', 'http://schemas.datacontract.org/x/y/z.xx', 'ra', "http://schemas.datacontract.org/x/y/z.xx"

)));

$result = $auth_client->GetAuthorization($parameters);

Is the structure I was trying to push through originally (before I simplified it to try to figure out what was wrong), figuring that since I need so much control over the namespacing of the parameters I would need to. BUT that just makes the request with a self-closed element.

Can someone PLEASE tell me how to structure the call to yield the appropriate XML structure? Is it possible this is on the Service's end and there is something wrong with the WSDL? (I'm not sure exactly what the WSDL is responsible for on the back end.)

I do apologize for the vagueness of the question, but I feel so lost I'm not even sure of the right one to ask. :-(

6
  • What does __getFunctions() tell you about this method, and perhaps also post the relevant portions of __getTypes() used there? (or, for that matter: if the wsdl is public / does not need to be kept secret, perhaps share that one..) Commented Jan 15, 2014 at 23:33
  • unfortunately, the WSDL and associated info is confidential :-(. I REALLY wanted to include it. Commented Jan 15, 2014 at 23:42
  • AH, well, then: without the definitions of the functions & parameters, the first example really looks like it should work... Are you using the vanilla built-in SoapClient, or some other one or one that extends/alters it? Commented Jan 15, 2014 at 23:46
  • I am using the built in SOAP client. Sorry, I am new to SOAP calls and not familiar with the WSDL's exact function. Is it possible that there is an error on the service's end? Will their code have an effect on HOW my SOAP client builds the request? The service is brand new and I am the first to try and use it. Commented Jan 16, 2014 at 14:46
  • It is not something the server actively can change (it is after all a request you set up & need to send to the server). But a wrong / buggy wsdl can have strange consequences. However, looking at it one more time: in your first example, can you try $soap_client->__soapCall('GetAuthorization',array($params)); instead? (So an extra layer step in an array. Seems like it should do it. It's either $client->FunctionName($parameter) or $client->__soapCall('FunctionName',array($parameter)), see the difference? Commented Jan 16, 2014 at 15:27

2 Answers 2

4

It should work:

<?php
$client = new \SoapClient(null, array(
    'uri'           => 'http://localhost/stack/21150482/',
    'location'      => 'http://localhost/stack/21150482/server.php',
    'trace'         => true
));
try {

    $company         = new \SoapVar('XXXXX', XSD_STRING, null, null, 'Company', 'http://a.uri');
    $computer        = new \SoapVar('XXXXX', XSD_STRING, null, null, 'Computer', 'http://a.uri');
    $facility        = new \SoapVar('XXXXX', XSD_STRING, null, null, 'Facility', 'http://a.uri');

    $registrationObj = new \SoapVar(
        array($company,$computer,$facility),
        SOAP_ENC_OBJECT,
        'RegistrationAuthorization',
        'http://a.uri',
        'registrationObj',
        'http://www.w3.org/2001/XMLSchema-instance'
    );

    $client->GetAuthorization($registrationObj);

} catch (\Exception $e) {
    var_dump($e->getMessage());
}

$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($client->__getLastRequest());

print '<pre>';
print htmlspecialchars($dom->saveXML());

My result is:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/stack/21150482/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://a.uri" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <ns1:GetAuthorization>
      <xsi:registrationObj xsi:type="ns2:RegistrationAuthorization">
        <ns2:Company xsi:type="xsd:string">XXXXX</ns2:Company>
        <ns2:Computer xsi:type="xsd:string">XXXXX</ns2:Computer>
        <ns2:Facility xsi:type="xsd:string">XXXXX</ns2:Facility>
      </xsi:registrationObj>
    </ns1:GetAuthorization>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Sign up to request clarification or add additional context in comments.

1 Comment

This should be marked as the answer. Definitely helped me out of a sinkhole, +1.
1

Different approach I have used is:

<?php 

//note the "(object)" casting
$params = (object)[
  'registrationObj' => (object)[
    'Company' => 'abc',
    'Computer' => 'def',
    'Facility' => 'ghi'
  ]
];

$soap_client = new SoapClient('localhost/soap');

//direct call of the method GetAuthorization (without __soapCall)
$return = $soap_client->GetAuthorization($params);

Should work for PHP >= 5.4

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.