How to make a PHP SOAP call using the SoapClient class

后端 未结 12 579
星月不相逢
星月不相逢 2020-11-22 17:28

I\'m used to writing PHP code, but do not often use Object-Oriented coding. I now need to interact with SOAP (as a client) and am not able to get the syntax right. I\'ve got

相关标签:
12条回答
  • 2020-11-22 17:35

    If you create the object of SoapParam, This will resolve your problem. Create a class and map it with object type given by WebService, Initialize the values and send in the request. See the sample below.

    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);
    
    0 讨论(0)
  • 2020-11-22 17:38

    First, use SoapUI to create your soap project from the wsdl. Try to send a request to play with the wsdl's operations. Observe how the xml request composes your data fields.

    And then, if you are having problem getting SoapClient acts as you want, here is how I debug it. Set the option trace so that the function __getLastRequest() is available for use.

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

    Then the $xml variable contains the xml that SoapClient compose for your request. Compare this xml with the one generated in the SoapUI.

    For me, SoapClient seems to ignore the keys of the associative array $params and interpret it as indexed array, causing wrong parameter data in the xml. That is, if I reorder the data in $params, the $response is completely different:

    $params = ['account' => '12345', 'user' => 'Hey'];
    $response = $soapClient->__soapCall('<operation>', $params);
    
    0 讨论(0)
  • 2020-11-22 17:38

    getLastRequest():

    This method works only if the SoapClient object was created with the trace option set to TRUE.

    TRUE in this case is represented by 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); 
    

    worked for me.

    0 讨论(0)
  • 2020-11-22 17:40

    There is an option to generate php5 objects with WsdlInterpreter class. See more here: https://github.com/gkwelding/WSDLInterpreter

    for example:

    require_once 'WSDLInterpreter-v1.0.0/WSDLInterpreter.php';
    $wsdlLocation = '<your wsdl url>?wsdl';
    $wsdlInterpreter = new WSDLInterpreter($wsdlLocation);
    $wsdlInterpreter->savePHP('.');
    
    0 讨论(0)
  • 2020-11-22 17:41

    I don't know why my web service has the same structure with you but it doesn't need Class for parameter, just is array.

    For example: - My 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>
    

    I var_dump:

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

    Here is result:

    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)
    

    So in my 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' => 'test.ceres@yahoo.com',
                'language' => 'es'
            )
        );
        $result = $client->createOrder($params);
        var_dump($result);
    

    but it successfully!

    0 讨论(0)
  • 2020-11-22 17:42

    You need a multi-dimensional array, you can try the following:

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

    in PHP an array is a structure and is very flexible. Normally with soap calls I use an XML wrapper so unsure if it will work.

    EDIT:

    What you may want to try is creating a json query to send or using that to create a xml buy sort of following what is on this page: http://onwebdev.blogspot.com/2011/08/php-converting-rss-to-json.html

    0 讨论(0)
提交回复
热议问题