我尝试使用php实现webservice客户端并被卡住了... 我使用名为metadataservice的现有Web服务和已知的wsdl。 我将使用wsdl2phpgenerator为数据类型和服务本身创建php类。 使用其中一个Web服务方法(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来监控到Soap服务器的流量,是的....根据StringAsset Info Class中的定义,没有任何值......这是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>
我希望标签新标题名称。但是不见了。当我检查我的代码中的$ NewMetaData对象或$ Service-&gt; addMetadataToObject中的$ Parameter对象时,我可以看到属性&#34; Value&#34;已定义和设置。 对我来说似乎是对
的呼唤返回$ this-&gt; __ soapCall(&#39; addMetadataToObject&#39;,array($ parameters));
只接受基类AssetInfo的属性,但不接受派生类StringAssetInfo中的属性。 我还将代码更改为使用$ AssetInfo的数组(而不是对象):
$AssetInfo = array("dataFieldId"=>2, "dataFieldName"=>"TitleName","dataFieldTagName"=>"TitleName, "value"=>"New Title Name");
但没有任何改变。看来我们在这里有一些运行时类型转换或类型对齐但我无法看到这个的原因。我根本不是网络服务的新手,也是php的新手(但是我必须同时使用这两个: - )
有人可以评论或暗示我在这里发生了什么吗?
答案 0 :(得分:0)
我能够通过使用数组和soapvars来实现它,请注意我在代码中的注释:
$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 Body中的预期输出(并且还在Soap信封中添加了一些命名空间
<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>