webentwicklung-frage-antwort-db.com.de

Wie man einen ... macht PHP SOAP Aufruf mit der SoapClient-Klasse

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:

  • Kontakt-ID
  • Kontaktname
  • Allgemeine Beschreibung
  • Menge

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: 

  • Kontakt-ID: 100
  • Name des Ansprechpartners: John
  • Allgemeine Beschreibung: Ölfass
  • Betrag: 500

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'

104
user1305445

Das müssen Sie tun.

Nur um zu wissen, ich habe versucht, Ihre Situation neu zu erstellen ...


  • Für dieses Beispiel habe ich einen .NET-Beispiel-Webservice mit einer 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


Der Code.

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

?>

Woher weiß ich, dass das funktioniert?

  • Wenn Sie print_r($params); tun, wird diese Ausgabe angezeigt, wie Ihr Webservice erwartet:

Array ([Kontakt] => Kontaktobjekt ([ID] => 100 [Name] => John) [Beschreibung] => Ölfass [Menge] => 500)

  • Beim Debuggen des .NET-Beispielservices habe ich Folgendes erhalten:

enter image description here

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

  • Die Antwort des .NET-Beispiel-Webservice war die erwartete und wurde auf der Seite PHP angezeigt:

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 :-)

155
Oscar Jara

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.

64
Salvador P.

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">
26
MMK

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!

21
Tín Phạm

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);
3
Sang Nguyen

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);
2
Umesh Chavan

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>";
?>
1
Abid Hussain

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

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.

0
CollinsKe

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('.');
0

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.

BEARBEITEN:

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

0
James Williams

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.

0
Martin Zvarík