PHP Soap Client не отправляет все свойства объекта при вызове веб-сервиса - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь реализовать клиент веб-сервиса с использованием php и застрял ... Я использую существующий веб-сервис под названием metadataservice с известным wsdl.Я буду использовать wsdl2phpgenerator для создания классов php для типов данных и самой службы.Используя один из методов веб-сервиса (addMetadataToObject), я должен отправить массив объектов на сервер.Существует базовый класс:

class AssetInfo
{
    public $dataFieldId = null;
    public $dataFieldName = null;
    public $dataFieldTagName = null;
    public function __construct($dataFieldId, $dataFieldName, $dataFieldTagName)
    {
      $this->dataFieldId = $dataFieldId;
      $this->dataFieldName = $dataFieldName;
      $this->dataFieldTagName = $dataFieldTagName;
    }
}

и производный класс, содержащий строковые значения (есть также другие производные классы для Longs и т. Д.):

class StringAssetInfo extends AssetInfo
{
    public $value = null;
    public function __construct($dataFieldId, $dataFieldName,$dataFieldTagName, $value)
    {
      parent::__construct($dataFieldId, $dataFieldName, $dataFieldTagName);
      $this->value = $value;
    }
}

Для вызова Metadataservice-> addMetadataToObject также определен addMetadataToObject:

class addMetadataToObject
{
    public $objectId = null;
    public $objectType = null;
    public $assetInfos = null;
    public function __construct($objectId, $objectType)
    {
      $this->objectId = $objectId;
      $this->objectType = $objectType;
    }
} 

Свойство $ assetInfos должно содержать массив объектов AssetInfo.wdsl2phpgenerator создает класс для моего MetadataService, который является производным от SoapClient.Этот класс предоставляет все доступные методы для этой службы.Здесь я только показываю метод addMetadataToObject:

public function addMetadataToObject(addMetadataToObject $parameters)
{
  return $this->__soapCall('addMetadataToObject', array($parameters));
}

Мой код выполняет:

// Define the Data    
$ServiceOptions = [];
    $AssetInfos = [];
    $AssetInfo = new StringAssetInfo(2, "TitleName", "TitleName","New Title Name);        
    array_push($AssetInfos, $AssetInfo);

// Create the Service
    $Service = new MetadataService($ServiceOptions, getServiceWSDL($Options, "MetadataService"));
    $Service->__setSoapHeaders(getGalaxySoapHeader($Options));
    $NewMetaData = new addMetadataToObject(61755, "ASSET");
    $NewMetaData->assetInfos = $AssetInfos;

// Call the Service
    $failedAssets = $Service->addMetadataToObject($NewMetaData);

Вызов вызывает исключение Soap, что значение не может быть извлечено.Что заставляет меня задуматься.Я начал отслеживать трафик к серверу мыла с помощью wireshark и да .... больше нет значения, определенного в информационном классе StringAsset ... Вот тело мыла, показанное wireshark:

<SOAP-ENV:Body>
    <ns1:addMetadataToObject>
        <objectId>61755</objectId>
        <objectType>ASSET</objectType>
        <assetInfos>
            <dataFieldId>2</dataFieldId>
            <dataFieldName>TitleName</dataFieldName>
            <dataFieldTagName>TitleName</dataFieldTagName>
        </assetInfos>
    </ns1:addMetadataToObject>
Id</SOAP-ENV:Body>

Я бы ожидал тэг New Title Name.Но это не прошло.Когда я проверил объект $ NewMetaData в своем коде или объект $ Parameter в $ Service-> addMetadataToObject, я вижу, что свойство «Значение» определено и установлено.Мне кажется, что вызов

возвращает $ this -> __ soapCall ('addMetadataToObject', array ($ parameters));

принимает только свойства базового класса AssetInfo, но не принимаетсвойства из производного класса StringAssetInfo.Я также изменил код, чтобы использовать массив (вместо объекта) для $ AssetInfo:

$AssetInfo =  array("dataFieldId"=>2, "dataFieldName"=>"TitleName","dataFieldTagName"=>"TitleName, "value"=>"New Title Name"); 

Но без каких-либо изменений.Кажется, что у нас есть некоторые виды преобразования типов во время выполнения или выравнивания типов, но я не вижу причины этого.Я все еще плохо знаком с веб-сервисами, а также с php (однако я должен использовать оба для Момента: -)

Кто-нибудь может прокомментировать или дать подсказку, что здесь происходит?

1 Ответ

0 голосов
/ 26 апреля 2018

Я смог реализовать это, используя массивы и мыльные переменные. Обратите внимание на мои комментарии в коде:

$ServiceOptions = [];
    $AssetInfos = [];

// I have to use an Array because the Server depends on the order of the properties. I wasn't able to define expected order using the existing objects but with arrays
    $AssetInfo =  array("dataFieldId"=>2, "dataFieldName"=>"TitleName","dataFieldTagName"=>"TitleName, "value"=>"New Title Name");        

// instead of pushing the Array directly, I create an instance of an SoapVar, pass the Array as data and set the Encoding, the expected type and the Namespace uri
array_push($AssetInfos, new SoapVar($AssetInfo, SOAP_ENC_OBJECT, "StringAssetInfo", "http://metadataservice.services.provider.com"));
    array_push($AssetInfos, $AssetInfo);

// Create the Service
    $Service = new MetadataService($ServiceOptions, getServiceWSDL($Options, "MetadataService"));
    $Service->__setSoapHeaders(getGalaxySoapHeader($Options));
    $NewMetaData = new addMetadataToObject(61755, "ASSET");
    $NewMetaData->assetInfos = $AssetInfos;

// Call the Service
    $failedAssets = $Service->addMetadataToObject($NewMetaData);

Это дало ожидаемый результат в теле мыла (а также добавило некоторые пространства имен в мылоконверт

<SOAP-ENV:Body>
    <ns1:addMetadataToObject>
        <objectId>61755</objectId>
        <objectType>ASSET</objectType>
        <assetInfos xsi:type="ns1:StringAssetInfo">
            <dataFieldId>2</dataFieldId>
            <dataFieldName>TitleName</dataFieldName>
            <dataFieldTagName>TitleName</dataFieldTagName>
            <value>New Titel Name 1146</value>
        </assetInfos>
    </ns1:addMetadataToObject>
</SOAP-ENV:Body>
...