How to Call SOAP Web Services in WordPress Using wp_remote_post

Compared to the REST API, SOAP (Simple Object Access Protocol) is a more complex web service interface. Theoretically, we can use PHP’s native SoapClient class to access SOAP interfaces and retrieve data.

However, while developing a WordPress theme recently, we encountered repeated failures when trying to use SoapClient for user synchronization. After switching to the WordPress-native wp_remote_post function, we were able to successfully connect and retrieve data almost immediately. Here’s how to implement it.

1. Preparing the SOAP Request Data

Based on your SOAP interface documentation, first prepare the data you need to send. In this example, we start with a standard PHP array. Note that every SOAP interface has unique requirements; adjust this structure to match your specific API.

$params = [
    'data' => [
        'header' => [
            'security'   => [],
            'time'       => '2017-12-06',
            'sender'     => 'user1',
            'where'      => "time between '2020-07-25 00:00:00' and '2020-07-30 13:59:03'",
        ],
    ],
];

Converting to XML Format

Since SOAP communicates using XML, we need to wrap our data into an XML envelope before sending it.

$xml = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:izn="http://example.com/service">
   <soapenv:Header/>
   <soapenv:Body>
      <izn:doQuery>
         <string>' . json_encode($params) . '</string>
      </izn:doQuery>
   </soapenv:Body>
</soapenv:Envelope>';

2. Sending the Request with wp_remote_post

Now, we send this XML data as the HTTP request body. It’s crucial to set the Content-Type to text/xml in the headers and specify the content length and timeout values.

$service_url = 'http://example.com/service';

$headers = [
    'Content-Type'   => 'text/xml',
    'Content-Length' => strlen($xml),
];

$response = wp_remote_post($service_url, [
    'headers' => $headers,
    'body'    => $xml,
    'timeout' => 60, // Set an appropriate timeout
]);

if (is_wp_error($response)) {
    // Handle error
    echo $response->get_error_message();
} else {
    $body = wp_remote_retrieve_body($response);
    // Parse the XML response back into a PHP object or array
}

Alternative: Using PHP cURL

Under the hood, WordPress’s wp_remote_post often uses the PHP cURL library. If you prefer or require direct control, you can use cURL directly:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $service_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 

$response = curl_exec($ch);
curl_close($ch);

From our experience, SOAP is considerably more cumbersome to work with than REST APIs. If you have the choice when building your own services, we strongly recommend prioritizing REST APIs to save development time and reduce complexity.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *