English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
[HTTP Access]
There are many ways to access HTTP, mainly including: curl, socket, file_get_contents(), and other methods.
If the server on the other end does not respond for a long time, we are in trouble, as it is easy to kill the entire server, so we also need to consider the timeout issue when accessing HTTP.
[CURL Access HTTP]
CURL is a reliable library commonly used for accessing HTTP protocol interfaces, with high performance and some concurrency support features.
CURL:
curl_setopt($ch, opt) can set some timeout settings, mainly including:
*(Important) CURLOPT_TIMEOUT sets the longest second allowed by cURL.
*(Important) CURLOPT_TIMEOUT_MS sets the longest millisecond allowed by cURL. (In cURL 7.16.2was added. From PHP 5.2.3available starting. )
CURLOPT_CONNECTTIMEOUT is the time to wait before initiating a connection. If set to 0, it will wait indefinitely.
CURLOPT_CONNECTTIMEOUT_MS is the time to wait for a connection attempt, in milliseconds. If set to 0, it will wait indefinitely. In cURL 7.16.2was added. From PHP 5.2.3available starting.
CURLOPT_DNS_CACHE_TIMEOUT sets the time to save DNS information in memory, the default is120 seconds.
curl regular second-level timeout:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //You only need to set a number of seconds
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_USERAGENT, $defined_vars['HTTP_USER_AGENT']);
curl uses the following for the regular second-level timeout:
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
If curl needs to perform a millisecond timeout, you need to add:
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
Or:
curl_setopt($ch, CURLOPT_NOSIGNAL, true); supports millisecond timeout settings
Example of a millisecond timeout for curl:
<?php if (!isset($_GET['foo'])) { // Client $ch = curl_init('http://example.com/'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //Note that the millisecond timeout must be set curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //Timeout in milliseconds, cURL 7.16.2was added. From PHP 5.2.3Can be used $data = curl_exec($ch); $curl_errno = curl_errno($ch); $curl_error = curl_error($ch); curl_close($ch); if ($curl_errno > 0) { echo "cURL Error ($curl_errno): $curl_error\n"; } else { echo "Data received: $data\n"; } } else { // Server sleep(10); echo "Done."; } ?>
Other some tips:
1. According to experience, it is: cURL version >= libcurl/7.21.0 version, millisecond-level timeouts are definitely effective, please note.
2. curl_multi's millisecond-level timeout also has issues... While single access supports ms-level timeouts, curl_multi parallel calls are inaccurate
[Stream processing method to access HTTP]
In addition to curl, we often use fsockopen or file operation functions for HTTP protocol processing, so timeout handling in this area is also necessary.
Generally, connection timeout can be set directly, but stream read timeout requires separate handling.
Handle it yourself:
$tmCurrent = gettimeofday(); $intUSGone = ($tmCurrent['sec' - $tmStart['sec']) * 1000000 + ($tmCurrent['usec' - $tmStart['usec']); if ($intUSGone > $this->_intReadTimeoutUS) { return false; }
or use built-in stream handling functions stream_set_timeout() and stream_get_meta_data() for processing:
<?php // Timeout in seconds $timeout = 5; $fp = fsockopen("example.com", 80, $errno, $errstr, $timeout); if ($fp) { fwrite($fp, "GET"); / HTTP/1.0\r\n"); fwrite($fp, "Host: example.com\r\n"); fwrite($fp, "Connection: Close\r\n\r\n"); stream_set_blocking($fp, true); //Important, set to non-blocking mode stream_set_timeout($fp,$timeout); //Set timeout $info = stream_get_meta_data($fp); while ((!feof($fp)) && (!$info['timed_out'])) { $data .= fgets($fp, 4096); $info = stream_get_meta_data($fp); ob_flush; flush(); } if ($info['timed_out']) { echo "Connection Timed Out!"; } else { echo $data; } }
file_get_contents timeout:
<?php $timeout = array( 'http' => array( 'timeout' => 5 //Set a timeout time, unit in seconds ) ); $ctx = stream_context_create($timeout); $text = file_get_contents("http://example.com/", 0, $ctx); ?>
fopen timeout:
<?php $timeout = array( 'http' => array( 'timeout' => 5 //Set a timeout time, unit in seconds ) ); $ctx = stream_context_create($timeout); if ($fp = fopen("http://example.com/", "r", false, $ctx)) { while( $c = fread($fp, 8192)) { echo $c; } fclose($fp); } ?>
This is the full content of the brief discussion on the solution to the timeout problem of the backend and interface access after PHP processing that the editor has brought to you. Hope everyone will support and cheer for the tutorial~