Pregunta

Tengo problemas con el análisis de PHP de la respuesta de una llamada SoapClient. Para algunos tipos de respuestas, es que regresan matrices de stdClass vacío objetos en lugar de objetos StdClass inicializados.

El servidor es un servicio web Java desplegado con axis2 en tomcat6. La firma de Java de la llamada de servicio es problemática Curso public Course getCourseDetails(Long courseId) es un POJO estándar definido como:

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

    //etc...
}

Hole es un POJO estándar con sólo los miembros primariedad.

Cuando se llama con PHP, el miembro de agujeros es una matriz con la longitud correcta, pero cada agujero está vacío.

$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

La impresión de la $soapClient->__getLastResponse() XML devuelto con lo que parece ser la representación correcta:

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

¿Por qué es cada hoyo una stdClass vacío? ¿Hay limitaciones conocidos por el número de niveles SoapClient va a analizar una respuesta?

¿Fue útil?

Solución 3

Esto parece ser un fallo en PHP. http://bugs.php.net/bug.php?id=49070

Por desgracia, el gestor de fallos no me deja comentarios al respecto.

Otros consejos

Yo tenía un problema similar. Fui a través de cada iteración que pasó por. En un golpe de suerte que el almacenamiento en caché desactivada "soap.wsdl_cache" ya sea cambiando el archivo php.ini o ini_set('soap.wsdl_cache', WSDL_CACHE_NONE); y en mi próxima solicitud fue poblada todos los datos que faltan. Esto puede suceder fácilmente debido a que el "soap.wsdl_cache_ttl" está ajustado a "86400", por defecto, que es de 60 días.

Lo que descubrí fue que el servidor de jabón tenía un cambio de código. Creación de un nuevo WSDL. WSDL almacenado en caché del cliente estaba duro en ese punto. Se podría pensar que, al menos, un hash suma de comprobación de algún tipo sería salir con cada solicitud para verificar que el WSDL había cambiado pero no lo hace.

Para resolver este problema y seguir utilizando el almacenamiento en caché he creado un archivo WSDL que podía consumir localmente.

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

Espero que esto usted o cualquier otra persona que pasa a parar y tienen un problema similar ayuda.

Te diste cuenta de todo esto a cabo por la depuración o imprimir el contenido del objeto PHP (print_r, var_dump)?

¿Ha intentado imprimir la cadena de respuesta real de jabón (no el objeto PHP)? Usted puede hacer esto mediante la creación de la SoapClient con el conjunto de opciones de depuración:

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

A continuación, cuando se utiliza el cliente para hacer su llamada SOAP, puede echar un vistazo a la vez la solicitud y las cadenas de respuesta.

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

Esto podría ayudar a determinar qué SoapClient está haciendo cuando se está convirtiendo la respuesta a un objeto PHP. Más información sobre __getLastResponse () .

Aquí vamos casi un año y medio después ...

En mi experiencia reciente semi-similar este no era un error de PHP. Es una cuestión relacionada con la forma en que el servicio web está escrito en PHP y cómo lee la salida. Que estaba experimentando un problema similar (incluso hasta getLastResponse devolver el XML correcto) y llegué a descubrir que no era tanto PHP o mi función SOAP que tenía un problema, pero que el resultado de la función "roto" no era una forma explícita cursor definido.

Ejemplo de mala definición del cursor:

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

Ejemplo de buena definición cursor:

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

Al parecer Java puede manejar el "malo" de salida / no explícita bien, pero PHP devuelve un array de objetos nulos.

No estoy seguro si esto le ayudará, pero la definición de la salida de la función de servicios web como la forma "buena" por encima fijado mi problema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top