如何使用SoapClient类进行PHP SOAP调用

121 php soap

我习惯编写PHP代码,但不经常使用面向对象的编码.我现在需要与SOAP(作为客户端)进行交互,并且无法正确获取语法.我有一个WSDL文件,它允许我使用SoapClient类正确设置新连接.但是,我无法实际进行正确的调用并返回数据.我需要发送以下(简化)数据:

  • 联系人ID
  • 联系人姓名
  • 一般说明

WSDL文档中定义了两个函数,但我只需要一个(下面的"FirstFunction").这是我运行的脚本,用于获取有关可用功能和类型的信息:

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

这是它生成的输出:

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"
}
Run Code Online (Sandbox Code Playgroud)

假设我想用数据调用FirstFunction:

  • 联系ID: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));
Run Code Online (Sandbox Code Playgroud)

但我得到了这个回应:Object has no 'Contact' property.正如你在输出中看到的那样getTypes(),有一个struct叫做Contact,所以我想我不知何故需要弄清楚我的参数包括Contact数据,但问题是:如何?

更新2:我也试过这些结构,同样的错误.

$params = array(
  array(
    "id" => 100,
    "name" => "John",
  ),
  "Barrel of Oil",
  500,
);
Run Code Online (Sandbox Code Playgroud)

以及:

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

两种情况都有错误:对象没有"联系人"属性

Osc*_*car 167

这是你需要做的.

只是要知道,我试图重现你的情况......


  • 对于这个例子,我用一个WebMethod被调用的.NET示例Web服务,Function1这些是参数:

Function1(联系人联系人,字符串描述,int金额)

  • 在这Contact仅仅是一个bean id有getter和setter nameprint_r($params)像你的情况.

  • 您可以在以下位置下载此.NET示例Web服务:

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

?>
Run Code Online (Sandbox Code Playgroud)

我怎么知道这有效?

  • 如果这样,Contact您将看到此输出,因为您的Web服务期望:

数组([联系方式] =>联系对象([id] => 100 [名称] =>约翰)[描述] =>油桶[金额] => 500)

  • 当我调试示例.NET webservice时,我得到了这个:

在此输入图像描述

(如您所见,nullobject不是null,也是其他参数,这意味着您的请求是从PHP端成功完成的).

  • .NET示例Web服务的响应是预期的,并在PHP端显示:

object(stdClass)[3] public'Function1Result'=> string'您的请求的详细信息!id:100,姓名:John,描述:油桶,数量:500'(长度= 98)


希望这可以帮助 :-)

  • @ chapman84你从未接受过他的回答. (4认同)
  • @user应该接受它:) BTW,非常好的答案,完整而且非常清晰.+1 (4认同)
  • 完善!我的行为就像我对SOAP服务的了解要多于我真正做过的事情,这让我得到了我需要的地方. (3认同)

Sal*_* P. 67

您也可以这样使用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);
Run Code Online (Sandbox Code Playgroud)

这是一个真实服务的例子,它可以工作.

希望这可以帮助.


MMK*_*MMK 27

首先初始化webservices:

$client = new SoapClient("http://example.com/webservices?wsdl");
Run Code Online (Sandbox Code Playgroud)

然后设置并传递参数:

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

$response = $client->__soapCall('methodname', array($params));
Run Code Online (Sandbox Code Playgroud)

请注意,方法名称在WSDL中可用作操作名称,例如:

<operation name="methodname">
Run Code Online (Sandbox Code Playgroud)


Tín*_*hạm 21

我不知道为什么我的Web服务与你有相同的结构,但它不需要Class for parameter,只是数组.

例如: - 我的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>
Run Code Online (Sandbox Code Playgroud)

我var_dump:

var_dump($client->getFunctions());
var_dump($client->getTypes());
Run Code Online (Sandbox Code Playgroud)

结果如下:

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)
Run Code Online (Sandbox Code Playgroud)

所以在我的代码中:

    $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);
Run Code Online (Sandbox Code Playgroud)

但它成功了!

  • 你的例子更有帮助,因为它显示了结构依赖 (3认同)

小智 5

如果您创建 SoapParam 对象,这将解决您的问题。创建一个类并将其映射到 WebService 给出的对象类型,初始化值并发送请求。请参阅下面的示例。

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);
Run Code Online (Sandbox Code Playgroud)