SoapClient क्लास का उपयोग करके PHP SOAP कॉल कैसे करें


130

मुझे PHP कोड लिखने की आदत है, लेकिन अक्सर ऑब्जेक्ट-ओरिएंटेड कोडिंग का उपयोग नहीं करते हैं। अब मुझे एसओएपी (एक ग्राहक के रूप में) के साथ बातचीत करने की आवश्यकता है और मैं वाक्यविन्यास अधिकार प्राप्त करने में सक्षम नहीं हूं। मुझे एक WSDL फ़ाइल मिली है जो मुझे SoapClient वर्ग का उपयोग करके एक नया कनेक्शन ठीक से स्थापित करने की अनुमति देती है। हालांकि, मैं वास्तव में सही कॉल करने और डेटा वापस पाने में असमर्थ हूं। मुझे निम्नलिखित (सरलीकृत) डेटा भेजने की आवश्यकता है:

  • संपर्क आईडी
  • संपर्क नाम
  • सामान्य विवरण
  • रकम

WSDL दस्तावेज़ में दो फ़ंक्शन परिभाषित हैं, लेकिन मुझे केवल एक (नीचे "FirstFunction") की आवश्यकता है। यहाँ वह स्क्रिप्ट है जो मैं उपलब्ध कार्यों और प्रकारों के बारे में जानकारी प्राप्त करने के लिए चलाता हूँ:

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

और यहाँ उत्पादन यह उत्पन्न होता है:

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"
}

कहो कि मैं डेटा के साथ FirstFunction को कॉल करना चाहता हूं:

  • संपर्क आईडी: 100
  • संपर्क नाम: जॉन
  • सामान्य विवरण: तेल का बैरल
  • राशि: 500

सही सिंटैक्स क्या होगा? मैं सभी प्रकार के विकल्पों की कोशिश कर रहा हूं, लेकिन ऐसा प्रतीत होता है कि साबुन की संरचना काफी लचीली है इसलिए ऐसा करने के कई तरीके हैं। मैनुअल से यह पता नहीं लगा सका ...


अद्यतन 1: 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));

लेकिन मैं इस प्रतिक्रिया मिल: Object has no 'Contact' property। जैसा कि आप आउटपुट में देख सकते हैं getTypes(), एक structकहा जाता है Contact, इसलिए मुझे लगता है कि मुझे किसी तरह स्पष्ट करने की आवश्यकता है कि मेरे मापदंडों में संपर्क डेटा शामिल है, लेकिन सवाल यह है: कैसे?

अद्यतन 2: मैंने भी इन संरचनाओं की कोशिश की है, एक ही त्रुटि।

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

साथ ही साथ:

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

दोनों मामलों में त्रुटि: ऑब्जेक्ट का कोई 'संपर्क' गुण नहीं है

php  soap 

जवाबों:


178

यह वह है जो आपको करना जरूरी है।

मैंने स्थिति को फिर से बनाने की कोशिश की ...


  • इस उदाहरण के लिए, मैंने एक .NET नमूना वेबसर्विस (डब्लूएस) बनाया है, WebMethodजिसे Function1निम्नलिखित पैरा की उम्मीद है:

फ़ंक्शन 1 (संपर्क से संपर्क करें, स्ट्रिंग विवरण, इंट राशि)

  • जहां Contactसिर्फ एक मॉडल है जिसके पास आपके मामले में पाने idऔर nameपसंद करने के लिए गेटर्स और सेटर हैं ।

  • आप .NET का नमूना WS पर डाउनलोड कर सकते हैं:

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


कोड।

यह वही है जो आपको PHP की तरफ करने की आवश्यकता है:

(परीक्षण और काम)

<?php
// Create Contact class
class Contact {
    public function __construct($id, $name) 
    {
        $this->id = $id;
        $this->name = $name;
    }
}

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

// Create Contact obj
$contact = new Contact(100, "John");

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

// Invoke WS method (Function1) with the request params 
$response = $client->__soapCall("Function1", array($params));

// Print WS response
var_dump($response);

?>

पूरी बात परखना।

  • यदि आप करते हैं तो print_r($params)आपको निम्न आउटपुट दिखाई देंगे, जैसा कि आपका WS उम्मीद करेगा:

सरणी ([संपर्क] => संपर्क वस्तु ([आईडी] => १०० [नाम] => जॉन) [विवरण] => तेल का बैरल [राशि] => ५००)

  • जब मैंने .NET नमूना WS को डीबग किया तो मुझे निम्नलिखित मिला:

यहाँ छवि विवरण दर्ज करें

(जैसा कि आप देख सकते हैं, Contactऑब्जेक्ट नहीं है nullऔर न ही अन्य परम हैं। इसका मतलब है कि आपका अनुरोध PHP की ओर से सफलतापूर्वक किया गया था)

  • .NET सैंपल WS से प्रतिक्रिया अपेक्षित थी और यह वही है जो मुझे PHP की तरफ मिला है:

ऑब्जेक्ट (stdClass) [3] सार्वजनिक 'Function1Result' => स्ट्रिंग 'आपके अनुरोध की विस्तृत जानकारी! आईडी: 100, नाम: जॉन, विवरण: तेल का बैरल, राशि: 500 '(लंबाई = 98)


हैप्पी कोडिंग!


3
उत्तम! मैंने ऐसा अभिनय किया कि मैं SOAP सेवाओं के बारे में थोड़ा अधिक जानता था जितना मैंने वास्तव में किया था और यह मुझे वहां मिला जहां मुझे होना चाहिए।
13 मई को chapman84

1
मैंने सवाल नहीं पूछा, अन्यथा मेरे पास होता। सवाल और इस जवाब पर हालांकि मुझ से उठापटक हुई।
chapman84

4
@user को इसे स्वीकार करना चाहिए :) BTW, बहुत अच्छा जवाब, पूर्ण और बहुत स्पष्ट। +1
यान्नुज़

इसके लिए धन्यवाद! एसओएपी संरचना को समझने के लिए लील का बढ़ावा।
EatCodePlaySleep

69

आप SOAP सेवाओं का उपयोग इस तरह भी कर सकते हैं:

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

यह एक वास्तविक सेवा के साथ एक उदाहरण है, और यह काम करता है।

उम्मीद है की यह मदद करेगा।


मुझे निम्न त्रुटि मिलती है: ऑब्जेक्ट (stdClass) # 70 (1) {["GetWeatherResult"] => string (14) "डेटा नहीं मिला"} कोई विचार?
इल्के बाल्टासी

लगता है कि उन्होंने शहरों के तार बदल दिए हैं। मैंने उदाहरण के लिए एक और कॉल के साथ एक और सेवा प्रदान की है और वह काम कर रहा है। मैंने उन स्ट्रिंग्स का उपयोग करने की कोशिश की, जो वे शहरों के रूप में लौटते हैं, लेकिन ठीक काम नहीं करता है, वैसे भी GetCitiesByCountry () फ़ंक्शन कॉल करने के तरीके के रूप में कार्य करता है।
साल्वाडोर पी।

30

पहले पहल वेबसर्विसेज:

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

फिर पैरामीटर सेट करें और पास करें:

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

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

नोट करें कि विधि नाम WSDL में ऑपरेशन नाम के रूप में उपलब्ध है, उदाहरण के लिए:

<operation name="methodname">

धन्यवाद! मैंने यह कोशिश की है, लेकिन मुझे त्रुटि मिलती है "ऑब्जेक्ट में कोई 'संपर्क' संपत्ति नहीं है"। मेरे सवाल को पूरी जानकारी के साथ अपडेट करेंगे। कोई विचार?

@ user16441 क्या आप WSDL और सेवा के स्कीमा को पोस्ट कर सकते हैं? मैं आमतौर पर यह पता लगाने से शुरू करता हूं कि XML क्या सेवा की उम्मीद करता है, फिर वायरशर्क का उपयोग करके यह पता लगाने के लिए कि मेरा ग्राहक वास्तव में क्या भेज रहा है।
davidfmatheson

21

मुझे नहीं पता कि मेरी वेब सेवा में आपके साथ समान संरचना क्यों है, लेकिन इसके लिए पैरामीटर के लिए क्लास की आवश्यकता नहीं है, बस सरणी है।

उदाहरण के लिए: - मेरा 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>

मैं var_dump:

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

यहाँ परिणाम है:

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)

तो मेरे कोड में:

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

लेकिन यह सफलतापूर्वक!


1
आपका उदाहरण अधिक सहायक है, क्योंकि यह संरचना निर्भरता दिखाता है
vladkras

3

इसे पढ़ें;-

http://php.net/manual/en/soapclient.call.php

या

SOAP फ़ंक्शन "__call" के लिए यह एक अच्छा उदाहरण है। हालांकि यह पदावनत है।

<?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>";
?>

3

सबसे पहले, का उपयोग SoapUI wsdl से अपने साबुन प्रोजेक्ट बनाने के लिए। Wsdl के संचालन के साथ खेलने के लिए अनुरोध भेजने का प्रयास करें। निरीक्षण करें कि कैसे xml अनुरोध आपके डेटा फ़ील्ड बनाता है।

और फिर, यदि आपको सोपक्लिंट कार्य करने में समस्या हो रही है जैसा कि आप चाहते हैं, तो यहां बताया गया है कि मैं इसे कैसे डीबग करता हूं। विकल्प ट्रेस सेट करें ताकि फ़ंक्शन __getLastRequest () उपयोग के लिए उपलब्ध हो।

$soapClient = new SoapClient('http://yourwdsdlurl.com?wsdl', ['trace' => true]);
$params = ['user' => 'Hey', 'account' => '12345'];
$response = $soapClient->__soapCall('<operation>', $params);
$xml = $soapClient->__getLastRequest();

तब $ xml वैरिएबल में xml होता है जो SoapClient आपके अनुरोध के लिए रचना करता है। इस xml की तुलना सोपुई में उत्पन्न एक से करें।

मेरे लिए, SoapClient साहचर्य सरणी $ params की कुंजियों को अनदेखा करता है और इसे अनुक्रमित सरणी के रूप में व्याख्या करता है, जिससे xml में गलत पैरामीटर डेटा होता है। अगर मैं $ परम में डेटा को फिर से व्यवस्थित करता हूं , तो $ प्रतिक्रिया पूरी तरह से अलग है:

$params = ['account' => '12345', 'user' => 'Hey'];
$response = $soapClient->__soapCall('<operation>', $params);

3

यदि आप सोपपराम की वस्तु बनाते हैं, तो यह आपकी समस्या का समाधान करेगा। एक क्लास बनाएं और इसे वेबसर्विस द्वारा दिए गए ऑब्जेक्ट प्रकार के साथ मैप करें, मानों को इनिशियलाइज़ करें और रिक्वेस्ट में भेजें। नीचे का नमूना देखें।

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

1

मेरे पास एक ही मुद्दा था, लेकिन मैंने सिर्फ इस तरह के तर्कों को लपेटा और यह अब काम करता है।

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

इस फ़ंक्शन का उपयोग करना:

 print_r($this->client->__getLastRequest());

आप अनुरोध XML को देख सकते हैं कि यह आपके तर्कों के आधार पर बदल रहा है या नहीं।

SoapClient विकल्पों में [ट्रेस = 1, अपवाद = 0] का उपयोग करें।


0

आपको वर्ग अनुबंध घोषित करने की आवश्यकता है

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

या

$params = array(
  $contract,
  "description" => "Barrel of Oil",
  "amount" => 500,
);

फिर

$response = $client->__soapCall("Function1", array("FirstFunction" => $params));

या

$response = $client->__soapCall("Function1", $params);

0

आपको एक बहुआयामी सरणी की आवश्यकता है, आप निम्नलिखित की कोशिश कर सकते हैं:

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

PHP में एक सरणी एक संरचना है और बहुत लचीला है। आम तौर पर साबुन कॉल के साथ मैं एक XML आवरण का उपयोग करता हूं ताकि अगर यह काम करेगा।

संपादित करें:

आप जिस चीज़ को आज़माना चाहते हैं, उसे भेजने या उपयोग करने के लिए एक json क्वेरी बना रहा है कि इस पृष्ठ पर जो कुछ भी हो, उसे खरीदने के लिए एक xml खरीदें: http://onwebdev.blogspot.com/2011/08/php-converting-rss- टू-json.html


धन्यवाद, लेकिन यह भी काम नहीं किया। आप एक्सएमएल रैपर का उपयोग कैसे करते हैं, शायद इससे अधिक उपयोग करना आसान हो ...

सबसे पहले आपको यह सुनिश्चित करना होगा कि आपका WSDL XML रैपर को संभाल सके। लेकिन यह समान है, आप XML में अनुरोध का निर्माण करते हैं और ज्यादातर मामलों में कर्ल का उपयोग करते हैं। मैंने बैंकों के माध्यम से लेनदेन को संसाधित करने के लिए XML के साथ SOAP का उपयोग किया है। आप इन्हें स्टार्टर पॉइंट के रूप में देख सकते हैं। forum.digitalpoint.com/showthread.php?t=424619#post4004636 w3schools.com/soap/soap_intro.asp
जेम्स विलियम्स

0

WsdlInterpreter वर्ग के साथ php5 ऑब्जेक्ट जनरेट करने का विकल्प है। यहाँ और देखें: https://github.com/gkwelding/WSDLInterpreter

उदाहरण के लिए:

require_once 'WSDLInterpreter-v1.0.0/WSDLInterpreter.php';
$wsdlLocation = '<your wsdl url>?wsdl';
$wsdlInterpreter = new WSDLInterpreter($wsdlLocation);
$wsdlInterpreter->savePHP('.');

0

getLastRequest ():

यह विधि केवल तभी काम करती है जब साबुन ऑब्जेक्ट को TRUE पर सेट ट्रेस विकल्प के साथ बनाया गया हो।

इस मामले में TRUE 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); 

मेरे लिए काम किया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.