如何在php中创建SOAP请求,就像在SoapUI中一样?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在php中创建SOAP请求,就像在SoapUI中一样?相关的知识,希望对你有一定的参考价值。

我是php的新手,所有人都在做肥皂请求。我有另外一个问题How to send a SOAP request in javascript, like in SoapUI,我刚刚得到了答案,但我现在决定在php而不是Node.js工作。由于我希望我的PHP代码完全相同,我将在下面重复我之前的问题:

我有这个WSDL网站,我需要从中获得一些答案。我已经弄清楚如何在SoapUI中执行此操作,但我不知道如何在php中执行此操作。我在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>

我也有wsdl-link:https://wsiautor.uni-login.dk/wsiautor-v4/ws?WSDL

我希望你有一些建议,告诉我你是否需要更多信息来回答我的问题:)

我上一个问题的答案如下

    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);
});
答案

您可以使用至少两个扩展来启用它。

我会推荐旧的和良好的curl扩展。

另一个提示是,使用Postman,您可以使用curlhttp-request为HTTP请求生成代码。您可以在发送按钮附近的右上角找到它。

验证您首先安装扩展(在我的情况下,使用apt安装):

sudo apt-get install php-curl

无论如何,我相信您可以使用此代码来完成它:

<?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;
}
另一答案

您可以使用本机PHP SoapClient类来实现您的计划。在你的情况下,使用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>";
    }
}

如果我们查看该代码示例,我们使用您的wsdl url和一些选项实例化一个简单的SoapClient,它授予对一些非常酷的调试函数的访问权限。 trace选项启用__getLastRequest()__getLastResponse()函数,这样您就可以轻松查看已发送的内容以及响应的内容(如果客户端处于活动状态)。您应该将此选项设置为false。当开发过程结束时,应删除cache_wsdl选项。

使用PHP SoapClient类发送数据

如果我们查看您的wsdl文件,我们可以看到函数的确切定义以及此函数所需的类型。让我们看看,hentDataAftaler需要什么。

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

这是hentDataAftaler请求的定义。它说这个函数需要一个属性类型uni:hentDataAftaler。在这种情况下,uni是定义hentDataAftaler的命名空间。您的wsdl文件还说,uni命名空间的类型定义是在一个单独的xsd文件中定义的,该文件导入另一个xsd文件。深入研究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>

有了这些知识,您可以使用php轻松调用您的Web服务方法。根据定义,您的参数是一个复杂类型,它等于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);

我们在这做了什么?我们已经将xsd定义中的复杂类型调整为PHP类。该类将两个参数作为SoapVar对象,我们在其中定义值和名称空间。最后,我们可以将此对象作为参数,并调用webservice方法hentDataAftaler。 soap客户端自动知道函数名称,因为soap客户端直接从wsdl文件中获取此信息。

希望这有点帮助。

以上是关于如何在php中创建SOAP请求,就像在SoapUI中一样?的主要内容,如果未能解决你的问题,请参考以下文章

php SOAP 响应编码问题

如何像在 babelrc 中创建依赖别名一样在 typescript 中创建类型别名?

jav怎样实现对soapUI mockService功能的模拟,需要代码

如何在 Javascript 中创建查询参数?

如何在C#中创建SOAP / WSDL客户端?

如何在PHP中传递SOAP标头和Body作为参数