J'ai l'habitude d'écrire du code PHP, mais je n'utilise pas souvent le codage orienté objet. J'ai maintenant besoin d'interagir avec SOAP (en tant que client) et je ne parviens pas à obtenir la syntaxe correcte. J'ai un fichier WSDL qui me permet de configurer correctement une nouvelle connexion à l'aide de la classe SoapClient. Cependant, je suis incapable de faire le bon appel et de récupérer les données. J'ai besoin d'envoyer les données suivantes (simplifiées):
Il existe deux fonctions définies dans le document WSDL, mais je n’en ai besoin que d’une seule ("FirstFunction" ci-dessous). Voici le script que je lance pour obtenir des informations sur les types et les fonctions disponibles:
$client = new SoapClient("http://example.com/webservices?wsdl");
var_dump($client->__getFunctions());
var_dump($client->__getTypes());
Et voici le résultat qu'il génère:
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"
}
Dites que je veux faire un appel à la FirstFunction avec les données:
Quelle serait la bonne syntaxe? J'ai essayé toutes sortes d'options, mais il semble que la structure du savon soit assez flexible et qu'il existe de très nombreuses façons de le faire. Impossible de comprendre le manuel non plus ...
UPDATE 1: échantillon essayé 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));
Mais je reçois cette réponse: Object has no 'Contact' property
. Comme vous pouvez le constater dans la sortie de getTypes()
, il existe une struct
appelée Contact
. Je suppose donc que je dois en quelque sorte préciser que mes paramètres incluent les données de contact, mais la question est de savoir comment?
UPDATE 2: J'ai aussi essayé ces structures, même erreur.
$params = array(
array(
"id" => 100,
"name" => "John",
),
"Barrel of Oil",
500,
);
Aussi bien que:
$params = array(
"Contact" => array(
"id" => 100,
"name" => "John",
),
"description" => "Barrel of Oil",
"amount" => 500,
);
Erreur dans les deux cas: l'objet n'a pas de propriété 'Contact'
Juste pour savoir, j'ai essayé de recréer votre situation ...
WebMethod
appelée Function1
et voici les paramètres: Function1 (Contact Contact, description de la chaîne, montant en int)
Dans lequel Contact
est simplement un haricot class
qui a des accesseurs et des calculateurs pour id
et name
comme dans votre cas.
Vous pouvez télécharger cet exemple de service Web .NET à l'adresse:
https://www.dropbox.com/s/6pz1w94a52o5xah/11593623.Zip
Voici ce que vous devez faire du côté PHP:
(Testé et fonctionnel)
<?php
/* Create a class for your webservice structure, in this case: Contact */
class Contact {
public function __construct($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);
?>
print_r($params);
, vous verrez cette sortie, comme le prévoit votre service Web:Tableau ([Contact] => Objet de contact ([id] => 100 [nom] => John) [Description] => baril de pétrole [quantité] => 500)
(Comme vous pouvez le constater, l'objet Contact
n'est pas null et les autres paramètres également, cela signifie que votre demande a été effectuée avec succès du côté PHP).
object (stdClass) [3] public 'Function1Result' => string 'Detailed informations de votre demande! id: 100, nom: John, description: Barrel d'huile, montant: 500 '(longueur = 98)
J'espère que cela t'aides :-)
Vous pouvez également utiliser les services SOAP de cette façon:
<?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);
// Get the Cities By Country
$param = array('CountryName' => 'Spain');
$response = $soapclient->getCitiesByCountry($param);
var_dump($response);
Ceci est un exemple avec un vrai service, et ça marche.
J'espère que cela t'aides.
Commencez par initialiser les webservices:
$client = new SoapClient("http://example.com/webservices?wsdl");
Puis définissez et transmettez les paramètres:
$params = array (
"arg0" => $contactid,
"arg1" => $desc,
"arg2" => $contactname
);
$response = $client->__soapCall('methodname', array($params));
Notez que le nom de la méthode est disponible dans WSDL en tant que nom de l'opération, par exemple:
<operation name="methodname">
Je ne sais pas pourquoi mon service Web a la même structure que vous mais il n’a pas besoin de Class pour paramètre, c’est simplement un tableau.
Par exemple: - Mon 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>[email protected]</email>
<language>es</language>
</receiver>
</ns:createOrder>
</soapenv:Body>
</soapenv:Envelope>
Je var_dump:
var_dump($client->getFunctions());
var_dump($client->getTypes());
Voici le résultat:
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)
Donc dans mon code:
$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' => '[email protected]',
'language' => 'es'
)
);
$result = $client->createOrder($params);
var_dump($result);
mais c'est avec succès!
Tout d’abord, utilisez SoapUI pour créer votre projet soap à partir du WSDL. Essayez d'envoyer une demande pour jouer avec les opérations de wsdl. Observez comment la requête XML compose vos champs de données.
Et puis, si vous rencontrez des problèmes pour obtenir SoapClient agissant comme vous le souhaitez, voici comment le déboguer. Définissez l'option trace de sorte que la fonction __getLastRequest () soit disponible.
$soapClient = new SoapClient('http://yourwdsdlurl.com?wsdl', ['trace' => true]);
$params = ['user' => 'Hey', 'account' => '12345'];
$response = $soapClient->__soapCall('<operation>', $params);
$xml = $soapClient->__getLastRequest();
Ensuite, la variable $ xml contient le code XML que SoapClient compose pour votre demande. Comparez ce xml avec celui généré dans SoapUI.
Pour moi, SoapClient semble ignorer les clés du tableau associatif $ params et l’interpréter comme un tableau indexé, ce qui provoque des données de paramètre incorrectes dans le xml. Autrement dit, si je réorganise les données dans $ params, la réponse $ est complètement différente:
$params = ['account' => '12345', 'user' => 'Hey'];
$response = $soapClient->__soapCall('<operation>', $params);
Si vous créez l'objet de SoapParam, cela résoudra votre problème. Créez une classe et mappez-la avec le type d'objet spécifié par WebService, initialisez les valeurs et envoyez la demande. Voir l'exemple ci-dessous.
struct Contact {
function Contact ($pid, $pname)
{
id = $pid;
name = $pname;
}
}
$struct = new Contact(100,"John");
$soapstruct = new SoapVar($struct, SOAP_ENC_OBJECT, "Contact","http://soapinterop.org/xsd");
$ContactParam = new SoapParam($soapstruct, "Contact")
$response = $client->Function1($ContactParam);
lis ça;-
http://php.net/manual/en/soapclient.call.php
Ou
Ceci est un bon exemple, pour la fonction SOAP "__call" . Cependant, elle est obsolète.
<?php
$wsdl = "http://webservices.tekever.eu/ctt/?wsdl";
$int_zona = 5;
$int_peso = 1001;
$cliente = new SoapClient($wsdl);
print "<p>Envio Internacional: ";
$vem = $cliente->__call('CustoEMSInternacional',array($int_zona, $int_peso));
print $vem;
print "</p>";
?>
Vous devez déclarer la classe Contrat
class Contract {
public $id;
public $name;
}
$contract = new Contract();
$contract->id = 100;
$contract->name = "John";
$params = array(
"Contact" => $contract,
"description" => "Barrel of Oil",
"amount" => 500,
);
ou
$params = array(
$contract,
"description" => "Barrel of Oil",
"amount" => 500,
);
Ensuite
$response = $client->__soapCall("Function1", array("FirstFunction" => $params));
ou
$response = $client->__soapCall("Function1", $params);
getLastRequest ():
Cette méthode ne fonctionne que si l'objet SoapClient a été créé avec l'option de trace définie sur TRUE.
TRUE dans ce cas est représenté par 1
$wsdl = storage_path('app/mywsdl.wsdl');
try{
$options = array(
// 'soap_version'=>SOAP_1_1,
'trace'=>1,
'exceptions'=>1,
'cache_wsdl'=>WSDL_CACHE_NONE,
// 'stream_context' => stream_context_create($arrContextOptions)
);
// $client = new \SoapClient($wsdl, array('cache_wsdl' => WSDL_CACHE_NONE) );
$client = new \SoapClient($wsdl, array('cache_wsdl' => WSDL_CACHE_NONE));
$client = new \SoapClient($wsdl,$options);
a travaillé pour moi.
Il existe une option pour générer des objets php5 avec la classe WsdlInterpreter. Voir plus ici: https://github.com/gkwelding/WSDLInterpreter
par exemple:
require_once 'WSDLInterpreter-v1.0.0/WSDLInterpreter.php';
$wsdlLocation = '<your wsdl url>?wsdl';
$wsdlInterpreter = new WSDLInterpreter($wsdlLocation);
$wsdlInterpreter->savePHP('.');
Vous avez besoin d'un tableau multi-dimensionnel, vous pouvez essayer les solutions suivantes:
$params = array(
array(
"id" => 100,
"name" => "John",
),
"Barrel of Oil",
500
);
dans PHP, un tableau est une structure et est très flexible. Normalement, avec des appels soap, j'utilise un wrapper XML, donc je ne sais pas si cela fonctionnera.
Ce que vous voudrez peut-être essayer, c’est de créer une requête JSON à envoyer ou de l’utiliser pour créer un achat xml en suivant ce qui est présenté sur cette page: http://onwebdev.blogspot.com/2011/08/php-converting- rss-to-json.html
J'ai eu le même problème, mais je viens de résumer les arguments comme celui-ci et cela fonctionne maintenant.
$args = array();
$args['Header'] = array(
'CustomerCode' => 'dsadsad',
'Language' => 'fdsfasdf'
);
$args['RequestObject'] = $whatever;
// this was the catch, double array with "Request"
$response = $this->client->__soapCall($name, array(array( 'Request' => $args )));
En utilisant cette fonction:
print_r($this->client->__getLastRequest());
Vous pouvez voir le XML de la demande, qu'il change ou non, en fonction de vos arguments.
Utilisez [trace = 1, exceptions = 0] dans les options SoapClient.