Ich bin es gewohnt, PHP - Code zu schreiben, verwende jedoch häufig keine objektorientierte Codierung. Ich muss jetzt mit SOAP (als Client) interagieren und kann die Syntax nicht richtig ausführen. Ich habe eine WSDL-Datei, die es mir ermöglicht, eine neue Verbindung mithilfe der SoapClient-Klasse richtig einzurichten. Ich kann jedoch nicht wirklich den richtigen Anruf tätigen und Daten erhalten. Ich muss die folgenden (vereinfachten) Daten senden:
Im WSDL-Dokument sind zwei Funktionen definiert, aber ich brauche nur eine ("FirstFunction" unten). Hier ist das Skript, das ich ausführte, um Informationen zu den verfügbaren Funktionen und Typen zu erhalten:
$client = new SoapClient("http://example.com/webservices?wsdl");
var_dump($client->__getFunctions());
var_dump($client->__getTypes());
Und hier ist die Ausgabe, die es generiert:
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"
}
Angenommen, ich möchte die FirstFunction mit den Daten anrufen:
Was wäre die richtige Syntax? Ich habe alle möglichen Optionen ausprobiert, aber es scheint, dass die Seifenstruktur sehr flexibel ist. Es gibt also viele Möglichkeiten, dies zu tun. Konnte es auch nicht aus dem Handbuch herausfinden ...
UPDATE 1: probiertes Beispiel von 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));
Ich erhalte jedoch diese Antwort: Object has no 'Contact' property
. Wie Sie in der Ausgabe von getTypes()
sehen können, gibt es eine struct
mit dem Namen Contact
. Ich denke, ich muss irgendwie klarstellen, dass meine Parameter die Kontaktdaten enthalten, aber die Frage ist: wie?
UPDATE 2: Ich habe auch diese Strukturen ausprobiert, gleicher Fehler.
$params = array(
array(
"id" => 100,
"name" => "John",
),
"Barrel of Oil",
500,
);
Ebenso gut wie:
$params = array(
"Contact" => array(
"id" => 100,
"name" => "John",
),
"description" => "Barrel of Oil",
"amount" => 500,
);
Fehler in beiden Fällen: Objekt hat keine Eigenschaft 'Kontakt'
Nur um zu wissen, ich habe versucht, Ihre Situation neu zu erstellen ...
WebMethod
mit dem Namen Function1
erstellt. Dies sind die Parameter: Funktion1 (Kontakt Kontakt, Stringbeschreibung, Int. Betrag)
Dabei ist Contact
nur eine Bean class
, die wie in Ihrem Fall Getter und Setter für id
und name
enthält.
Sie können diesen .NET-Beispiel-Webservice unter folgender Adresse herunterladen:
https://www.dropbox.com/s/6pz1w94a52o5xah/11593623.Zip
Auf der Seite PHP müssen Sie Folgendes tun:
(Getestet und funktioniert)
<?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);
tun, wird diese Ausgabe angezeigt, wie Ihr Webservice erwartet:Array ([Kontakt] => Kontaktobjekt ([ID] => 100 [Name] => John) [Beschreibung] => Ölfass [Menge] => 500)
(Wie Sie sehen können, ist Contact
object nicht null und auch die anderen Parameter, dh Ihre Anfrage wurde erfolgreich von PHP - Seite ausgeführt).
object (stdClass) [3] public 'Function1Result' => Zeichenfolge 'Detailliert Informationen zu Ihrer Anfrage! id: 100, name: John, beschreibung: Barrel Öl, Menge: 500 '(Länge = 98)
Hoffe das hilft :-)
Sie können SOAP auch auf diese Weise verwenden:
<?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);
Dies ist ein Beispiel mit einem echten Dienst, und es funktioniert.
Hoffe das hilft.
Zunächst initialisieren Sie Webservices:
$client = new SoapClient("http://example.com/webservices?wsdl");
Stellen Sie dann die Parameter ein und übergeben Sie sie:
$params = array (
"arg0" => $contactid,
"arg1" => $desc,
"arg2" => $contactname
);
$response = $client->__soapCall('methodname', array($params));
Beachten Sie, dass der Methodenname in WSDL als Operationsname verfügbar ist, z. B .:
<operation name="methodname">
Ich weiß nicht, warum mein Webservice die gleiche Struktur hat wie Sie, aber es ist keine Klasse für Parameter erforderlich, nur Array.
Zum Beispiel: - Meine 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>
Ich var_dump:
var_dump($client->getFunctions());
var_dump($client->getTypes());
Hier ist das Ergebnis:
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)
Also in meinem 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);
aber erfolgreich!
Verwenden Sie zuerst SoapUI , um Ihr Seifenprojekt aus dem WSDL zu erstellen. Versuchen Sie, eine Anfrage zu senden, um mit den Operationen des WSDL zu spielen. Beobachten Sie, wie die XML-Anforderung Ihre Datenfelder zusammenstellt.
Und wenn Sie Probleme damit haben, dass SoapClient die gewünschten Aktionen ausführt, debuggen Sie hier. Stellen Sie die Option trace so ein, dass die Funktion __getLastRequest () verfügbar ist.
$soapClient = new SoapClient('http://yourwdsdlurl.com?wsdl', ['trace' => true]);
$params = ['user' => 'Hey', 'account' => '12345'];
$response = $soapClient->__soapCall('<operation>', $params);
$xml = $soapClient->__getLastRequest();
Dann enthält die Variable $ xml die XML-Datei, die SoapClient für Ihre Anfrage erstellt. Vergleichen Sie diese XML-Datei mit der in der SoapUI generierten.
Für mich scheint SoapClient die Schlüssel des assoziativen Arrays $ params zu ignorieren und als indiziertes Array zu interpretieren, was zu falschen Parameterdaten in der XML führt. Das heißt, wenn ich die Daten in $ params umsortiere, ist die $ -Antwort völlig anders:
$params = ['account' => '12345', 'user' => 'Hey'];
$response = $soapClient->__soapCall('<operation>', $params);
Wenn Sie das Objekt SoapParam erstellen, wird Ihr Problem dadurch gelöst. Erstellen Sie eine Klasse und ordnen Sie sie dem von WebService angegebenen Objekttyp zu. Initialisieren Sie die Werte und senden Sie die Anforderung. Siehe das Beispiel unten.
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);
lesen Sie dies;-
http://php.net/manual/de/soapclient.call.php
Oder
Dies ist ein gutes Beispiel für die SOAP - Funktion "__call" . Sie ist jedoch veraltet.
<?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>";
?>
Sie müssen die Klasse erklären Vertrag
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,
);
oder
$params = array(
$contract,
"description" => "Barrel of Oil",
"amount" => 500,
);
Dann
$response = $client->__soapCall("Function1", array("FirstFunction" => $params));
oder
$response = $client->__soapCall("Function1", $params);
getLastRequest ():
Diese Methode funktioniert nur, wenn das SoapClient-Objekt mit der Traceoption TRUE erstellt wurde.
TRUE wird in diesem Fall durch 1 dargestellt
$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);
arbeitete für mich.
Es gibt eine Option zum Generieren von php5-Objekten mit der WsdlInterpreter-Klasse. Weitere Informationen finden Sie hier: https://github.com/gkwelding/WSDLInterpreter
zum Beispiel:
require_once 'WSDLInterpreter-v1.0.0/WSDLInterpreter.php';
$wsdlLocation = '<your wsdl url>?wsdl';
$wsdlInterpreter = new WSDLInterpreter($wsdlLocation);
$wsdlInterpreter->savePHP('.');
Sie benötigen ein mehrdimensionales Array, Sie können Folgendes versuchen:
$params = array(
array(
"id" => 100,
"name" => "John",
),
"Barrel of Oil",
500
);
in PHP ist ein Array eine Struktur und ist sehr flexibel. Normalerweise verwende ich bei Seifenaufrufen einen XML-Wrapper, also bin ich nicht sicher, ob es funktioniert.
Vielleicht möchten Sie versuchen, eine json-Abfrage zum Senden zu erstellen oder diese zu verwenden, um eine XML-Kaufart zu erstellen, die auf dieser Seite aufgeführt ist: http://onwebdev.blogspot.com/2011/08/php-converting- rss-to-json.html
Ich hatte das gleiche Problem, aber ich habe die Argumente so verpackt und es funktioniert jetzt.
$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 )));
Verwendung dieser Funktion:
print_r($this->client->__getLastRequest());
Sie können die Anforderungs-XML anzeigen, je nachdem, ob sie sich ändert oder nicht.
Verwenden Sie [trace = 1, Ausnahmen = 0] in den SoapClient-Optionen.