SoFunction
Updated on 2025-03-10

Solve the problem of timeout requesting service in curl and soap methods in php

Many services in the company use curl or soap to interact with data. Recently, a new requirement has been added, that is, when the third-party service is distributed, you must retry when you cannot connect to the other party's server. If the business processing fails due to other reasons, it will be processed as failure and will not be called again.

The idea is to judge that curl or soap cannot connect to the other server, throw a TimeoutException exception, and retry it after being caught, and other errors thrown Exception will be processed as failure.

curl processing

  $ch = curl_init($url);
    $options = array(
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_CONNECTTIMEOUT => 5, //5 seconds connection time      CURLOPT_TIMEOUT    => 30, //30 seconds request waiting time    );
    
    curl_setopt_array($ch, $options);
    $response = curl_exec($ch);
    if ($no = curl_errno($ch)) {
      $error = curl_error($ch);
      curl_close($ch);
      //$no error code 7 is not connected, 28 is connected but the request returns result timeout      if(in_array(intval($no), [7, 28], true)) {
        throw new TimeoutException('Connect or request timed out' . $error, $no);
      }
    }
    curl_close($ch);

soap processing

The php document does not write the specific code returned by the soap timeout or the connection cannot be connected in detail. If the business process fails or the connection is not successful, a SoapFault exception will be thrown. After looking at the source code of php, it is still defined.

php source file location /ext/soap/php_http.c

Define the error code content

add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "SSL support is not available in this build", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Could not connect to host", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Failed to create stream??", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Redirection limit reached, aborting", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Didn't receive an xml document", NULL, err);
add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", "Can't uncompress compressed response", NULL, NULL);
add_soap_fault(this_ptr, "HTTP", http_msg, NULL, NULL);

As can be seen from the code, an HTTP code will be returned if it cannot be connected. Soap does not have specific code like curl to distinguish the two. Only using this code can determine whether it is a timeout or a network problem such as not being connected.

The specific code is as follows

ini_set('default_socket_timeout', 30); //Define the response timeout to 30 seconds
    try {
      $options = array(
        'cache_wsdl' => 0,
        'connection_timeout' => 5, //Define the connection timeout to 5 seconds      );
      libxml_disable_entity_loader(false);
      $client = new \SoapClient($url, $options);
      return $client->__soapCall($function_name, $arguments);

    } catch (\SoapFault $e) {
      //Timeout, connection cannot be connected      if($e->faultcode == 'HTTP'){
        throw new TimeoutException('Connect or request timed out', $e->getCode());
      }
    }

You can connect to the soap service, but if there is a problem with the client or server, $e->faultcode will return WSDL, use this to judge

The above is the method of php using soap and curl to capture request timeout and connection timeout. I hope it will be helpful to everyone's learning and I hope everyone will support me more.