duan_2000 2015-07-08 14:53
浏览 126
已采纳

PHP SoapServer(WSDL)如何将xml命名空间设置为项目而不是标题?

I have a tiny php soap server, that based on wsdl, and it serves DLNA requests. The server code looks like thousands of others:

$srv = new SoapServer( "wsdl/upnp_av.wsdl" );
$srv->setClass( "ContentDirectory" );
$srv->handle();

and it works. For the procedures it successfully returns SOAP responses:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:schemas-upnp-org:service:ContentDirectory:1">
<SOAP-ENV:Body>
<ns1:GetSearchCapabilitiesResponse>
<SearchCaps>*</SearchCaps>
</ns1:GetSearchCapabilitiesResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

And this is absolutely correct xml syntax. But most of my DLNA devices won't accept this answer (but Toshiba TV works very well with it). So I took Wireshark and traced xml from other DLNA servers, and figured out, that all of them return slightly another xml, with namespace defined at ns1 body, not in envelope. This is sample correct lines, that all devices accepting well:

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetSearchCapabilitiesResponse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1">
<SearchCaps>*</SearchCaps>
</u:GetSearchCapabilitiesResponse>
</s:Body>
</s:Envelope>

So the "ContentDirectory" xmlns just moved into a block from header. Both xmls are syntactically correct.

Some guys also faced same problem:

Problem with WSDL

change soap prefixes in php

Soap Response Namespace issue

SoapServer maps functions incorectly when the wsdl messages have the same part name

PHP Soap Server response formatting

After 2-days of research, I figured out this workaround, to change binding from document to rpc method:

<soap:binding style="document"   -->   <soap:binding style="rpc"

but when I doing this, the php script just crashes [somewhere inside of zend engine?], so I have a line in access.log mentioned 500 error happened, but it does not shown in error.log - the file keeps empty (of course, all the others 500 errors goes to error.log pretty well).

As it is too big, I have uploaded WSDL file: http://pastebin.com/ZNG4DqAn

Is there something else, that I can try to workaround this trouble?

Remember, that TV handles this xml syntax completely correct, and everything works very well, but probably android phones does other xml parser that requires namespace in that place? Just right now I am already ready to do preg_replaces() to move that damned xmlns to the correct place :), but I am thinking this is not a path for the Jedies :)

My environment: PHP 5.4.20, Apache 2.2, Windows 2012

  • 写回答

1条回答 默认 最新

  • drzfnr0275 2015-07-09 15:53
    关注

    Finally I will not become Jedi, I did manual replacement and it works.

    function replace_xmlns( $soapXml )
    {
    $marker1 = "xmlns:ns1=";
    $marker2 = "<ns1:";
    
    $startpos = strpos( $soapXml, $marker1 );
    $endpos   = strpos( $soapXml, "\"", $startpos + 14 );
    
    $namespace = substr( $soapXml, $startpos, $endpos - $startpos + 1 );
    $soapXml   = str_replace( $namespace, "", $soapXml );
    
    $m2start = mb_strpos( $soapXml, $marker2 );
    $m2end   = mb_strpos( $soapXml, '>', $m2start );
    
    $soapXml = substr_replace( $soapXml, " " . $namespace, $m2end, 0 );
    
    return $soapXml;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛