且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-10-20 20:18:13

可以使用原生 PHP SoapClient 类来实现你的计划.在您的情况下,使用 SoapClient 执行此操作会更容易,因为代码将不那么复杂且更易于理解.

$client = null;尝试 {$client = 新 SoapClient('https://wsiautor.uni-login.dk/wsiautor-v4/ws?WSDL',['cache_wsdl' =>WSDL_CACHE_NONE,'编码' =>'utf-8','例外' =>真的,'soap_version' =>肥皂_1_1,'跟踪' =>真的,],);}赶上(SoapFault $e){echo "
";var_dump($e->getMessage());echo "</pre>";if ($client instanceof SoapClient) {echo "
";var_dump($client->__getLastRequest(), $client->__getLastResponse());echo "</pre>";}}

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

使用 PHP SoapClient 类发送数据

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

<part name="parameters" element="uni:hentDataAftaler"/></消息>

这是hentDataAftaler 请求的定义.它说这个函数需要一个属性类型uni:hentDataAftaler.在这种情况下,uni 是定义 hentDataAftaler 的命名空间.您的 wsdl 文件还说,uni 命名空间的类型定义在一个单独的 xsd 文件中定义,该文件导入另一个 xsd 文件.在深入了解 xsd 定义之后,您的请求参数定义如下.

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

有了这些知识,您可以轻松地使用 php 调用您的网络服务方法.根据定义,您的参数是一个复杂类型,它等于一个 PHP 对象.

类凭证{公共 $wsBrugerid;公共 $wsPassword;公共函数 __construct(SoapVar $wsBrugerid, SoapVar $wsPassword){$this->wsBrugerid = $wsBrugerid;$this->wsPassword = $wsPassword;}}$parameters = 新凭证(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 文件中获取此信息.

希望这会有所帮助.

I am all new to php and all lost in doing a soap request. 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. As I want my php code to do the exact same, I will repeat my earlier question down below:

I have this WSDL site that I need to get some answers from. I have figured out how to do this in SoapUI, but I have no idea how to do it in php. The request that I am sending in soapUI looks like this:

<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

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

you can use the native PHP SoapClient class to achieve your plan. In your case it 's even easier to do it with SoapClient because the code will be less complex and easier to understand.

$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. 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. You should set this option to false. Also the cache_wsdl option should be removed, when the development process has ended.

Sending Data with the PHP SoapClient class

If we have a look into your wsdl file, we can see the exact definition for the function and the types this function needs. So let us see, what hentDataAftaler needs.

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

This is the definition for the hentDataAftaler request. It says that this function requres an attribute type uni:hentDataAftaler. In this case uni ist the namespace in which hentDataAftaler is defined. 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. After a deep dive into the xsd definitions your request paramter is defined as follows.

<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. As defined your parameter is a complex type which equals a PHP object.

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. This class takes two parameters as SoapVar objects, in which we define the value and namespace stuff. At the end we can take this object as the parameter and call the webservice method hentDataAftaler. The function name is known automatically by the soap client, because the soap client takes this information directly from the wsdl file.

Hope this helps a little bit.