我有一个SoapClient的呼叫的响应的PHP解析麻烦。对于某些类型的答案,它是空的stdClass已经返回阵列对象,而不是初始化stdClass的对象。

在服务器部署上的tomcat6 Axis2的一个Java web服务。有问题的服务调用的Java的签名是public Course getCourseDetails(Long courseId)场定义为标准POJO:

public class Course {
    private Long id;
    private List<Hole> holes;
    private String name;
    private String tees;

    //etc...
}

孔与只灵长类动物的成员标准POJO。

当用PHP叫,孔构件是具有正确长度的阵列,但每个孔是空的。

$args = array();
$args["courseId"] = $courseId;
$response = $client->getCourseDetails($args);
$course = $response->return;
//course has all of its primitive members set correctly: good
$holes = $course->holes;
//holes is an array with count = 18: good
$hole = $holes[0];
//hole is an empty stdClass: bad

打印出与$soapClient->__getLastResponse()返回的XML是什么样子的正确表示:

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getCourseDetailsResponse xmlns:ns="http://webservice.golfstats">
<ns:return xmlns:ax21="http://datastructures.server.golfstats/xsd" xmlns:ax22="http://util.java/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ax24="http://uuid.eaio.com/xsd" xsi:type="ax21:Course">
<ax21:courseLocation>Faketown, VA</ax21:courseLocation>
<ax21:courseName>Fake Links</ax21:courseName>
<ax21:dateAdded>2003-01-02</ax21:dateAdded>
<ax21:holes><ax21:id>1</ax21:id><ax21:number>1</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>2</ax21:id><ax21:number>2</ax21:number><ax21:par>3</ax21:par><ax21:yardage>150</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>3</ax21:id><ax21:number>3</ax21:number><ax21:par>5</ax21:par><ax21:yardage>502</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>4</ax21:id><ax21:number>4</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>5</ax21:id><ax21:number>5</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>6</ax21:id><ax21:number>6</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>7</ax21:id><ax21:number>7</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>8</ax21:id><ax21:number>8</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>9</ax21:id><ax21:number>9</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>10</ax21:id><ax21:number>10</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>11</ax21:id><ax21:number>11</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>12</ax21:id><ax21:number>12</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>13</ax21:id><ax21:number>13</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>14</ax21:id><ax21:number>14</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>15</ax21:id><ax21:number>15</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>16</ax21:id><ax21:number>16</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>17</ax21:id><ax21:number>17</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:holes><ax21:id>18</ax21:id><ax21:number>18</ax21:number><ax21:par>4</ax21:par><ax21:yardage>345</ax21:yardage></ax21:holes>
<ax21:id>1</ax21:id>
<ax21:rating>68.5</ax21:rating>
<ax21:slope>113</ax21:slope>
<ax21:tees>Blue</ax21:tees>
</ns:return>
</ns:getCourseDetailsResponse>
</soapenv:Body>
</soapenv:Envelope>

为什么每个洞空stdClass的?是否有已知限制到SoapClient的将解析的响应电平的数目?

有帮助吗?

解决方案 3

这似乎是在PHP的错误。 http://bugs.php.net/bug.php?id=49070

不幸的是,bug跟踪系统不会让我评论它。

其他提示

我也有类似的问题。我通过你经历的每一次迭代去了。在侥幸我禁用缓存“soap.wsdl_cache”通过更改php.ini文件或ini_set('soap.wsdl_cache', WSDL_CACHE_NONE);和我的下一个请求中的所有丢失的数据填充。这可以很容易发生,因为“soap.wsdl_cache_ttl”被设定为“86400”,默认情况下,这是60天。

我发现了什么是SOAP服务器有一个代码更改。创建一个新的WSDL。客户端的缓存WSDL是在这一点陈旧。你可能会认为,至少,某种形式的的校验和会出去与每个请求,验证WSDL已经改变,但事实并非如此。

要解决此问题,并仍然使用缓存我创建了一个WSDL文件,我可以在本地消费。

    $cache = Services_Utilities::getCacheResource();
    if (!$cache->test(self::CACHE_KEY)) {
        $data = file_get_contents($wsdl);
        $cache->save($data, self::CACHE_KEY);
        file_put_contents($newWsdl, $data);
        if (file_exists($newWsdl)) {
            $wsdl = $newWsdl;
        }
    } else {
        if (file_exists($newWsdl)) {
            $wsdl = $newWsdl;
        }
    }

    // Remove $newWsdl when necessary
    // unset($newWsdl);

希望这有助于你或其他人恰巧路过和有类似的问题。

你推测出这一切由调试或打印出PHP对象的内容(的print_r,的var_dump)?

您是否尝试打印出实际的SOAP响应字符串(不是PHP对象)?你可以通过调试选项集创建SoapClient的做到这一点:

$soapClient = new SoapClient( "http://your.soap.server.com/services/yourWsdl.wsdl", array("trace" => 1));

然后,当您使用客户端,让您的SOAP调用,您可以看看的请求和响应串两者。

$response = $soapClient->getCourseDetails($params);
$requestAsString = $soapClient->__getLastRequest();
$responseAsString = $soapClient->__getLastResponse();

这可能会帮助你找出当它转换为PHP对象的响应什么SoapClient的是做。 上__getLastResponse更多信息()

在这里,我们走了近一年半的时间过去了......

在我最近的半类似的经验,这不是一个PHP错误。这是与方式的问题,你的web服务的书面和PHP如何读取输出。我正经历着类似的问题(甚至下降到使用getLastResponse返回正确的XML),来到发现它是没有这么多PHP或SOAP我的功能有一个问题,但“破”函数的结果不是一个明确定义光标。

坏光标定义的示例:

PROCEDURE GetBlahByBlahID(IN IN_BLAH_ID VARCHAR, IN IN_BLAHPKG VARCHAR,                                     
OUT result CURSOR
) BEGIN ...

好光标定义的示例:

PROCEDURE GetBlahByBlahID(IN IN_BLAH_ID VARCHAR, IN IN_BLAHPKG VARCHAR,                                     
OUT result CURSOR (  BLAH VARCHAR(250),
                     BLAH2 VARCHAR(250),
                     BLAH_DATE DATE,
                     BLAH3 VARCHAR(250))) BEGIN ...

显然,Java可以处理的“坏” /无明确的输出就好了,但PHP返回null对象的数组。

不知道这是否会帮助你,但定义Web服务功能输出上面的“好”办法固定我的问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top