wsdl服务响应一旦发送变量,php

时间:2012-12-15 15:02:07

标签: php soap service web wsdl

我是SOAP WSDL FUNCTIONS的新手。我有一个客户从一家从事汽车测试的公司获得了wsdl文件。我的客户是他们的分包商。他们告诉我们上传有关车牌,类别等的信息,一旦发送详细信息,服务器会有成功或失败的回复。请帮忙。

浏览不同的信息,我尝试做类似下面的事情,但它无法正常工作

    <?php
$data = array('1'=>'value','2'=>'value','3'=>'value','4'='value','5'=>'value');
$wsdl ='http://181.24.80.32/ws/services/servicename';
$client = new SoapClient($wsdl); 
$response = $client->servicenamerequest($data);  

echo $response->servicenamereturn;  
    ?>

2 个答案:

答案 0 :(得分:3)

首先:如果您正在处理未知的Soap服务,请前往SoapUI。 SoapUI将读取WSDL文件,并允许您查看与Soap方法,参数和返回值相关的几乎所有内容(如果您敢于调用实时服务 - 希望有一个沙盒服务器不会做任何关键)。 / p>

但SoapUI可以通过创建一个接收您的请求的模拟服务来帮助您,并使用您准备的预制请求进行响应。以下是我从链接的WSDL到工作代码示例的方法,而不涉及实际服务。

设置SoapUI

在SoapUI中创建一个新项目并提供WSDL的位置。你可以命名这个项目。

然后,SoapUI读取WSDL的内容并创建包含所有描述的请求的项目。之后,您将看到该服务提供了哪些方法,以及哪些参数必须作为树提供。打开此树将使您检测到的每个方法都显示“请求1”,这会在免费版本中显示一些XML(付费版本稍微更容易填写表单),如此(来自vehiclePassedTest方法):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tr="http://tr.gov.tp.stp.ws.PassedVehicleTestService">
   <soapenv:Header>
      <tr:password>?</tr:password>
      <tr:username>?</tr:username>
   </soapenv:Header>
   <soapenv:Body>
      <tr:vehiclePassedTest>
         <chassisNo>?</chassisNo>
         <plateNo>?</plateNo>
         <plateCode>?</plateCode>
         <plateCategory>?</plateCategory>
         <plcEmiCode>?</plcEmiCode>
         <currentUserName>?</currentUserName>
      </tr:vehiclePassedTest>
   </soapenv:Body>
</soapenv:Envelope>

问号是您必须提供数据的地方。您必须使用PHP的SoapClient创建此请求结构。

我们嘲笑这个。模拟意味着SoapUI启动它自己的接受请求的Soap服务器。它通常运行在127.0.0.1:8080。右键单击项目“PassedVehicleTestService”并选择“New MockService”。接受名称,按确定。

右键单击要模拟的方法。选择“添加到模拟服务”,然后从上一步中选择创建的服务。回答是打开模拟响应编辑器。在那里,您可以看到答案的XML结构,其中包含服务将填写的数据的问号。来自此服务的所有响应都允许一个答案作为字符串,因此请写一些不错的内容将返回。如果需要,您可以稍后将其他方法添加到此服务中。

右键单击“MockService 1”并选择“Start minimize”。这将启动Soap服务器,它将等待传入的请求。

为模拟设置PHP SoapClient。

你需要知道两件事。首先是WSDL的位置。此文件包含要用于请求的真实服务器的地址,但PHP允许覆盖它。所以你需要的第二个信息是正在运行的模拟服务的地址。

SoapUI在请求编辑器中显示WSDL的地址。在你的情况下它是http://181.24.80.32/ws/services/PassedVehicleTestService - 模拟服务在http://127.0.0.1:8080/ws/services/PassedVehicleTestService上运行 - IP和端口被替换,路径被保留。

这导致PHP代码的第一行:

$options = array(
    'location' => 'http://127.0.0.1:8080/ws/services/PassedVehicleTestService',
);

$client = new SoapClient("http://www.quickregistration.ae/temp/PassedVehicleTestService.xml", $options);

之后,您已经配置了SoapClient,可以与您的模拟服务进行通信。如果以后要使用实际服务,请将带有“location”的行抛出数组,如果碰巧添加了一些,请保留其他配置参数。

与模拟对话

使用客户端,您可以执行$client->nameOfSoapMethod(paramStructure)。参数结构通常是数组或对象和标量值(如字符串)的混合。这就是我首先尝试的:

$result = $client->vehiclePassedTest(array());
var_dump($result);

然后我看看SoapUI看看会发生什么。 php脚本的输出:

Notice: Array to string conversion in [...]/soap.php on line 20
string(1) "?"

SoapUI说:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tr.gov.tp.stp.ws.PassedVehicleTestService">
    <SOAP-ENV:Body>
        <ns1:vehiclePassedTest>
            <chassisNo>Array</chassisNo>
            <plateNo/>
            <plateCode/>
            <plateCategory/>
            <plcEmiCode/>
            <currentUserName/>
        </ns1:vehiclePassedTest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

这不是正确的做法。数组被转换为字符串“Array”,并被放置为第一个参数。其余的都是空的。很好,因为我知道soap调用可能会接受更多的一个参数,这就是这些服务之一。

$result = $client->vehiclePassedTest('chassisNo', 'plateNo', 'plateCode', 'plateCategory', 'plcEmiCode', 'currentUserName');

这在SoapUI中正确显示,但标题仍然缺失。

将SoapHeader添加到请求

SoapClient提供了一个名为__setSoapHeaders()的方法,并且有一个类SoapHeader

描述说setSoapHeaders()接受一个SoapHeader对象或一个SoapHeader对象数组。让我们创建一个,传递它,看看会发生什么:

$username = new SoapHeader();
$client->__setSoapHeaders($username);
$result = $client->vehiclePassedTest('chassisNo', 'plateNo', 'plateCode', 'plateCategory', 'plcEmiCode', 'currentUserName');
var_dump($result);

PHP说:Warning: SoapHeader::SoapHeader() expects at least 2 parameters, 0 given

$username = new SoapHeader('namespace', 'username', 'MyUserName');

这很有效。 SoapUI说:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tr.gov.tp.stp.ws.PassedVehicleTestService" xmlns:ns2="namespace">
    <SOAP-ENV:Header>
        <ns2:username>MyUserName</ns2:username>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:vehiclePassedTest><chassisNo>chassisNo</chassisNo><plateNo>plateNo</plateNo><plateCode>plateCode</plateCode><plateCategory>plateCategory</plateCategory><plcEmiCode>plcEmiCode</plcEmiCode><currentUserName>currentUserName</currentUserName></ns1:vehiclePassedTest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

请注意SOAP-ENV:Envelope元素中的两个xmlns属性。原始请求要求用户名在命名空间“tr”中 - 但“tr”只是定义为“xlmns:tr”的字符串的快捷方式 - 此后面的字符串是您需要的命名空间(尽管它可能已经用于真正的服务)。

$username = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'username', 'myUser');
$password = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'password', 'yetAnotherPassword');
$client->__setSoapHeaders(array($username, $password));

这正确定义了标题,如您所见:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tr.gov.tp.stp.ws.PassedVehicleTestService">
    <SOAP-ENV:Header>
        <ns1:username>myUser</ns1:username>
        <ns1:password>yetAnotherPassword</ns1:password>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:vehiclePassedTest><chassisNo>chassisNo</chassisNo><plateNo>plateNo</plateNo><plateCode>plateCode</plateCode><plateCategory>plateCategory</plateCategory><plcEmiCode>plcEmiCode</plcEmiCode><currentUserName>currentUserName</currentUserName></ns1:vehiclePassedTest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

envelope元素中没有两个名称空间,每个元素都是名称空间“ns1”。这应该有用。

您的最终代码:

$options = array(
    'location' => 'http://127.0.0.1:8080/ws/services/PassedVehicleTestService',
);

$client = new SoapClient("http://www.quickregistration.ae/temp/PassedVehicleTestService.xml", $options);

$username = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'username', 'myUser');
$password = new SoapHeader("http://tr.gov.tp.stp.ws.PassedVehicleTestService", 'password', 'yetAnotherPassword');
$client->__setSoapHeaders(array($username, $password));

$result = $client->vehiclePassedTest('chassisNo', 'plateNo', 'plateCode', 'plateCategory', 'plcEmiCode', 'currentUserName');

var_dump($result);

答案 1 :(得分:1)

尝试这样的事情。适合我。

try {
  $client = new SoapClient("http://wsdl",  array('trace' => 1));
  $data = $client->someFunction(array('parma1' => 'value1', 'param2' => 'value2'));
  print_r($data);
} catch (SoapFault $fault) {
   trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
   exit();
}

并检查您是否在服务器中安装了php-soap软件包。

Greatings。