I've spent hours trying to figure this out and nothing I've tried from suggestions on SO to PHP.net have worked. I'm trying to get a SOAP Call to work where I have multiple nested levels of XML and there's attributes on the top level as well as sub levels, and nothing seems to work. Where am I going wrong with my code?
I've tried what seems like everything from SO and PHP.net, but none of the answers seem to go in depth enough or multiple levels of XML, they all seem to assume that you only go one level deep.
I've tried both of the below, in addition to more:
$params = array("Request"=>array("_"=>array("Credentials"=>array("UserNumberCredentials"=>array("UserNumber"=>$userNumber,"Password"=>$password)),"DeviceInformation"=>array("_"=>"","DeviceType"=>$this->deviceType,"DeviceNumber"=>$this->deviceNumber)),"MessageId"=>$this->messageId));
$params = array("Request"=>array("_"=>array("Credentials"=>array("_"=>array("UserNumberCredentials"=>array("_"=>array("UserNumber"=>$userNumber,"Password"=>$password)))),"DeviceInformation"=>array("_"=>"","DeviceType"=>$this->deviceType,"DeviceNumber"=>$this->deviceNumber)),"MessageId"=>$this->messageId));
And the expected XML is:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<user:logon>
<!--Optional:-->
<Request MessageId="messageId">
<!--Optional:-->
<Credentials>
<!--Optional:-->
<UserNumberCredentials>
<!--Optional:-->
<UserNumber>value</UserNumber>
<!--Optional:-->
<Password>value</Password>
</UserNumberCredentials>
</Credentials>
<!--Optional:-->
<DeviceInformation DeviceType="deviceType" DeviceNumber="number" />
</Request>
</user:logon>
</soapenv:Body>
</soapenv:Envelope>
I'm passing params into the SOAP call like this:
$results = $this->client->logon($params);
I've tried multiple ways, and either it returns a validation error, where it says it's missing MessageId attribute on the request tag or when it returns a soap fault saying the device information or credentials are wrong, and I know they're both typed correctly and passed into the wrapping function variables correctly, so they're being passed over the soap call correctly. But because it returns a soap fault, I can't tell the actual formed XML it's passing over.
UPDATE: The below parameters are sort of correct, but both of the DeviceInformation attributes are not being sent I think. I think it's only sending one, so the server is rejecting the call. The DeviceInformation tag itself is empty, but the DeviceNumber and DeviceType attributes are both required in that tag, and I think only one or none are being sent in the call. But it returns a fault, so I'm not able to get the XML to see.
$params = array("Request"=>array("_"=>array("Credentials"=>array("UserNumberCredentials"=>array("UserNumber"=>$userNumber,"Password"=>$password)),"DeviceInformation"=>array("_"=>"","DeviceType"=>$this->deviceType,"DeviceNumber"=>$this->deviceNumber)),"MessageId"=>$this->messageId));
Here is how i normally login and send my SOAP requests:
<?php
// The form
$params = array(
"Request"=>array(
"MessageId"=>$this->messageId,
"Credentials"=>array(
"UserNumberCredentials"=>array(
"UserNumber"=>$userNumber,
"Password"=>$password
)
),
"DeviceInformation"=>array(
"DeviceType"=>$this->deviceType,
"DeviceNumber"=>$this->deviceNumber
)
)
);
// API Configs
$config = array(
"wsdl" => "https:// ... the wsdl url ... ", // WSDL URL Here
"namespace" => "http://schemas.xmlsoap.org/soap/envelope/",
"username" => "", // Username
"password" => "", // Password
"soap_options" => array(
"exceptions" => true,
"trace" => 1,
/* If you need a proxy, uncomment
"proxy_host" => "",
"proxy_port" => 80,
*/
"cache_wsdl" => WSDL_CACHE_NONE
),
// For SSL..
"stream_context" => stream_context_create(array(
"ssl" => array(
// set some SSL/TLS specific options
"verify_peer" => false,
"verify_peer_name" => false,
"allow_self_signed" => true
)
))
);
// Initialize soap client object
$client = new SoapClient($config, $config["soap_options"]);
// Credentials
$credentials = array(
"userName" => $config["username"],
"password" => $config["password"]
);
$authvalues = new SoapVar($credentials, SOAP_ENC_OBJECT);
// Headers
$header = new SoapHeader($config["namespace"], "AuthenticationInfo", $authvalues, false);
$client->__setSoapHeaders(array($header));
// Response
$resp = array(
"status" => "success"
);
// Request
$req = array();
try {
// SOAP Request
$req = $client->logon($params); // Here is the WS Method you want to call.
$resp["result"] = $req;
} catch(Exception $e) {
$resp["status"] = "error";
$resp["details"] = $e;
$resp["result"] = $req;
$resp["soap_form"] = $form;
}
echo json_encode($resp);