【问题标题】:PHP SOAPCall null resultPHP SOAPCall 空结果
【发布时间】:2015-05-20 18:53:43
【问题描述】:

我已经使用 AXIS 部署了一个 SOAP WS。我在 Ubuntu 14.04 上使用 SOAPClient 库和 PHP 5.5.9 来调用公开的操作,但是当我进行“__SoapCall”时它什么也不返回。我也尝试过使用“NuSOAP”库,但我得到了相同的结果。 但是当我调用“__getLastResponse”时,它会返回良好的响应(虽然重复),如您所见:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <idXMLReturn xmlns="http://aemetproyecto">PD94bWwgdm...</idXMLReturn>
    </soapenv:Body>
</soapenv:Envelope>

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <idXMLReturn xmlns="http://aemetproyecto">PD94bWwgdm...</idXMLReturn>
    </soapenv:Body>
</soapenv:Envelope>

Here is the WSDL

我的 PHP 代码:

<?php

    function generarTabla($id, $formato){
        try{

            // Create the SoapClient instance 
            $url = "http://localhost:8080/axis/services/AemetProyect?wsdl";

            $client = new SoapClient($url, array("trace" => 1, "exception" => 1));

            // Creo XML
            $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
            $xml .= "<!DOCTYPE id [\n";
            $xml .= "<!ELEMENT id (#PCDATA)>\n";
            $xml .= "]>\n";
            $xml .= "<id>".$id."</id>";

            // Codifico XML en Base64
            $Base64xml = base64_encode($xml);

            // Llamada SOAP a DescargarInfoTiempo
            $resultado = $client -> __soapCall("DescargarInfoTiempo",
                                                array($Base64xml));

            //$resultado = $client -> __getLastResponse();
            //echo $resultado;
            //$resultado = $client -> __getLastRequest();
            //echo $resultado;

            echo $resultado;
        } catch (SoapFault $ex){
            $error = "SOAP Fault: (faultcode: {$ex->faultcode}\n"
                                ."faultstring: {$ex->faultstring})";
            echo $error;
        } catch (Exception $e){
            $error = "Exception: {$e->faultstring}";
            echo $error;
        }
    }

?>

我注意到返回元素的名称(“idXMLReturn”)与 WSDL 中描述的名称(“DescargarInfoTiempoReturn”)不同。 会不会是这个问题?

更新

我已经尝试过:

$argumens['idXML'] = $Base64xml;
$resultado = $client -> __soapCall("DescargarInfoTiempo",
                                                    array($arguments));

$arguments['idXML'] = $Base64xml;
$resultado = $client ->DescargarInfoTiempo($arguments);

但是当我调用时,我得到“注意:数组到字符串的转换”。

【问题讨论】:

  • 贴出你的PHP代码,让我们看看你有没有错误。

标签: php web-services soap wsdl axis


【解决方案1】:

你的错误有点详细。

对于使用 SoapClient 的调用,您必须以参数数组的形式发送参数,而不是发送 xml(为什么需要编码 base64?是您的 WebService 的一些规则吗?)。请参阅PHP docs 了解正确方法

参数 要传递给函数的参数数组。这可以是有序数组或关联数组。请注意,大多数 SOAP 服务器都需要提供参数名称,在这种情况下,这必须是关联数组。

所以,你的数组参数*必须是这样的:

$arguments['id'] = $id// if you need base 64, use base64_encode($id) or something
$resultado = $client -> __soapCall("DescargarInfoTiempo",array($arguments));

做同样事情的其他选项,是直接调用函数:

$arguments['id'] = $id// if you need base 64, use base64_encode($id) or something
    $resultado = $client ->DescargarInfoTiempo($arguments);// note that we don't need array($arguments), just $arguments

在文档页面的 cmets 中查看其他示例。

最后,如果您仍想创建要发送的 XML,我建议您使用其他方法,例如 file_get_contents 或 CURL,并且不要忘记使用肥皂信封创建 XML,这是 Soap Protocol 所必需的

*一些旧的 WebServices 需要一个名为“parameters”的数组

更新

看,您正试图将您的 $arguments 发送到一个仅包含一个元素的数组中:您的 $Base64xml var 中的 XML。我认为问题仍然存在。

根据PHP manual您无法在 SoapCall 中发送 XML。 var 必须是 与您的 var 关联的数组,因此请尝试执行以下操作:

$arguments['id'] = $id// this $id var is your function argument(int, string or somenthing else), forget the created XML
    $resultado = $client -> __soapCall("DescargarInfoTiempo",array($arguments));

关于你需要的base64,我以前从来没有用过,但是看PHP manual这个页面的marcovtwout评论

如果您的 WSDL 文件包含具有 base64Binary 类型的参数,则在传递您的肥皂变量时不应使用 base64_encode()。发出请求时,SOAP 库会自动对您的数据进行 base64 编码,否则您将对其进行两次编码。

所以,我相信您不需要对变量进行编码。

简而言之,忘记 XML 并只发送您的变量。 PHP SoapClient 使用正确的编码和所有这些东西创建 Soap 信封。

如果您在执行此操作时仍然遇到问题,请尝试在您的 var 后面加上一些 SoapVars。也许您的 WSDL 配置需要这种处理。

希望对你有帮助

【讨论】:

  • 首先,我需要进行 Base64 编码,因为我使用的是 Document/literal 样式。如果我不对其进行编码,则肥皂信封将无效。我也可以使用 CDATA 字段。你的建议不起作用。我得到“注意:数组到字符串的转换”。我的称呼是正确的。问题在于它映射响应的时间。
  • @JavierTello 哪一行将通知返回给您?由于您的要求,我仍然认为您的回复不正确。如果可以,请更新您问题中的新代码,以便我们共同解决问题。
  • WSDL 不包含任何 base64 类型。所有请求和回复类型都是简单的字符串。我尝试调用的操作是“public String DescargarInfoTiempo(String idXML)”。我将尝试使用 CURL。非常感谢;)
【解决方案2】:

解决方案是指定文档文字样式,如 Creating a SOAP call using PHP with an XML body

【讨论】:

  • 但是我需要在 SOAP 正文中包含一个 DTD,所以您的解决方案对我无效。
  • 我建议根据 WSDL 进行验证。查看stackoverflow.com/a/14070848/4100071提供的指针
【解决方案3】:

正如我上面所说,“我注意到返回元素的名称(“idXMLReturn”)与 WSDL 中描述的名称(“DescargarInfoTiempoReturn”)不同” 所以,这就是问题所在:AXIS 不会生成适合 WSDL 模式的信封。似乎 java:RPC 提供者并不担心操作的返回名称。

现在,我通过将参数从“idXML”重命名为“DescargarInfoTiempo”解决了这个问题,因此 SOAP 响应将是“DescargarInfoTiempoReturn”,它符合 WSDL 模式,PHP 将映射正确响应。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 2011-08-21
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多