具有多个层和属性的 SOAP 客户端
SOAP Client with multiple layers and attributes
我花了几个小时试图解决这个问题,但从 SO 到 PHP.net 的建议,我都没有尝试过。我正在尝试让 SOAP 调用在我有多个 XML 嵌套级别并且在顶层和子级别上都有属性的地方工作,但似乎没有任何效果。我的代码哪里出错了?
我已经尝试了 SO 和 PHP.net 中的所有内容,但 none 的答案似乎足够深入或 XML 的多个级别,它们似乎都假设您只深入一层。
我已经尝试了以下两种方法,此外还有更多:
$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));
而预期的 XML 是:
<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>
我像这样将参数传递到 SOAP 调用中:
$results = $this->client->logon($params);
我尝试了多种方法,要么是 returns 一个验证错误,它说它在请求标签上缺少 MessageId 属性,要么是 returns 一个 soap 错误,说设备信息或凭据错误,我知道它们都被正确输入并正确传递到包装函数变量中,因此它们被正确地传递给 soap 调用。但是因为它 returns 肥皂故障,我无法判断实际形成的 XML 它正在过去。
更新:
下面的参数是正确的,但我认为这两个 DeviceInformation 属性都没有被发送。我认为它只发送一个,所以服务器拒绝呼叫。 DeviceInformation 标签本身是空的,但 DeviceNumber 和 DeviceType 属性在该标签中都是必需的,我认为在调用中只发送了一个或 none。但它 returns 是个错误,所以我无法让 XML 看到。
$params = array("Request"=>array("_"=>array("Credentials"=>array("UserNumberCredentials"=>array("UserNumber"=>$userNumber,"Password"=>$password)),"DeviceInformation"=>array("_"=>"","DeviceType"=>$this->deviceType,"DeviceNumber"=>$this->deviceNumber)),"MessageId"=>$this->messageId));
这是我通常登录和发送 SOAP 请求的方式:
<?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);
显然,下面是应该如何格式化数组以获取参数中的属性。我从使用相同服务的人那里得到了示例代码,这与他们格式化它的方式相似,并且它有效。这与我用谷歌搜索的内容完全不同,但也许它会对以后的人有所帮助。作为记录,我的 SoapClient 处于 WSDL 模式。
$params = array(
"Request"=>array(
"MessageId"=>$this->messageId,
"Credentials"=>array(
"UserNumberCredentials"=>array(
"UserNumber"=>$userNumber,
"Password"=>$password
)
),
"DeviceInformation"=>array(
"DeviceType"=>$this->deviceType,
"DeviceNumber"=>$this->deviceNumber
)
)
);
我花了几个小时试图解决这个问题,但从 SO 到 PHP.net 的建议,我都没有尝试过。我正在尝试让 SOAP 调用在我有多个 XML 嵌套级别并且在顶层和子级别上都有属性的地方工作,但似乎没有任何效果。我的代码哪里出错了?
我已经尝试了 SO 和 PHP.net 中的所有内容,但 none 的答案似乎足够深入或 XML 的多个级别,它们似乎都假设您只深入一层。
我已经尝试了以下两种方法,此外还有更多:
$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));
而预期的 XML 是:
<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>
我像这样将参数传递到 SOAP 调用中:
$results = $this->client->logon($params);
我尝试了多种方法,要么是 returns 一个验证错误,它说它在请求标签上缺少 MessageId 属性,要么是 returns 一个 soap 错误,说设备信息或凭据错误,我知道它们都被正确输入并正确传递到包装函数变量中,因此它们被正确地传递给 soap 调用。但是因为它 returns 肥皂故障,我无法判断实际形成的 XML 它正在过去。
更新: 下面的参数是正确的,但我认为这两个 DeviceInformation 属性都没有被发送。我认为它只发送一个,所以服务器拒绝呼叫。 DeviceInformation 标签本身是空的,但 DeviceNumber 和 DeviceType 属性在该标签中都是必需的,我认为在调用中只发送了一个或 none。但它 returns 是个错误,所以我无法让 XML 看到。
$params = array("Request"=>array("_"=>array("Credentials"=>array("UserNumberCredentials"=>array("UserNumber"=>$userNumber,"Password"=>$password)),"DeviceInformation"=>array("_"=>"","DeviceType"=>$this->deviceType,"DeviceNumber"=>$this->deviceNumber)),"MessageId"=>$this->messageId));
这是我通常登录和发送 SOAP 请求的方式:
<?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);
显然,下面是应该如何格式化数组以获取参数中的属性。我从使用相同服务的人那里得到了示例代码,这与他们格式化它的方式相似,并且它有效。这与我用谷歌搜索的内容完全不同,但也许它会对以后的人有所帮助。作为记录,我的 SoapClient 处于 WSDL 模式。
$params = array(
"Request"=>array(
"MessageId"=>$this->messageId,
"Credentials"=>array(
"UserNumberCredentials"=>array(
"UserNumber"=>$userNumber,
"Password"=>$password
)
),
"DeviceInformation"=>array(
"DeviceType"=>$this->deviceType,
"DeviceNumber"=>$this->deviceNumber
)
)
);