39 votos

Cómo hacer un PHP llamada SOAP utilizando la clase SoapClient

Estoy acostumbrado a escribir código PHP, pero a menudo no uso Orientado a Objetos de codificación. Ahora necesito interactuar con JABÓN (como cliente) y no soy capaz de conseguir la sintaxis correcta. Tengo un archivo WSDL que me permite configurar correctamente una nueva conexión con la clase SoapClient. Sin embargo, yo soy incapaz de hacer realidad el derecho de llamar y obtener los datos devueltos. Tengo que enviar los siguientes (simplificado) de datos:

  • ID de contacto
  • Nombre De Contacto
  • Descripción General
  • Cantidad

Hay dos funciones definidas en el documento WSDL, pero sólo tengo uno ("FirstFunction" a continuación). Aquí está el script que ejecutará para obtener información sobre las funciones disponibles y los tipos:

$client = new SoapClient("http://example.com/webservices?wsdl");
var_dump($client->__getFunctions()); 
var_dump($client->__getTypes()); 

Y aquí está la salida que genera:

array(
  [0] => "FirstFunction Function1(FirstFunction $parameters)",
  [1] => "SecondFunction Function2(SecondFunction $parameters)",
);

array(
  [0] => struct Contact {
    id id;
    name name;
  }
  [1] => string "string description"
  [2] => string "int amount"
}

Supongamos que queremos hacer una llamada a la FirstFunction con los datos:

  • Contacto ID: 100
  • Nombre De Contacto: Juan
  • Descripción General: el Barril de Petróleo
  • Cantidad: 500

¿Cuál sería el derecho de la sintaxis? He estado intentando todo tipo de opciones, pero parece que el jabón estructura es muy flexible, así que hay muchas maneras de hacer esto. No podía entenderlo desde el manual, ya sea...


ACTUALIZACIÓN 1: tratado de la muestra de MMK:

$client = new SoapClient("http://example.com/webservices?wsdl");

$params = array(
  "id" => 100,
  "name" => "John",
  "description" => "Barrel of Oil",
  "amount" => 500,
);
$response = $client->__soapCall("Function1", array($params));

Pero me da esta respuesta: Object has no 'Contact' property. Como se puede ver en la salida de getTypes(), hay un struct llamado Contact, así que supongo que de alguna manera necesario dejar en claro mi parámetros incluyen los datos de Contacto, pero la pregunta es: ¿cómo?

ACTUALIZACIÓN 2: también he probado estas estructuras, el mismo error.

$params = array(
  array(
    "id" => 100,
    "name" => "John",
  ),
  "Barrel of Oil",
  500,
);

Así como:

$params = array(
  "Contact" => array(
    "id" => 100,
    "name" => "John",
  ),
  "description" => "Barrel of Oil",
  "amount" => 500,
);

Error en ambos casos: el Objeto no tiene 'Contacto' propiedad`

74voto

Oscar Jara Puntos 5104

Esto es lo que usted necesita hacer.

Solo para saber, traté de recrear su situación...


  • Para este ejemplo, he hecho una .NETO de la muestra webservice con un WebMethod llamado Function1 y estos son los parámetros:

Función 1(Contacto, descripción de cadena, int cantidad)

  • En que Contact es sólo un bean class que ha getters y setters para id y name como en su caso.

  • Usted puede descargar este .NETO de la muestra webservice en:

https://www.dropbox.com/s/6pz1w94a52o5xah/11593623.zip


El código.

Esto es lo que usted necesita hacer en PHP lado:

(Probado y funcionando)

<?php
/* Create a class for your webservice structure, in this case: Contact */
class Contact {
    function Contact($id, $name) 
    {
        $this->id = $id;
        $this->name = $name;
    }
}

/* Initialize webservice with your WSDL */
$client = new SoapClient("http://localhost:10139/Service1.asmx?wsdl");

/* Fill your Contact Object */
$contact = new Contact(100, "John");

/* Set your parameters for the request */
$params = array(
  "Contact" => $contact,
  "description" => "Barrel of Oil",
  "amount" => 500,
);

/* Invoke webservice method with your parameters, in this case: Function1 */
$response = $client->__soapCall("Function1", array($params));

/* Print webservice response */
var_dump($response);

?>

Cómo sé que esto está funcionando?

  • Si no print_r($params); verá esta salida, como su webservice espera:

Array ( [Contacto] => Contacto Object ( [id] => 100 [nombre] => Juan ) [description] => Barril de Petróleo [cantidad] => 500 )

  • Cuando yo depurar la muestra .NET webservice tengo esto:

enter image description here

(Como se puede ver, Contact objeto no es null y también otros parámetros, lo que significa que su solicitud se ha hecho con éxito desde PHP lado).

  • La respuesta de .NETO de la muestra webservice fue el esperado y se muestra en PHP lado:

object(stdClass)[3] público 'Function1Result' => string 'Detallada la información de su solicitud! id: 100, nombre: Juan, descripción: Barril de Aceite, cantidad: 500' (length=98)


Espero que esta ayuda :-)

26voto

Salvador P. Puntos 357

Usted puede utilizar los servicios SOAP de esta manera:

<?php 
//Create the client object
$soapclient = new SoapClient('http://www.webservicex.net/globalweather.asmx?WSDL');

//Use the functions of the client, the params of the function are in 
//the associative array
$params = array('CountryName' => 'Spain', 'CityName' => 'Alicante');
$response = $soapclient->getWeather($params);

var_dump($response);

Este es un ejemplo con un servicio real, y funciona.

Espero que esto ayude.

11voto

MMK Puntos 706

en primer lugar, debemos inicializar webservices

$client = new SoapClient("http://example.com/webservices?wsdl");

y se pasa el parámetro como este

    $params = array (
            "arg0" => $contactid,
            "arg1" => $desc,
    "arg2" => $contactname
    );

$response = $client->__soapCall('methodname', array($params));

y nota nombre de método está disponible en wsdl como nombre de la operación por ejemplo

 <operation name="methodname">

8voto

Tín Phạm Puntos 89

No sé por qué mi web service tiene la misma estructura con usted pero no tiene la Clase de parámetro, sólo es matriz.

Por ejemplo: - Mi WSDL:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ns="http://www.kiala.com/schemas/psws/1.0">
    <soapenv:Header/>
    <soapenv:Body>
        <ns:createOrder reference="260778">
            <identification>
                <sender>5390a7006cee11e0ae3e0800200c9a66</sender>
                <hash>831f8c1ad25e1dc89cf2d8f23d2af...fa85155f5c67627</hash>
                <originator>VITS-STAELENS</originator>
            </identification>
            <delivery>
                <from country="ES" node=""/>
                <to country="ES" node="0299"/>
            </delivery>
            <parcel>
                <description>Zoethout thee</description>
                <weight>0.100</weight>
                <orderNumber>10K24</orderNumber>
                <orderDate>2012-12-31</orderDate>
            </parcel>
            <receiver>
                <firstName>Gladys</firstName>
                <surname>Roldan de Moras</surname>
                <address>
                    <line1>Calle General Oraá 26</line1>
                    <line2>(4º izda)</line2>
                    <postalCode>28006</postalCode>
                    <city>Madrid</city>
                    <country>ES</country>
                </address>
                <email>gverbruggen@kiala.com</email>
                <language>es</language>
            </receiver>
        </ns:createOrder>
    </soapenv:Body>
</soapenv:Envelope>

Yo var_dump:

var_dump($client->getFunctions());
var_dump($client->getTypes());

Aquí está el resultado:

array
  0 => string 'OrderConfirmation createOrder(OrderRequest $createOrder)' (length=56)

array
  0 => string 'struct OrderRequest {
 Identification identification;
 Delivery delivery;
 Parcel parcel;
 Receiver receiver;
 string reference;
}' (length=130)
  1 => string 'struct Identification {
 string sender;
 string hash;
 string originator;
}' (length=75)
  2 => string 'struct Delivery {
 Node from;
 Node to;
}' (length=41)
  3 => string 'struct Node {
 string country;
 string node;
}' (length=46)
  4 => string 'struct Parcel {
 string description;
 decimal weight;
 string orderNumber;
 date orderDate;
}' (length=93)
  5 => string 'struct Receiver {
 string firstName;
 string surname;
 Address address;
 string email;
 string language;
}' (length=106)
  6 => string 'struct Address {
 string line1;
 string line2;
 string postalCode;
 string city;
 string country;
}' (length=99)
  7 => string 'struct OrderConfirmation {
 string trackingNumber;
 string reference;
}' (length=71)
  8 => string 'struct OrderServiceException {
 string code;
 OrderServiceException faultInfo;
 string message;
}' (length=97)

Así que en mi código:

    $client  = new SoapClient('http://packandship-ws.kiala.com/psws/order?wsdl');

    $params = array(
        'reference' => $orderId,
        'identification' => array(
            'sender' => param('kiala', 'sender_id'),
            'hash' => hash('sha512', $orderId . param('kiala', 'sender_id') . param('kiala', 'password')),
            'originator' => null,
        ),
        'delivery' => array(
            'from' => array(
                'country' => 'es',
                'node' => '',
            ),
            'to' => array(
                'country' => 'es',
                'node' => '0299'
            ),
        ),
        'parcel' => array(
            'description' => 'Description',
            'weight' => 0.200,
            'orderNumber' => $orderId,
            'orderDate' => date('Y-m-d')
        ),
        'receiver' => array(
            'firstName' => 'Customer First Name',
            'surname' => 'Customer Sur Name',
            'address' => array(
                'line1' => 'Line 1 Adress',
                'line2' => 'Line 2 Adress',
                'postalCode' => 28006,
                'city' => 'Madrid',
                'country' => 'es',
                ),
            'email' => 'test.ceres@yahoo.com',
            'language' => 'es'
        )
    );
    $result = $client->createOrder($params);
    var_dump($result);

pero con éxito!

0voto

James Williams Puntos 3233

Usted necesita una matriz multidimensional, puede intentar lo siguiente:

$params = array(
   array(
      "id" => 100,
      "name" => "John",
   ),
   "Barrel of Oil",
   500
);

en PHP una matriz es una estructura y es muy flexible. Normalmente con las llamadas soap yo uso un XML envoltorio tan seguro de si funcionará.

EDITAR:

Lo que usted puede intentar es crear un json consulta para enviar o usar para crear un xml comprar ordenación de seguir lo que está en esta página: http://onwebdev.blogspot.com/2011/08/php-converting-rss-to-json.html

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X