PHP SOAP服务返回中<被转义为<的问题求助
解决PHP SOAP响应中CDATA被转义或结构错乱的问题
问题分析
- 你的WSDL将
description定义为xsd:string类型,PHP SOAP扩展会自动转义XML特殊字符(<>会变成<>),导致手动添加的<![CDATA[]]>被转义成<![CDATA[...]]>。 - 使用
XSD_ANYXML类型时,PHP会将内容作为原始XML直接插入,跳过description标签的包裹,破坏了SOAP响应的结构。
解决方案
方案1:修改WSDL定义(优先推荐,若有权限修改)
将description的类型从xsd:string改为xs:any或xsd:anyType,让字段支持原始XML内容:
<xs:schema xmlns:xs='xyz' xmlns:xsd='abc'> <xs:complexType name="data"> <xs:element name='name' type='xsd:string' /> <!-- 修改description的类型 --> <xs:element name='description' type='xs:any' /> <xs:element name='location' type='xsd:string' /> .... </xs:complexType> </xs:schema>
然后在PHP中用XSD_ANYXML类型的SoapVar包裹CDATA内容:
$this->description = new SoapVar("<![CDATA[".$res['info']."]]>", XSD_ANYXML);
这样SOAP响应会正确将CDATA包裹在description标签内,且不会转义CDATA的标记。
方案2:不修改WSDL的情况下构造CDATA
如果无法修改WSDL(比如对接第三方服务),可以通过DOMDocument创建CDATA节点,再转换为SoapVar:
// 创建DOM文档并生成CDATA节点 $dom = new DOMDocument(); $cdataNode = $dom->createCDATASection($res['info']); // 将CDATA节点转为SoapVar,类型指定为XSD_ANYXML $this->description = new SoapVar($cdataNode, XSD_ANYXML);
这种方式会让PHP SOAP扩展将CDATA节点正确插入到description标签中,即使WSDL定义的是xsd:string,也能避免内容被转义。
注意事项
- 不要手动将
<![CDATA[]]>作为字符串传入XSD_STRING类型的字段,否则SOAP扩展会自动转义其中的XML特殊字符。 - 使用
XSD_ANYXML时,确保传入的内容是合法的XML片段,否则会导致SOAP响应格式错误。
内容的提问来源于stack exchange,提问作者user22733493
相关产品推荐
相关产品推荐

