如果您遵循 Web 标准,使用 PHP 的 Soap 请求实际上非常简单。 PHP SoapClient 类旨在为您完成整个 xml 工作。如果您只使用从 WSDL 文件派生的对象,那将变得非常容易。
你是在正确的方式。第一步应该是从 WSDL 文件中确定函数和数据类型。您已经使用 $client->__getFunctions() 和 $client->__getTypes() 函数完成了这项工作。
ResponseMessage getReport(RequestMessage $getReportRequest)
这提供了以下信息。如果要调用web服务的getReport函数,必须在请求中使用RequestMessage对象,并接收ResponseMessage对象作为响应。那么我们从哪里获得这些方法呢?这些信息写在链接的XSD file 中,或者您也可以使用$client->__getTypes() 函数。这将为我们提供以下信息。
struct ResponseMessage {
messageId responseId;
dateTime responseDateTime;
messageId requestId;
dateTime requestDateTime;
string user;
protocolEnum protocol;
string customProtocol;
string data;
}
RequestMessage {
messageId requestId;
dateTime requestDateTime;
protocolEnum protocol;
string customProtocol;
boolean testDataMarker;
string data;
}
我们可以将一个结构体翻译成一个 PHP 类。这个类就是所谓的值对象。
class RequestMessage
{
protected $requestId;
protected $requestDateTime;
protected $protocol;
protected $customProtocol;
protected $testDataMarker;
protected $data;
public function getRequestId(): ?string
{
return $this->requestId;
}
public function setRequestId(?string $requestId): self
{
$this->requestId = $requestId;
return $this;
}
public function getRequestDateTime(): ?string
{
return $this->requestDateTime;
}
public function setRequestDateTime(?string $requestDateTime): self
{
$this->requestDateTime = $requestDateTime;
return $this;
}
public function getProtocol(): ?string
{
return $this->protocol;
}
public function setProtocol(?string $protocol): self
{
$this->protocol = $protocol;
return $this;
}
public function getCustomProtocol(): ?string
{
return $this->customProtocol;
}
public function setCustomProtocol(?string $customProtocol): self
{
$this->customProtocol = $customProtocol;
return $this;
}
public function getTestDataMarker(): ?bool
{
return $this->testDataMarker;
}
public function setTestDataMarker(?bool $testDataMarker): self
{
$this->testDataMarker = $testDataMarker;
return $this;
}
public function getData(): ?string
{
return $this->data;
}
public function setData(?string $data): self
{
$this->data = $data;
return $this;
}
}
class Credentials
{
protected $user;
protected $password;
public function getUser(): ?string
{
return $this->user;
}
public function setUser(?string $user): self
{
$this->user = $user;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(?string $password): self
{
$this->password = $password;
return $this;
}
}
这是一个简单的 PHP 值对象,带有用于类属性的 getter 和 setter。这些属性与结构信息中所述的完全相同。您可以对 $client->__getTypes() 函数返回的所有结构执行此操作。如果所有类型都映射到 PHP 值对象类,soap 客户端甚至会在映射的 php 类中解析响应。如果没有到响应类型的映射,soap 客户端会将 xml 响应解析为stdClass PHP 对象。
对于getReport 示例,我们需要RequestMessage 和Credentials 值对象。
下一步是使用正确的选项参数初始化SoapClient 类。初始化后,我们需要设置凭证标头,然后为我们的请求设置数据。
try {
$client = new SoapClient(
'https://wasstt.infomonitor.pl/bigApi/v1/ReportOrderService/WEB-INF/wsdl/wsBigApi1v1.wsdl',
[
'trace' => true,
'exception' => true,
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
'soap_version' => SOAP_1_1,
'classmap' => [
'Credentials' => Credentials::class,
'RequestMessage' => RequestMessage::class,
],
]
);
// set the credentials header
$credentials = (new Credentials())
->setUser('user')
->setPassword('password');
$header = new SoapHeader('http://api.big.pl/bigApi/v1/types', 'credentials', $credentials, false);
$client->__setSoapHeaders([ $header ]);
// set the request data
$requestMessage = (new RequestMessage())
->setRequestId(1)
->setRequestDateTime('2020-01-15T15:00:00')
->setProtocol('bimo v1')
->setTestDataMarker(true)
->setData('test');
$result = $client->getReport($requestMessage);
var_dump($result);
} catch (SoapFault $fault) {
var_dump($fault, $client->__getLastRequest(), __LINE__);
}
如您所见,SoapClient 类的初始化包含在 try / catch 块中。这使您能够捕获错误。 trace 选项使您能够获取发送的请求和接收的响应 xml。 classmap 选项包含我们从$client->__getTypes() 函数获得的xsd 类型。 classmap 使soap 客户端能够将类型映射到您的值对象类。
我们知道,getReport webservice 函数需要一个RequestMessage 对象作为参数,我们使用我们的RequestObject 值对象类和我们要在请求中提交的所有值。
发送的xml请求如下:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://api.big.pl/bigApi/v1/types">
<SOAP-ENV:Header>
<ns1:credentials>
<user>user</user>
<password>password</password>
</ns1:credentials>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:getReportRequest>
<requestId>1</requestId>
<requestDateTime>2020-01-15T15:00:00</requestDateTime>
<protocol>bimo v1</protocol>
<testDataMarker>true</testDataMarker>
<data>test</data>
</ns1:getReportRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
此 xml 由 SoapClient 类自动生成。最终,此请求会导致身份验证错误,因为我不知道您的凭据。但是现在你知道了,如何在不编写任何 xml 的情况下使用 php 原生 PHP 类发送和接收数据。
希望这对您有所帮助。