如何在函数phpDoc中为Zend_Soap_Server定义minOccurs和maxOccurs



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

如下所示,当我在函数myFunction上使用这个phpDoc时,

 /**
 *
 * @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>

因此,如果我想使用minOccursmaxOccurs来限制函数params(param1&param2),我该怎么做才能使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>

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

如果有些人仍然感兴趣。。。在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_minOccurss*=s*(d+|unbounded)/',$tempo,$matches)) { 
    $element->setAttribute('minOccurs', $matches[1]); 
} 
if (preg_match('/___FOR_ZEND_maxOccurss*=s*(d+|unbounded)/',$tempo,$matches)) { 
  $element->setAttribute('maxOccurs', $matches[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 { ... }

希望这能帮助到别人。

在最近的一个项目中,我一直在寻找这个问题的答案。据我所知,这在ZF的当前版本中是不可能的(请参阅"bug")。

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

它是一个很好的起点,您可以使用模板手动构建更复杂的约束。或者,您可以构建自己的类来处理您的特定需求(如本问题答案的注释中所建议的)

我发现有一个提议,其中包括一个针对复杂类型的修改代码,但我不确定它是否实现过,我还没有机会测试它。结账:

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

最新更新