我已经使用SoapClient向wsdl创建了一个请求。我已经设法使用__getFunctions()
来获取功能列表,因此可以确认我的URL正常工作。
问题出在调用函数时,我收到Could not connect to host
错误消息。我还应该提到我使用Laravel,并且错误消息没有给我任何更多信息。
我个人认为这是一个基于身份验证的问题,因为我需要通过标题解析用户名和密码,而且我可能语法错误。
我的PHP函数:
try {
$wsdlUrl = 'https://myurl.com/Service.svc?wsdl';
$context = [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
'cache_wsdl' => WSDL_CACHE_NONE,
];
$client = new SoapClient($wsdlUrl, array('stream_context' => $context));
$authentication = array(
'Username' => env('USERNAME'),
'Password' => env('PASSWORD')
);
//Soap Header
$header = new SoapHeader(
'https://myurl.com/',
'Credentials',
$authentication,
false
);
$client->__setSoapHeaders($header);
return $client->GetElement(['ID' => '462493']);
} catch (\Exception $e) {
\Log::error($e->getMessage());
}
和我要匹配的xml:
<soapenv:Header>
<Credentials>
<Password>Password</Password>
<Username>Brugernavn</Username>
</Credentials>
</soapenv:Header>
<soapenv:Body>
<GetElementRequestType>
<ID>4624393</ID>
</GetElementRequestType>
</soapenv:Body>
您的代码中存在一些基本问题。让我们审视使用PHP处理肥皂请求和响应时,您必须做的不同事情。
[使用肥皂处理时,总会抛出SoapFault
。 SoapFault
类直接继承自Exception
。考虑到这一点,您必须捕获一个SoapFault
而不是一个ErrorException
。
try {
// doing some soap stuff here
} catch (SoapFault $fault) {
Log::error($fault->getMessage());
}
可选地,如果您正在等待其他可抛出的东西,则可以使用不同的catch块来捕获不同的异常。
try {
} catch (SoapFault $fault) {
// catches soap faults
} catch (ErrorException $e) {
// catches error exceptions
} finally {
// final catch of everything else
}
finally
语句将始终执行,无论之前抛出过哪种可抛出对象。
只要您不处理任何证书,就不必创建上下文。您可以,但是没有这种情况也可以。在您的情况下,由于您只是在处理用户名和密码凭据,因此上下文只是另一个可能的错误来源。为了开发,SoapClient
类的选项应如下所示。
try {
$wsdl = 'https://www.domain.tld/service?wsdl';
$options = [
'cache_wsdl' => WSDL_CACHE_NONE,
'exceptions' => true,
'trace' => true,
];
$client = new SoapClient($wsdl, $options);
} catch (SoapFault $fault) {
if ($client) {
// get the last sent request
var_dump($client->__getLastRequest());
// get the last response
var_dump($client->__getLastResponse());
}
var_dump($fault);
}
使用trace
选项,您可以启用获取上一个请求和响应的功能。这在开发过程中可能会很有帮助。在任何情况下,exception
选项都会强制客户端抛出异常。如果未设置此选项,则客户端可能会在出现错误情况时保持冷静。
仅假定PHP Soap扩展严格是面向对象的。因此,您必须处理直接在wsdl文件中描述的值对象和元素。您可以通过直接在broser中调用wsdl url来查看定义。此处描述了所有复杂和简单的类型和函数调用。
因此,当我们查看您的soap标头时,会看到带有属性用户名和密码的凭据对象(复杂类型)。我们可以直接在php中将其用作类。
class Credentials
{
protected string $Password;
protected string $Username;
public function getPassword(): string
{
return $this->Password;
}
public function setPassword(string $password): self
{
$this->Password = $password;
return $this;
}
public function getUsername(): string
{
return $this->Username;
}
public function setUsername(string $username): self
{
$this->Username = $username;
return $this;
}
}
您可以看到,这是凭据的简单数据模型。现在,您必须对其进行初始化,并将其强制为soap header。
$credentials = (new Credentials())
->setPassword('bla')
->setUsername('blubb');
$header = new SoapHeader(
'http://www.domain.tld/namespace',
'Credentials',
new SoapVar($credentials, SOAP_ENC_OBJECT, '', '', 'Credentials', '')
);
$client->__setSoapHeaders($header);
$response = $client->GetElement([ 'ID' => 1234 ]);
如果这不起作用,请记住跟踪功能。如果出现肥皂故障,请尝试查看最后发送的请求。在大多数情况下,您可以看到,请求xml结构出了点问题。