Domanda

Ho problemi con PHP analisi della risposta di una chiamata SoapClient. Per alcuni tipi di risposte, è ritorno array di stdClass vuoto oggetti anziché oggetti stdClass inizializzati.

Il server è un webservice java schierato con axis2 su tomcat6. La firma Java della chiamata di servizio problematico è corso public Course getCourseDetails(Long courseId) è un POJO standard definito come:

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

    //etc...
}

Hole è un POJO serie con solo i membri primative.

Quando chiamato con PHP, l'organo di fori è un array con la lunghezza corretta, ma ogni foro è vuoto.

$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

Stampa della XML restituito con $soapClient->__getLastResponse() quello che sembra la rappresentazione corretta:

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

Perché ogni buca uno stdClass vuoto? Ci sono noti limiti al numero di livelli SoapClient sarà analizzare una risposta?

È stato utile?

Soluzione 3

Questo sembra essere un bug in PHP. http://bugs.php.net/bug.php?id=49070

Purtroppo, il bug tracker non mi permette di commentare su di esso.

Altri suggerimenti

Ho avuto un problema simile. Sono andato attraverso ogni iterazione che ha attraversato. Su un colpo di fortuna ho disabile caching "soap.wsdl_cache" o modificando il file php.ini o ini_set('soap.wsdl_cache', WSDL_CACHE_NONE); e sulla mia prossima richiesta, tutti i dati mancanti è stata popolata. Questo può facilmente accadere perché il "soap.wsdl_cache_ttl" è impostato su "86400", per impostazione predefinita, che è di 60 giorni.

Quello che ho scoperto è che il server di sapone aveva una modifica del codice. Creazione di un nuovo WSDL. WSDL memorizzato nella cache del cliente era viziata in quel punto. Si potrebbe pensare che, almeno, un hash checksum di qualche tipo sarebbe uscire con ogni richiesta per verificare che il WSDL era cambiato, ma non è così.

Per risolvere il problema e continuare a utilizzare il caching ho creato un file WSDL che ho potuto consumare a livello locale.

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

Spero che questo tu o chiunque altro che accade di fermarsi e hanno un problema simile aiuta.

Hai capire questo tutti fuori dal debug o stampare il contenuto dell'oggetto PHP (print_r, var_dump)?

Hai provato stampando la stringa di risposta effettiva SOAP (non l'oggetto PHP)? È possibile farlo creando il SoapClient con il set di opzione di debug:

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

Poi, quando si utilizza il client per effettuare la chiamata SOAP, è possibile dare un'occhiata a entrambi la richiesta e le stringhe di risposta.

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

Questo potrebbe aiutare a capire che cosa sta facendo SoapClient quando è convertire la risposta a un oggetto PHP. Maggiori informazioni __getLastResponse () .

Qui andiamo quasi un anno e mezzo più tardi ...

Nella mia recente esperienza semi-simile questo non era un bug php. Si tratta di un problema relativo al modo in cui il webservice è scritto e come PHP legge l'uscita. Stavo sperimentando un problema simile (anche fino al getLastResponse restituzione del XML corretto) ed è venuto a scoprire che non era tanto PHP o la mia funzione SOAP che ha avuto un problema, ma che il risultato della funzione "spezzato" non era un esplicito cursore definito.

Esempio di definizione del cursore cattivo:

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

Esempio di buona definizione del cursore:

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

A quanto pare Java in grado di gestire l'uscita "cattivo" / non esplicita bene, ma PHP restituisce un array di oggetti nulli.

Non sono sicuro se questo vi aiuterà, ma definisce l'uscita funzione di servizio Web come il modo "buono" di cui sopra risolto il mio problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top