Creating a SOAP call using PHP with an XML body

前端 未结 2 1916
旧巷少年郎
旧巷少年郎 2020-12-04 10:27

I\'m trying to call a SOAP method using PHP.

Here\'s the code I\'ve got:

$data = array(\'Acquirer\' =>
  array(
    \'Id\' => \'MyId\',
    \'U         


        
相关标签:
2条回答
  • 2020-12-04 10:59

    There are a couple of ways to solve this. The least hackiest and almost what you want:

    $client = new SoapClient(
        null,
        array(
            'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler',
            'uri' => 'http://example.com/wsdl',
            'trace' => 1,
            'use' => SOAP_LITERAL,
        )
    );
    $params = new \SoapVar("<Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer>", XSD_ANYXML);
    $result = $client->Echo($params);
    

    This gets you the following XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl">
        <SOAP-ENV:Body>
            <ns1:Echo>
                <Acquirer>
                    <Id>MyId</Id>
                    <UserId>MyUserId</UserId>
                    <Password>MyPassword</Password>
                </Acquirer>
            </ns1:Echo>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    That is almost exactly what you want, except for the namespace on the method name. I don't know if this is a problem. If so, you can hack it even further. You could put the <Echo> tag in the XML string by hand and have the SoapClient not set the method by adding 'style' => SOAP_DOCUMENT, to the options array like this:

    $client = new SoapClient(
        null,
        array(
            'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler',
            'uri' => 'http://example.com/wsdl',
            'trace' => 1,
            'use' => SOAP_LITERAL,
            'style' => SOAP_DOCUMENT,
        )
    );
    $params = new \SoapVar("<Echo><Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer></Echo>", XSD_ANYXML);
    $result = $client->MethodNameIsIgnored($params);
    

    This results in the following request XML:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
        <SOAP-ENV:Body>
            <Echo>
                <Acquirer>
                    <Id>MyId</Id>
                    <UserId>MyUserId</UserId>
                    <Password>MyPassword</Password>
                </Acquirer>
            </Echo>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    Finally, if you want to play around with SoapVar and SoapParam objects, you can find a good reference in this comment in the PHP manual: http://www.php.net/manual/en/soapvar.soapvar.php#104065. If you get that to work, please let me know, I failed miserably.

    0 讨论(0)
  • 2020-12-04 11:05

    First off, you have to specify you wish to use Document Literal style:

    $client = new SoapClient(NULL, array(
        'location' => 'https://example.com/path/to/service',
        'uri' => 'http://example.com/wsdl',
        'trace' => 1,
        'use' => SOAP_LITERAL)
    );
    

    Then, you need to transform your data into a SoapVar; I've written a simple transform function:

    function soapify(array $data)
    {
            foreach ($data as &$value) {
                    if (is_array($value)) {
                            $value = soapify($value);
                    }
            }
    
            return new SoapVar($data, SOAP_ENC_OBJECT);
    }
    

    Then, you apply this transform function onto your data:

    $data = soapify(array(
        'Acquirer' => array(
            'Id' => 'MyId',
            'UserId' => 'MyUserId',
            'Password' => 'MyPassword',
        ),
    ));
    

    Finally, you call the service passing the Data parameter:

    $method = 'Echo';
    
    $result = $client->$method(new SoapParam($data, 'Data'));
    
    0 讨论(0)
提交回复
热议问题