Question

Je ne parviens pas à avec l'analyse syntaxique PHP de la réponse d'un appel SoapClient. Pour certains types de réponses, il est de retour des tableaux d'objets stdClass vide au lieu d'objets StdClass initialisés.

Le serveur est un webservice Java déployé avec axis2 sur tomcat6. La signature Java de l'appel de service est problématique public Course getCourseDetails(Long courseId) Cours est un POJO standard défini comme:

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

    //etc...
}

Hole est un POJO standard avec seulement les membres primative.

Lorsqu'il est appelé avec PHP, l'élément de trous est un tableau à la bonne longueur, mais chaque trou est vide.

$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

Impression sur le XML retourné avec $soapClient->__getLastResponse() ce qui ressemble à la représentation correcte:

<?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>

Pourquoi chaque trou un stdClass vide? Y at-il des limites connues du nombre de niveaux SoapClient analysera une réponse?

Était-ce utile?

La solution 3

Cela semble être un bogue dans PHP. http://bugs.php.net/bug.php?id=49070

Malheureusement, le bug tracker ne me laisse pas commenter.

Autres conseils

J'ai eu un problème similaire. Je suis passé par chaque itération vous avez traversé. Sur un coup de chance, je cache désactivé « soap.wsdl_cache » en changeant le fichier php.ini ou ini_set('soap.wsdl_cache', WSDL_CACHE_NONE); et sur ma prochaine demande toutes les données manquantes ont été peuplées. Cela peut facilement se produire parce que le « cache soap.wsdl_cache_ttl » est réglé sur « 86400 », par défaut, qui est de 60 jours.

Ce que j'ai découvert était que le serveur de savon a eu un changement de code. Création d'un nouveau fichier WSDL. Le cache wsdl du client était vicié à ce moment-là. On pourrait penser que, au moins, un hachage de contrôle d'une sorte irait avec chaque demande pour vérifier que le wsdl avait changé, mais il ne fonctionne pas.

Pour résoudre ce problème et toujours utiliser la mise en cache, j'ai créé un fichier wsdl que je pouvais consommer localement.

    $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);

Espérons que cela vous aide ou quelqu'un d'autre qui arrive à arrêter et avoir un problème similaire.

Avez-vous tout cela figure par le débogage ou l'impression du contenu de l'objet PHP (print_r, var_dump)?

Avez-vous essayé l'impression de la chaîne de réponse SOAP réelle (et non l'objet PHP)? Vous pouvez le faire en créant le SoapClient avec l'option de débogage série:

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

Ensuite, lorsque vous utilisez le client pour effectuer votre appel SOAP, vous pouvez jeter un oeil à la fois la demande et les chaînes de réponse.

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

Cela pourrait vous aider à comprendre ce que SoapClient fait quand il est la conversion de la réponse à un objet PHP. Plus d'info sur __getLastResponse () .

Ici, nous allons près d'un an et demi plus tard ...

Dans ma récente expérience semi-même ce n'était pas un bug php. Il est une question liée à la façon dont votre webservice est écrit et comment PHP lit la sortie. Je ressentais un problème similaire (même jusqu'à getLastResponse retourner le code XML correct) et est venu à constater que ce n'était pas tellement PHP ou ma fonction SOAP qui avait un problème, mais que le résultat de la fonction « cassé » était pas explicitement curseur défini.

Exemple de mauvaise définition du curseur:

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

Exemple de bonne définition du curseur:

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 ...

Apparemment Java peut gérer le « mauvais » / non sortie explicite très bien, mais PHP retourne un tableau d'objets nuls.

Je ne sais pas si cela vous aidera, mais la définition de la sortie de la fonction de service Web comme le moyen « bon » fixé au-dessus de mon problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top