简体   繁体   English

我如何在 php 中发出 SOAP 请求,就像在 SoapUI 中一样?

[英]How do I make a SOAP-request in php, just like in SoapUI?

I am all new to php and all lost in doing a soap request.我是 php 的新手,在做 soap 请求时全都迷失了。 I have this other question How to send a SOAP request in javascript, like in SoapUI , which I have just got answered, but I have now decided to work in php instead of Node.js.我有另一个问题How to send a SOAP request in javascript, like in SoapUI ,我刚刚得到回答,但我现在决定在 php 而不是 Node.js 中工作。 As I want my php code to do the exact same, I will repeat my earlier question down below:因为我希望我的 php 代码执行完全相同的操作,所以我将在下面重复我之前的问题:

I have this WSDL site that I need to get some answers from.我有这个 WSDL 站点,我需要从中获得一些答案。 I have figured out how to do this in SoapUI, but I have no idea how to do it in php.我已经想出如何在 SoapUI 中执行此操作,但我不知道如何在 php 中执行此操作。 The request that I am sending in soapUI looks like this:我在 soapUI 中发送的请求如下所示:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:uni="https://uni-login.dk">
   <soap:Header/>
   <soap:Body>
      <uni:hentDataAftaler>
         <uni:wsBrugerid>?</uni:wsBrugerid>
         <uni:wsPassword>?</uni:wsPassword>
      </uni:hentDataAftaler>
   </soap:Body>
</soap:Envelope>

I also have the wsdl-link: https://wsiautor.uni-login.dk/wsiautor-v4/ws?WSDL我还有 wsdl 链接: https ://wsiautor.uni-login.dk/wsiautor-v4/ws?WSDL

I hope you I have some suggestions and tell me if you need any more information to answer my question:)我希望你能给我一些建议,如果你需要更多信息来回答我的问题,请告诉我:)

The answer for my previous question was the following我之前的问题的答案如下

    const soapRequest = require('easy-soap-request');
    const url = 'https://wsiautor.uni-login.dk/wsiautor-v4/ws';
    const headers = {
      'Content-Type': 'application/soap+xml;charset=UTF-8',
      'soapAction': 'https://wsiautor.uni-login.dk/hentDataAftaler',
};
// example data
const xml = `
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:uni="https://uni-login.dk">
   <soap:Header/>
   <soap:Body>
      <uni:hentDataAftaler>
         <uni:wsBrugerid>?</uni:wsBrugerid>
         <uni:wsPassword>?</uni:wsPassword>
      </uni:hentDataAftaler>
   </soap:Body>
</soap:Envelope>
`;


// usage of module
soapRequest(url, headers, xml).then(({response: {body, statusCode}}) => {
    console.log(body);
    console.log(statusCode);
}).catch((errorBody) => {
    console.error(errorBody);
});

There are at least two extensions you can use to enable that.您至少可以使用两个扩展来启用它。

I would recommend the old and good curl extension.我会推荐旧的和好的curl扩展。

Another tip is that with Postman you can generate code for HTTP requests using curl or http-request .另一个提示是,使用Postman ,您可以使用curlhttp-request为 HTTP 请求生成代码。 You can find it in the right up corner, near the send button.您可以在发送按钮附近的右上角找到它。

Certify you install the extension first (in my case, installed using apt):证明您首先安装了扩展(在我的例子中,使用 apt 安装):

sudo apt-get install php-curl

Anyway, I believe you can use this code to accomplish it:无论如何,我相信你可以使用这段代码来完成它:

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_PORT => "80",
  CURLOPT_URL => "https://wsiautor.uni-login.dk/wsiautor-v4/ws",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_SSL_VERIFYPEER => false,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" 
  xmlns:uni=\"https://uni-login.dk\">
    <soapenv:Header/>
     <soapenv:Body>
       <uni:hentDataAftaler>
         <uni:wsBrugerid>?</uni:wsBrugerid>
         <uni:wsPassword>?</uni:wsPassword>
       </uni:hentDataAftaler>
      </soapenv:Body>
    </soapenv:Envelope>",
  CURLOPT_HTTPHEADER => array(
    "Content-Type: application/soap+xml;charset=UTF-8",
    "soapAction: https://wsiautor.uni-login.dk/hentDataAftaler"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

you can use the native PHP SoapClient class to achieve your plan.您可以使用本机 PHP SoapClient类来实现您的计划。 In your case it 's even easier to do it with SoapClient because the code will be less complex and easier to understand.在您的情况下,使用 SoapClient 更容易做到这一点,因为代码将不那么复杂并且更容易理解。

$client = null;

try {
    $client = new SoapClient(
        'https://wsiautor.uni-login.dk/wsiautor-v4/ws?WSDL',
        [
            'cache_wsdl' => WSDL_CACHE_NONE,
            'encoding' => 'utf-8',
            'exceptions' => true,
            'soap_version' => SOAP_1_1,
            'trace' => true,
        ],
    );
} catch (SoapFault $e) {
    echo "<pre>";
    var_dump($e->getMessage());
    echo "</pre>";

    if ($client instanceof SoapClient) {
        echo "<pre>";
        var_dump($client->__getLastRequest(), $client->__getLastResponse());
        echo "</pre>";
    }
}

If we look at that code example, we instantiate a simple SoapClient with your wsdl url and some options, that grant access to some really cool debugging functions.如果我们查看该代码示例,我们会使用您的 wsdl url 和一些选项实例化一个简单的 SoapClient,这些选项授予对一些非常酷的调试功能的访问权限。 The trace option enables the functions __getLastRequest() and __getLastResponse() so you can easily look at what has been send and what was the response, if the client is alive. trace选项启用函数__getLastRequest()__getLastResponse()以便您可以轻松查看已发送的内容和响应(如果客户端处于活动状态)。 You should set this option to false.您应该将此选项设置为 false。 Also the cache_wsdl option should be removed, when the development process has ended.当开发过程结束时,还应删除cache_wsdl选项。

Sending Data with the PHP SoapClient class使用 PHP SoapClient 类发送数据

If we have a look into your wsdl file, we can see the exact definition for the function and the types this function needs.如果我们查看您的 wsdl 文件,我们可以看到该函数的确切定义以及该函数所需的类型。 So let us see, what hentDataAftaler needs.那么让我们看看, hentDataAftaler需要什么。

<message name="hentDataAftalerIn">
    <part name="parameters" element="uni:hentDataAftaler"/>
</message>

This is the definition for the hentDataAftaler request.这是hentDataAftaler请求的定义。 It says that this function requres an attribute type uni:hentDataAftaler .它说这个函数需要一个属性类型uni:hentDataAftaler In this case uni ist the namespace in which hentDataAftaler is defined.在本例中, uni ist 定义了hentDataAftaler的命名空间。 Your wsdl file also says, that the type definitions for the uni namespace are defined in a seperated xsd file, which imports another xsd file.您的 wsdl 文件还说, uni命名空间的类型定义是在一个单独的 xsd 文件中定义的,该文件导入另一个 xsd 文件。 After a deep dive into the xsd definitions your request paramter is defined as follows.在深入了解 xsd 定义后,您的请求参数定义如下。

<xs:complexType name="Credentials">
    <xs:sequence>
        <xs:element name="wsBrugerid" type="xs:string"/>
        <xs:element name="wsPassword" type="xs:string"/>
    </xs:sequence>
</xs:complexType>

With this knowledge you can easily call your webservice method with php.有了这些知识,您就可以轻松地使用 php 调用您的 webservice 方法。 As defined your parameter is a complex type which equals a PHP object.根据定义,您的参数是一个复杂类型,相当于一个 PHP 对象。

class Credentials
{
    public $wsBrugerid;
    public $wsPassword;

    public function __construct(SoapVar $wsBrugerid, SoapVar $wsPassword)
    {
        $this->wsBrugerid = $wsBrugerid;
        $this->wsPassword = $wsPassword;
    }
}

$parameters = new Credentials(
    new SoapVar('brugerid', XSD_STRING, null, null, 'wsBrugerid', 'https://uni-login.dk'),
    new SoapVar('password', XSD_STRING, null, null, 'wsPassword', 'https://uni-login.dk')
);

$result = $client->hentDataAftaler($parameters);

What have we done here?我们在这里做了什么? We 've adapted the complex type from the xsd definition into a PHP class.我们已经将 xsd 定义中的复杂类型改编为 PHP 类。 This class takes two parameters as SoapVar objects, in which we define the value and namespace stuff.这个类有两个参数作为 SoapVar 对象,我们在其中定义了值和命名空间的东西。 At the end we can take this object as the parameter and call the webservice method hentDataAftaler .最后我们可以将这个对象作为参数,调用webservice的方法hentDataAftaler The function name is known automatically by the soap client, because the soap client takes this information directly from the wsdl file. soap 客户端自动知道函数名称,因为 soap 客户端直接从 wsdl 文件获取此信息。

Hope this helps a little bit.希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM