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;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥35 平滑拟合曲线该如何生成
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站