PHP SoapClient Timeout

Est-il de toute façon pour un SoapClient Demande de temps et de lever une exception. A partir de Maintenant, je reçois PHP serveur délai de réponse, dans mon cas 60 secondes. Fondamentalement, ce que je veux est, s'il n'y a pas de réponse du Service Web dans un certain temps, une exception serait jeté et je pourrais attraper. L'avertissement de 60 secondes n'est pas ce que je veux.

19
demandé sur hakre 2010-08-17 12:13:34

5 réponses

regardez

si vous êtes à l'aise et que votre environnement vous permet de prolonger les cours.

il étend fondamentalement le SoapClient class, remplace le transport HTTP par curl qui peut gérer les timeouts:

class SoapClientTimeout extends SoapClient
{
    private $timeout;

    public function __setTimeout($timeout)
    {
        if (!is_int($timeout) && !is_null($timeout))
        {
            throw new Exception("Invalid timeout value");
        }

        $this->timeout = $timeout;
    }

    public function __doRequest($request, $location, $action, $version, $one_way = FALSE)
    {
        if (!$this->timeout)
        {
            // Call via parent because we require no timeout
            $response = parent::__doRequest($request, $location, $action, $version, $one_way);
        }
        else
        {
            // Call via Curl and use the timeout
            $curl = curl_init($location);

            curl_setopt($curl, CURLOPT_VERBOSE, FALSE);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($curl, CURLOPT_POST, TRUE);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
            curl_setopt($curl, CURLOPT_HEADER, FALSE);
            curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
            curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);

            $response = curl_exec($curl);

            if (curl_errno($curl))
            {
                throw new Exception(curl_error($curl));
            }

            curl_close($curl);
        }

        // Return?
        if (!$one_way)
        {
            return ($response);
        }
    }
}
17
répondu Andrei Serdeliuc ॐ 2012-06-02 14:19:19

tandis Qu'Andrei lié à une solution décente, celui - ci a moins de code mais arrive à une bonne solution:

exemple de code:

//
// setting a connection timeout (fifteen seconds on the example)
//
$client = new SoapClient($wsdl, array("connection_timeout" => 15));

et il y a aussi le contexte stream, si vous avez besoin d'un contrôle HTTP plus fin. Voir le stream_context option pour new SoapClient() Docs. Sous la surface SoapClient utilise les transports HTTP et SSL.

44
répondu Jon L. 2012-06-27 18:24:58
ini_set("default_socket_timeout", 15);
$client = new SoapClient($wsdl, array(......));

l'option connection_timeout définit un délai en secondes pour le connexion au service SOAP. Cette option ne définit pas un délai pour les services à réponse lente. Pour limiter le temps d'attente des appels pour terminer, le paramètre default_socket_timeout est disponible.

31
répondu gdtv 2012-08-25 04:41:34

la réponse acceptée cassera toutes les fonctionnalités que SoapClient a à offrir. Comme définir les en-têtes de contenu corrects, l'authentification etc.

Ce serait une meilleure solution au problème

class MySoapClient extends \SoapClient
{
    private $timeout = 10;

    public function __construct($wsdl, array $options)
    {
        // Defines a timeout in seconds for the connection to the SOAP service.
        // This option does not define a timeout for services with slow responses.
        // To limit the time to wait for calls to finish the default_socket_timeout setting is available.
        if (!isset($options['connection_timeout'])) {
            $options['connection_timeout'] = $this->timeout;
        }

        parent::__construct($wsdl, $options);
    }

    public function setTimeout($timeout)
    {
        $this->timeout = $timeout;
    }

    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $original = ini_get('default_socket_timeout');
        ini_set('default_socket_timeout', $this->timeout);
        $response = parent::__doRequest($request, $location, $action, $version, $one_way);
        ini_set('default_socket_timeout', $original);

        return $response;
    }

}
4
répondu Sander Visser 2016-05-13 14:42:12

vous pouvez l'installer via composer: https://github.com/ideaconnect/idct-soap-client

il étend le standard SoapClient et donne des options pour définir la quantité de tentatives, connexion et temps de lecture.

1
répondu Bartosz Pachołek 2018-03-02 11:11:26