我习惯编写PHP代码,但不经常使用面向对象的编码。我现在需要与SOAP(作为客户端)进行交互,并且无法正确获取语法。我有一个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:
什么是正确的语法?我一直在尝试各种各样的选择,但看起来肥皂结构非常灵活,所以有很多方法可以做到这一点。无法从手册中弄清楚......
更新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
的{{1}},所以我想我需要明确我的参数包括联系人数据,但问题是:怎么样?
更新2:我也试过这些结构,同样的错误。
Contact
以及:
$params = array(
array(
"id" => 100,
"name" => "John",
),
"Barrel of Oil",
500,
);
两种情况都有错误:对象没有'联系'属性`
答案 0 :(得分:158)
我试图重新创造这种情况......
WebMethod
名为Function1
,期望以下参数:Function1(联系人联系人,字符串描述,int金额)
Contact
只是一个模型,其中包含id
和name
的getter和setter,就像你的情况一样。
您可以在以下网址下载.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所期望的那样:数组([联系方式] =&gt;联系对象([id] =&gt; 100 [名称] =&gt;约翰) [描述] =&gt;油桶[数量] =&gt; 500)
(正如您所看到的,Contact
对象不是null
,也不是其他参数。这意味着您的请求是从PHP端成功完成的)
object(stdClass)[3] public'Punction1Result'=&gt;字符串'详细 您的要求的信息! id:100,姓名:John,描述:Barrel 油,量:500'(长度= 98)
快乐的编码!
答案 1 :(得分:64)
您也可以这样使用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);
这是一个真实服务的例子,它可以工作。
希望这有帮助。
答案 2 :(得分:27)
首先初始化webservices:
$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">
答案 3 :(得分: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>
我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);
但它成功了!
答案 4 :(得分:3)
首先,使用SoapUI从wsdl创建soap项目。尝试发送请求以使用wsdl的操作。观察xml请求如何组成数据字段。
然后,如果您在获取SoapClient时遇到问题,请按照以下方式进行调试。设置选项 trace ,以便可以使用函数 __ getLastRequest()。
$soapClient = new SoapClient('http://yourwdsdlurl.com?wsdl', ['trace' => true]);
$params = ['user' => 'Hey', 'account' => '12345'];
$response = $soapClient->__soapCall('<operation>', $params);
$xml = $soapClient->__getLastRequest();
然后 $ xml 变量包含SoapClient为您的请求组成的xml。将此xml与SoapUI中生成的xml进行比较。
对我来说,SoapClient似乎忽略了关联数组 $ params 的键并将其解释为索引数组,导致xml中的参数数据错误。也就是说,如果我重新排序 $ params 中的数据, $ response 就完全不同了:
$params = ['account' => '12345', 'user' => 'Hey'];
$response = $soapClient->__soapCall('<operation>', $params);
答案 5 :(得分:2)
如果您创建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);
答案 6 :(得分:1)
读这个; -
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>";
?>
答案 7 :(得分:0)
您需要一个多维数组,您可以尝试以下方法:
$params = array(
array(
"id" => 100,
"name" => "John",
),
"Barrel of Oil",
500
);
在PHP中,数组是一种结构,非常灵活。通常使用soap调用我使用XML包装器,因此不确定它是否可行。
您可能想要尝试创建一个json查询来发送或使用它来创建xml购买类型,跟随此页面上的内容:http://onwebdev.blogspot.com/2011/08/php-converting-rss-to-json.html
答案 8 :(得分: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);
答案 9 :(得分: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('.');
答案 10 :(得分:0)
我遇到了同样的问题,但是我只包装了这样的参数,现在就可以了。
bt_viewpakageroot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
// clearing app data
//String packageName = getApplicationContext().getPackageName();
Runtime runtime = Runtime.getRuntime();
runtime.exec("reboot"); //pmclear
runtime.wait();
//runtime.exec("pm start "+packageName);
//runtime.wait();
} catch (Exception e) {
Log.e("packageexeception", "&&&& " + e.toString());
Toast.makeText(MainActivity.this, "print errors : " + e.toString(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
});
使用此功能:
$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 )));
您可以查看Request XML,无论它是否在更改,具体取决于您的参数。
在SoapClient选项中使用[跟踪= 1,例外= 0]。
答案 11 :(得分:0)
getLastRequest():
仅当在跟踪选项设置为TRUE的情况下创建SoapClient对象时,此方法才有效。
在这种情况下,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);
为我工作。