1

我正在使用 Zend_Soap_Server 在 PHP 中使用自动发现模式创建 Web 服务,我想知道如何使用 phpDoc 或任何其他方式在特定变量/函数参数上生成限制(minOccurs,maxOccurs)。

像下面这样,当我在一个函数上使用这个 phpDoc 时myFunction

 /**
 *
 * @param   string $param1  Parameter One
 * @param   string $param2  Parameter Two
 * @return  array  $return
 */

它在 WSDL 中给了我以下消息:

<message name="myFunctionIn">
  <part name="param1" type="xsd:string"/>
  <part name="param2" type="xsd:string"/>
</message>
<message name="myFunctionOut">
  <part name="return" type="soap-enc:Array"/>
</message>

因此,如果我想限制函数 params( param1& param2) 的使用minOccursmaxOccurs我该怎么做才能使 WSDL 消息如下所示:

 <message name="myFunctionIn">
  <part name="param1" minOccurs="0" maxOccurs="1" type="xsd:string"/>
  <part name="param2" minOccurs="1" maxOccurs="1" type="xsd:string"/>
 </message>

我在互联网上搜索过,但找不到任何有用的信息。谢谢!

4

4 回答 4

1

如果有些人仍然感兴趣……这里的 zend 框架邮件列表上发布了一个相当简单的补丁。它允许以以下样式定义 minOccurs 和 maxOccurs:

/** 
* @var string ___FOR_ZEND_minOccurs=0 ___FOR_ZEND_maxOccurs=1 
*/ 
public $Username;

在 WSDL 中被翻译为:

<xsd:element name="Username" type="xsd:string" nillable="true" maxOccurs="1" minOccurs="0"/>

需要在第 58 行之后插入必要的代码更改,如下所示:

($element->setAttribute('type', $this->getContext()->getType(trim($matches[1][0])));)

要插入的代码:

$tempo = $property->getDocComment(); 
if (preg_match('/___FOR_ZEND_minOccurs\s*=\s*(\d+|unbounded)/',$tempo,$matches)) { 
    $element->setAttribute('minOccurs', $matches[1]); 
} 
if (preg_match('/___FOR_ZEND_maxOccurs\s*=\s*(\d+|unbounded)/',$tempo,$matches)) { 
  $element->setAttribute('maxOccurs', $matches[1]); 
}

显然,如果您喜欢不同的定义模式,您可以调整这些正则表达式。

于 2016-05-01T18:36:02.997 回答
1

如果这仍然与某人相关:一种更简洁的方法可能是实现一个自定义策略类来构建复杂的类型定义——这实际上是 Zend_Soap 官方支持的。

这样做,创建一个继承自 Zend_Soap_Wsdl_Strategy_ArrayOfTypeSequence 的类(参考 ZF 1.x,但在较新的框架版本中看起来相似,只是命名空间)。

在您的新类中,通过从父类复制整个方法体来重载 _addElementFromWsdlAndChildTypes 方法。

现在,您可以通过为给定的 $childTypeName 创建反射对象来开始操作代码并添加 docblock 解析器:

// add the following after 
// $element = $dom->createElement('xsd:element');
$strippedTypeName = substr($childTypeName, 4); // strip xml namespace
$reflect = new \Zend_Reflection_Class($strippedTypeName);
if ($reflect->getDocblock()->hasTag('myTagName')) {
   $tagValues = $reflect->getDocblock()->getTags('myTagName');
   // do whatever you want with your attribute values and then
   // add them to the XML element:
   $element->setAttribute($attributeName, $attributeValue);
}

完成后,您可以在创建 AutoDiscover 实例时将新类设置为类型策略:

new Zend_Soap_AutoDiscover(
    'MyNewStrategyClass', $namespace
);

你完成了。现在,每当您有一个定义复杂类型的类时,该类应该具有自定义 minOccurs、maxOccurs 或任何其他设置,您可以使用 @myTagName 标记和您喜欢定义属性值的任何语法来注释该类,例如

/**
 * MyCustomType DocBlock description
 * @myTagName minOccurs=0
 * @myTagName maxOccurs=10
 */
class MyCustomType { ... }

希望这可以帮助某人。

于 2017-05-09T15:11:24.960 回答
0

在最近的一个项目中,我一直在寻找这个问题的答案。据我所知,这在当前版本的 ZF 中是不可能的(参见“错误”)。

我认为 AutoDiscovery 仅适用于最基本的 WSDL 生成。或者至少当前版本是。也许未来的版本会更全面。

这是一个很好的起点,您可以使用模板手动构建更复杂的约束。或者,您可以构建自己的课程来处理您的特定要求(如该问题答案的评论中所建议)

于 2012-07-18T20:29:40.720 回答
0

我发现了一个提案,其中包括针对复杂类型的修改代码,但我不确定它是否曾经实现过,而且我还没有机会对其进行测试。查看:

http://framework.zend.com/wiki/display/ZFPROP/Zend_Soap_Wsdl_Strategy_DefaultComplexType+-+Improvement+for+the+AutoDiscover+-+Jeannie+BOFFEL

于 2014-06-25T16:47:01.267 回答