我正在拔头发。我尝试了很多不同的方法,但没有任何效果:
<?php
// Proxy is for Fiddler
$soap = new soapClient( 'http://testi.lemonsoft.eu:22000/CTP/lemonweb/userservices.svc?wsdl', array(
'proxy_host' => 'localhost',
'proxy_port' => '8888'
));
try {
$test = new stdClass();
$test->UserName = "foo";
$test->Password = "bar";
$test->CompanyDatabase = "baz";
// This should work:
print_r($soap->LogIn($test));
/** The rest are alternative experiments, no avail: **/
print_r($soap->LogIn(array($test)));
print_r($soap->LogIn(array('parameters' => $test)));
print_r($soap->login(array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
)));
print_r($soap->__soapCall('LogIn', array('parameters' => $test)));
print_r($soap->__soapCall('LogIn', array('parameters' => array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
))));
print_r($soap->LogIn(new SoapParam($test, "LogIn")));
print_r($soap->LogIn(new SoapParam(array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
), "LogIn")));
print_r($soap->__soapCall('LogIn', array('parameters' => array(
new SoapParam(array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
), "LogIn")
))));
} catch (SoapFault $fault) {
print_r($fault);
}
?>
我用 fiddler 捕获了请求,响应总是如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:LogIn/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
就好像登录参数从未发送过一样。空的 ns1:LogIn 标签真的意味着这个吗?中间是否存在一些我无法控制的实例,由于某种原因剥离参数?根据我的理解,LogIn 方法需要一个参数,根据文档,该参数应该是 PHP stdClass。
试试这个:
class LogInInfo{
public $UserName = '1';
public $Password = '2';
public $CompanyDatabase = '3';
}
ini_set('display_error', 1);
error_reporting(E_ALL);
$client = new SoapClient('http://testi.lemonsoft.eu:22000/CTP/LemonWeb/UserServices.svc?singleWsdl', array(
'classmap'=>array('LogInInfo'=>'LogInInfo'),
'debug'=>true,
'trace'=>true
));
try {
$info = new LogInInfo();
$resp = $client->LogIn($info);
} catch(Exception $e) {
var_dump($e);
}
print_r($client->__getLastRequest());
结果:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.datacontract.org/2004/07/Lemonsoft.LemonsoftServiceLibrary.User" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://tempuri.org/">
<SOAP-ENV:Body>
<ns2:LogIn xsi:type="ns1:LogInInfo">
<ns1:CompanyDatabase>3</ns1:CompanyDatabase>
<ns1:Password>2</ns1:Password>
<ns1:UserName>1</ns1:UserName>
</ns2:LogIn>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
您可以显示 WSDL 文件的内容吗?
ns1:LogIn 标签表示方法 LogIn 来自 ns1 命名空间(上面定义)。
我设法从 PHP 传递 SOAP 请求中的参数的唯一方法是这样的:
// __setSoapHeaders here
$listCriteriaXML = '<List xmlns="LINKHERE">
<listCriteria>
<ListCriterion>
<Name>DateNeeded</Name>
<SingleValue>' . date("Y-m-d", strtotime("+120 days")) . '</SingleValue>
</ListCriterion>
<ListCriterion>
<Name>limitresults</Name>
<SingleValue>false</SingleValue>
</ListCriterion>
</listCriteria>
</List>';
$listCriteria = new SoapVar($listCriteriaXML, XSD_ANYXML);
$response = $client->List($listCriteria);
echo $client->__getLastRequest();
我的参数也没有传播到消息中。尝试数组、stdClass、真实类、new SoapParams() ...
最后我发现,来自 WSDL 的 SoapClient getFunctions 定义的格式是参数必须单独设置到请求方法中。 所以,而不是这个,这是行不通的:
$params = array("param1"=>"hello",...);
$client->getMyData($params);
就我而言,使用以下内容就足够了:
$client->getMyData($param1, $param2, $param3);
只需执行函数即可发现
$soapClient->__getFunctions()
如果每个函数的响应有多个参数,那么就是这种情况。每个请求函数有多个参数时的响应:
Array ( [0] => MyClass getMyData(date $dateFrom, date $dateTo, string $contractNumber) [1] => OtherClass otherMethod(...),...)