Jestem przyzwyczajony do pisania kodu PHP, ale rzadko używam kodowania zorientowanego obiektowo. Teraz muszę współdziałać z SOAP (jako klient) i nie jestem w stanie uzyskać prawidłowej składni. Mam plik WSDL, który pozwala mi poprawnie skonfigurować nowe połączenie za pomocą klasy SoapClient. Jednak nie jestem w stanie wykonać właściwego połączenia i zwrócić danych. Muszę przesłać następujące (uproszczone) dane:
- Identyfikator kontaktu
- Nazwa Kontaktu
- Ogólny opis
- Ilość
W dokumencie WSDL zdefiniowano dwie funkcje, ale potrzebuję tylko jednej (poniżej „FirstFunction”). Oto skrypt, który uruchamiam, aby uzyskać informacje o dostępnych funkcjach i typach:
$client = new SoapClient("http://example.com/webservices?wsdl");
var_dump($client->__getFunctions());
var_dump($client->__getTypes());
A oto wynik, który generuje:
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"
}
Powiedz, że chcę zadzwonić do FirstFunction z danymi:
- Identyfikator kontaktu: 100
- Imię i nazwisko osoby kontaktowej: John
- Opis ogólny: Beczka oleju
- Kwota: 500
Jaka byłaby właściwa składnia? Próbowałem różnych opcji, ale wygląda na to, że struktura mydła jest dość elastyczna, więc jest na to wiele sposobów. Nie mogłem też tego rozgryźć na podstawie instrukcji ...
UPDATE 1: próbka z 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));
Ale mam tę odpowiedź: Object has no 'Contact' property
. Jak widać na wyjściu programu getTypes()
, pojawia się struct
wezwanie Contact
, więc myślę, że muszę jakoś wyjaśnić, że moje parametry obejmują dane kontaktowe, ale pytanie brzmi: jak?
UPDATE 2: Próbowałem też tych struktur, ten sam błąd.
$params = array(
array(
"id" => 100,
"name" => "John",
),
"Barrel of Oil",
500,
);
Jak również:
$params = array(
"Contact" => array(
"id" => 100,
"name" => "John",
),
"description" => "Barrel of Oil",
"amount" => 500,
);
Błąd w obu przypadkach: obiekt nie ma właściwości „Kontakt”
Z usług SOAP możesz również korzystać w ten sposób:
<?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);
To jest przykład z prawdziwą usługą i działa.
Mam nadzieję że to pomoże.
źródło
Najpierw zainicjuj usługi sieciowe:
$client = new SoapClient("http://example.com/webservices?wsdl");
Następnie ustaw i przekaż parametry:
$params = array ( "arg0" => $contactid, "arg1" => $desc, "arg2" => $contactname ); $response = $client->__soapCall('methodname', array($params));
Zauważ, że nazwa metody jest dostępna w WSDL jako nazwa operacji, np .:
<operation name="methodname">
źródło
Nie wiem, dlaczego moja usługa internetowa ma taką samą strukturę jak Ty, ale nie potrzebuje klasy jako parametru, po prostu jest tablicą.
Na przykład: - Mój 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>
I var_dump:
Oto wynik:
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)
Więc w moim kodzie:
$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);
ale z powodzeniem!
źródło
Przeczytaj to;-
http://php.net/manual/en/soapclient.call.php
Lub
To jest dobry przykład dla funkcji SOAP „__call”. Jednak jest przestarzały.
<?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>"; ?>
źródło
Najpierw użyj SoapUI, aby utworzyć projekt mydła z pliku wsdl. Spróbuj wysłać prośbę o zabawę z operacjami wsdl. Obserwuj, jak żądanie XML komponuje pola danych.
A potem, jeśli masz problem z uzyskaniem SoapClient, działającego tak, jak chcesz, oto jak go debuguję. Ustaw opcję śledzenia, aby funkcja __getLastRequest () była dostępna do użycia.
$soapClient = new SoapClient('http://yourwdsdlurl.com?wsdl', ['trace' => true]); $params = ['user' => 'Hey', 'account' => '12345']; $response = $soapClient->__soapCall('<operation>', $params); $xml = $soapClient->__getLastRequest();
Następnie zmienna $ xml zawiera xml, który SoapClient tworzy dla twojego żądania. Porównaj ten plik XML z plikiem wygenerowanym w SoapUI.
Dla mnie SoapClient wydaje się ignorować klucze tablicy asocjacyjnej $ params i interpretować je jako tablicę indeksowaną, powodując nieprawidłowe dane parametrów w xml. Oznacza to, że jeśli zmienię kolejność danych w parametrach $ , odpowiedź $ będzie zupełnie inna:
$params = ['account' => '12345', 'user' => 'Hey']; $response = $soapClient->__soapCall('<operation>', $params);
źródło
Jeśli utworzysz obiekt SoapParam, rozwiąże to twój problem. Utwórz klasę i zamapuj ją na typ obiektu podany przez WebService, zainicjuj wartości i wyślij w żądaniu. Zobacz przykład poniżej.
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);
źródło
Miałem ten sam problem, ale po prostu zawarłem argumenty w ten sposób i teraz działa.
$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 )));
Korzystanie z tej funkcji:
print_r($this->client->__getLastRequest());
Możesz zobaczyć plik XML żądania, czy zmienia się, czy nie, w zależności od argumentów.
Użyj [trace = 1, exceptions = 0] w opcjach SoapClient.
źródło
Musisz zadeklarować klasę Contract
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, );
lub
$params = array( $contract, "description" => "Barrel of Oil", "amount" => 500, );
Następnie
$response = $client->__soapCall("Function1", array("FirstFunction" => $params));
lub
$response = $client->__soapCall("Function1", $params);
źródło
Potrzebujesz wielowymiarowej tablicy, możesz spróbować następujących rzeczy:
$params = array( array( "id" => 100, "name" => "John", ), "Barrel of Oil", 500 );
w PHP tablica jest strukturą i jest bardzo elastyczna. Zwykle w przypadku wywołań mydła używam opakowania XML, więc nie jestem pewien, czy zadziała.
EDYTOWAĆ:
To, co możesz chcieć spróbować, to utworzenie zapytania json do wysłania lub użycie go do utworzenia pliku XML buy pewnego rodzaju na tej stronie: http://onwebdev.blogspot.com/2011/08/php-converting-rss- to-json.html
źródło
Istnieje możliwość generowania obiektów php5 z klasą WsdlInterpreter. Zobacz więcej tutaj: https://github.com/gkwelding/WSDLInterpreter
na przykład:
require_once 'WSDLInterpreter-v1.0.0/WSDLInterpreter.php'; $wsdlLocation = '<your wsdl url>?wsdl'; $wsdlInterpreter = new WSDLInterpreter($wsdlLocation); $wsdlInterpreter->savePHP('.');
źródło
getLastRequest ():
Ta metoda działa tylko wtedy, gdy obiekt SoapClient został utworzony z opcją śledzenia ustawioną na wartość TRUE.
PRAWDA w tym przypadku jest reprezentowana przez 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);
pracował dla mnie.
źródło