PHP SoapClient超时

Sha*_*fiz 26 php web-services timeout soap-client

无论如何,SoapClient请求超时并抛出异常.截至目前,我得到PHP服务器响应超时,在我的情况下60秒.基本上我想要的是,如果在一定时间内没有来自Web服务的任何回复,将抛出异常并且我可以捕获它.60秒警告不是我想要的.

Jon*_* L. 53

虽然Andrei与一个不错的解决方案相关联,但是这个解决方案的代码更少,但却找到了一个很好的解

示例代码:

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

如果您需要更细粒度的HTTP控制,还有流上下文.请参阅文档stream_context选项.表面下使用HTTP和SSL传输.new SoapClient()SoapClient

  • 根据PHP文档,此超时只会影响与服务的连接,而不会影响操作实际花费的时间。您需要设置“ default_socket_timeout”,如下所述 (4认同)

小智 38

ini_set("default_socket_timeout", 15);
$client = new SoapClient($wsdl, array(......));
Run Code Online (Sandbox Code Playgroud)

connection_timeout选项定义连接到SOAP服务的超时(以秒为单位).此选项不会为响应缓慢的服务定义超时.要限制等待调用完成的时间,可以使用default_socket_timeout设置.


And*_*c ॐ 17

看一下

如果你感觉舒服,你的环境允许你扩展课程.

它基本上扩展了SoapClient类,用curl替换了HTTP传输,可以处理超时:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我在PHP 5.4.6中试过这个,但看起来,它们已经改变了`_doRequest()的签名而没有另行通知.`$ request`不再包含原始XML,而是一个字符串,如`1412012996904600511412017173132141201717499173131141201717499463131141201717499483135false`.任何人都可以对此有所了解吗? (2认同)

San*_*ser 7

接受的答案将破坏SoapClient必须提供的所有功能。像设置正确的内容标题,身份验证等。

这将是解决该问题的更好方法

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

}
Run Code Online (Sandbox Code Playgroud)


Ere*_*Paz 7

您还可以使用stream_context_create()并将timeout选项添加到数组中http

$context = stream_context_create(
    array(
        'http' => array(
            "timeout" => 10,
        ),
    )
);
Run Code Online (Sandbox Code Playgroud)

这是 PHP 手册页

SoapHandler 初始化应该是:

$soapHandler = new SoapClient($wsdl, [
    //more params, if needed..
    
    'stream_context' => $context,
]);
Run Code Online (Sandbox Code Playgroud)

  • 为我工作。谢谢 (2认同)