SOAP-ERROR:编码:违反编码规则?

时间:2009-08-20 23:59:55

标签: php xml soap

伙计们,我被困住了,在过去的几个小时里,我把头从桌子上敲下来。

我正在尝试使用一个服务,并且我有8个其他函数,我称之为本质上几乎是IDENTICAL,但是这个函数导致'SOAP-ERROR:编码:违反编码规则'错误

继承函数调用(为安全起见省略了wsdl):

    function CanLoadProduct($data){

    $client = new SoapClient('wsdl-url');

    $params = array('username'   => $this->username,
                    'password'  => $this->password,
                    'prod'      => $data['productid'],
                    'mdn'       => $data['mdn']);

    try {
        $reply = $client->__soapCall("CanLoadProduct", $params);
    } catch (Exception $e) {
        echo 'Error: ',  $e->getMessage(), "\n";
        print_r($params);
        die();
    }

    if( $reply['result'] == 1 ){
        return TRUE;        // 1 = true
    } else {
        return FALSE;
    }

}

好的,这个函数连接到webservice,所需的元素是: 用户名,密码,prod,mdn,我提供的所有4个作为$ params数组的一部分。用户名/传递是先前定义的,并且工作正常,因为其他8个函数使用Web服务没有任何问题。

$ data []数组(我传递给函数)包含: $数据[ '的productid'] $数据[ 'MDN'] 没有别的用了。

我正在

SOAP-ERROR: Encoding: Violation of encoding rules

由于一些无法解释的原因,谷歌搜索这个错误让我无处可去。其他人遇到这个?运行PHP 5.2.9-2。奇怪的是,这与100%工作的这个功能相同:

    function GetPIN($productid){

    $client = new SoapClient('wsdl-url');

    $params = array('username'  => $this->username,
                    'password'  => $this->password,
                    'prod'      => $productid);

    try {
        $reply = $client->__soapCall("GetPIN", $params);
    } catch (Exception $e) {
        echo 'Error: ',  $e->getMessage(), "\n";
        die();
    }
        return $reply;
}

这是WSDL(应该首先发布):

<?xml version="1.0" encoding="ISO-8859-1"?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:tns="ready:test" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="ready:test">
<types>
<xsd:schema targetNamespace="ready:test"
>
 <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
 <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
</xsd:schema>
</types>
<message name="CanLoadProductRequest">
  <part name="username" type="xsd:string" />
  <part name="password" type="xsd:string" />
  <part name="prod" type="xsd:string" />    
  <part name="mdn" type="xsd:string" />
  <part name="esn" type="xsd:string" /></message>
<message name="CanLoadProductResponse">
  <part name="result" type="xsd:int" /></message>
<portType name="CanLoadProductPortType">
  <operation name="CanLoadProduct">
    <input message="tns:CanLoadProductRequest"/>
    <output message="tns:CanLoadProductResponse"/>
  </operation>
</portType>

<binding name="CanLoadProductBinding" type="tns:CanLoadProductPortType">
  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="CanLoadProduct">
    <soap:operation soapAction="{url-removed}" style="rpc"/>
    <input>
        <soap:body use="encoded" namespace="" 
           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    </input>
    <output>
        <soap:body use="encoded" namespace="" 
            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
    </output>
  </operation>
</binding>
<service name="CanLoadProduct">
  <port name="CanLoadProductPort" binding="tns:CanLoadProductBinding">

    <soap:address location="{url-removed}"/>
  </port>
</service>
</definitions>

11 个答案:

答案 0 :(得分:16)

看起来你的某个类型不匹配,无论是在组装你的请求时(其中一个参数不是string类型),或者服务器返回的不是int(违反了WSDL响应定义,从而导致了客户端)认为响应无效,因为它需要其他东西)。

  • 要测试第一种情况,请确保将所有参数转换为字符串
  • 要测试第二种情况,请创建SoapClient,并将 trace 选项设置为true,以便之后通过$ client-&gt; __ getLastResponse()从服务器访问实际的XML答案(您也可以通过__getLastRequest())将其用于请求调试。

其他一些意见/问题:

  • 根据发布的WSDL,'CanLoadProductRequest'有第五个参数'esn',您不能在函数调用中提供。
  • 您使用$client->__soapCall("CanLoadProduct", $params)代替$client->CanLoadProduct($username, $password, etc.)的任何理由? (第一个版本是较低级别的变体,旨在用于非WSDL方案。第二个版本可能会为您提供更详细的错误/异常)
  • 您可以通过其他方式测试对CanLoadProductRequest的SOAP调用吗?错误可能在服务器端,尝试返回不符合WSDL定义的结果类型。

答案 1 :(得分:6)

我遇到了同样的问题。

在soapUI首选项中,我选中了首选项→编辑器设置→验证响应选项,我收到了以下信息:

  

第3027行:十进制值无效:意外字符'44'。

这解决了我的问题。字段包含错误的类型值。

答案 2 :(得分:2)

尝试将XML作为参数传递给我的某个webservices时遇到了同样的问题。在<![CDATA[ ... ]]>中包装XML数据摆脱了 SOAP-ERROR:编码:违反编码规则,一切正常。

其他细节:
1.参数也被定义为xsd:string 2. WSDL是document / literal 3.使用带有php 5.2.10的内置SOAP类。

答案 3 :(得分:2)

我使用SoapUI工具收到此错误,直到我使用真实测试数据重新格式化响应,而不仅仅是'?'。此外,对于SoapUI,响应可能超出预期,并且可能必须通过删除若干可选响应参数来缩短到预期响应。希望这有帮助吗?

答案 4 :(得分:2)

我遇到了同样的问题,我解决了__soapCall的这种语法:

...
$params = new SoapParam($data, 'parameters');

$response = $this->__soapCall('methodName', 
    array(new SoapVar($data, XSD_ANYTYPE, 'parameters'))
  );        
...

而不是

__soapCall('methodName', array($params)

答案 5 :(得分:1)

在PHP中还存在一种错误,其中错误的类型没有留下将适当的SOAPfault返回给客户端的空间。

http://bugs.php.net/bug.php?id=50547

答案 6 :(得分:1)

<![CDATA[<?xml version="1.0"
encoding="utf-8"?>
<CONTENTXML></CONTENTXML]]></xmlCallString>]]>

答案 7 :(得分:0)

我遇到了同样的问题,并设法通过更正WSDL来修复它,假设服务器将为特定值发送一个整数,但实际上是在发送一个字符串。也许修改WSDL:

<part name="result" type="xsd:int" /></message>

<part name="result" type="xsd:string" /></message>

可以解决您的问题,以下是我所遇到的特定案例的一些信息:https://blog.dotnetframework.org/2016/12/06/uncaught-soapfault-exception-sender-soap-error-encoding-violation-of-encoding-rules/

答案 8 :(得分:0)

我在进行单元测试时在PhpStorm中遇到过这个问题。我禁用了wsdl缓存并且它工作正常: ini_set(“soap.wsdl_cache_enabled”,“0”);

答案 9 :(得分:0)

与@bezz类似,我的问题也是由WSDL缓存在临时目录中引起的。

我清除了/ tmp中的wsdl- *文件,并且可以正常工作。

答案 10 :(得分:0)

如果将PHP版本升级到7.3或更高版本,则先前的WSDL缓存可能会停止工作。

默认安装目录为/tmpdisabling cache or deleting the wsdl* cache files应该可以解决此问题。我建议您清除缓存,否则您的服务器每次都会拉WSDL(这可能是不希望的)。