Soap запросов с PHP на самом деле довольно просты, если вы следуете веб-стандарту. Класс PHP SoapClient
предназначен для всего, что вам нужно. Если вы работаете только с объектами, полученными из файла WSDL, это становится довольно просто.
Вы на правильном пути. Первым шагом должно быть определение функций и типов данных из файла WSDL. Вы сделали это уже с помощью функций $client->__getFunctions()
и $client->__getTypes()
.
ResponseMessage getReport(RequestMessage $getReportRequest)
Это дает следующую информацию. Если вы хотите вызвать функцию getReport веб-службы, вы должны использовать в запросе объект RequestMessage
и получить объект ResponseMessage
в качестве ответа. Так где же взять эти методы? Эта информация записана в связанном XSD-файле , или вы также можете использовать функцию $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 с методами получения и установки для свойств класса. Свойства точно такие же, как указано в информации о структуре. Вы можете сделать это для всех структур, которые возвращает функция $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. Это позволяет вам ловить ошибки. Опция трассировки позволяет получить отправленный запрос и полученный ответ xml. Опция classmap
содержит типы xsd, которые мы получили от функции $client->__getTypes()
. Карта классов позволяет клиенту soap сопоставлять типы с классами объектов-значений.
Как известно, для функции веб-службы getReport
в качестве параметра требуется объект 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
класс. В конечном итоге этот запрос приводит к ошибке аутентификации, поскольку я не знаю ваших учетных данных. Но теперь вы знаете, как отправлять и получать данные с php нативными PHP классами без записи xml.
Надеюсь, это вам немного помогло.