Php увеличить время ожидания ответа

set_time_limit

Задаёт время в секундах, в течение которого скрипт должен завершить работу. Если скрипт не успевает, вызывается фатальная ошибка. По умолчанию даётся 30 секунд, либо время, записанное в настройке max_execution_time в php.ini (если такая настройка установлена).

При вызове set_time_limit() перезапускает счётчик с нуля. Другими словами, если время ожидания изначально было 30 секунд, и через 25 секунд после запуска скрипта будет вызвана функция set_time_limit(20) , то скрипт будет работать максимум 45 секунд.

Список параметров

Максимальное время выполнения в секундах. Если задан ноль, время выполнения неограниченно.

Возвращаемые значения

Возвращает true в случае успешного выполнения, иначе false .

Примечания

Замечание:

Функция set_time_limit() и директива max_execution_time влияют на время выполнения только самого скрипта. Время, затраченное на различные действия вне скрипта, такие как системные вызовы функции system() , потоковые операции, запросы к базам данных и т.п. не включаются в расчёт времени выполнения скрипта. Это не относится к системам Windows, где рассчитывается абсолютное время выполнения.

Смотрите также

User Contributed Notes 25 notes

Both set_time_limit(. ) and ini_set(‘max_execution_time’. ); won’t count the time cost of sleep,file_get_contents,shell_exec,mysql_query etc, so i build this function my_background_exec(), to run static method/function in background/detached process and time is out kill it:

my_exec.php:
function my_background_exec ( $function_name , $params , $str_requires , $timeout = 600 )
< $map =array( '"' =>‘\»‘ , ‘$’ => ‘\$’ , ‘`’ => ‘\`’ , ‘\\’ => ‘\\\\’ , ‘!’ => ‘\!’ );
$str_requires = strtr ( $str_requires , $map );
$path_run = dirname ( $_SERVER [ ‘SCRIPT_FILENAME’ ]);
$my_target_exec = «/usr/bin/php -r \»chdir(‘ < $path_run >‘); < $str_requires >\\\$params=json_decode(file_get_contents(‘php://stdin’),true);call_user_func_array(‘ < $function_name >‘, \\\$params);\»» ;
$my_target_exec = strtr ( strtr ( $my_target_exec , $map ), $map );
$my_background_exec = «(/usr/bin/php -r \»chdir(‘ < $path_run >‘); < $str_requires >my_timeout_exec(\\\» < $my_target_exec >\\\», file_get_contents(‘php://stdin’), < $timeout >);\» my_timeout_exec ( $my_background_exec , json_encode ( $params ), 2 );
>

function my_timeout_exec ( $cmd , $stdin = » , $timeout )
< $start = time ();
$stdout = » ;
$stderr = » ;
//file_put_contents(‘debug.txt’, time().’:cmd:’.$cmd.»\n», FILE_APPEND);
//file_put_contents(‘debug.txt’, time().’:stdin:’.$stdin.»\n», FILE_APPEND);

$process = proc_open ( $cmd , [[ ‘pipe’ , ‘r’ ], [ ‘pipe’ , ‘w’ ], [ ‘pipe’ , ‘w’ ]], $pipes );
if (! is_resource ( $process ))
‘1’ , ‘stdout’ => $stdout , ‘stderr’ => $stderr );
>
$status = proc_get_status ( $process );
posix_setpgid ( $status [ ‘pid’ ], $status [ ‘pid’ ]); //seperate pgid(process group id) from parent’s pgid

stream_set_blocking ( $pipes [ 0 ], 0 );
stream_set_blocking ( $pipes [ 1 ], 0 );
stream_set_blocking ( $pipes [ 2 ], 0 );
fwrite ( $pipes [ 0 ], $stdin );
fclose ( $pipes [ 0 ]);

if ( time ()- $start > $timeout )
< //proc_terminate($process, 9); //only terminate subprocess, won't terminate sub-subprocess
posix_kill (- $status [ ‘pid’ ], 9 ); //sends SIGKILL to all processes inside group(negative means GPID, all subprocesses share the top process group, except nested my_timeout_exec)
//file_put_contents(‘debug.txt’, time().»:kill group \n», FILE_APPEND);
return array( ‘return’ => ‘1’ , ‘stdout’ => $stdout , ‘stderr’ => $stderr );
>

$status = proc_get_status ( $process );
//file_put_contents(‘debug.txt’, time().’:status:’.var_export($status, true).»\n»;
if (! $status [ ‘running’ ])
< fclose ( $pipes [ 1 ]);
fclose ( $pipes [ 2 ]);
proc_close ( $process );
return $status [ ‘exitcode’ ];
>

Читайте также:  Php string get one char

usleep ( 100000 );
>
>
?>

a_class.php:
class A
static function jack ( $a , $b )
< sleep ( 4 );
file_put_contents ( ‘debug.txt’ , time (). «:A::jack:» . $a . ‘ ‘ . $b . «\n» , FILE_APPEND );
sleep ( 15 );
>
>
?>

test.php:
require ‘my_exec.php’ ;

my_background_exec ( ‘A::jack’ , array( ‘hello’ , ‘jack’ ), ‘require «my_exec.php»;require «a_class.php»;’ , 8 );
?>

Источник

Php увеличить время ожидания ответа

Timeouts are a rarely discussed topic and neglected in many applications, even though they can have a huge effect on your site during times of high load and when dependent services are slow. For microservice architectures timeouts are important to avoid cascading failures when a service is down.

The default socket timeout in PHP is 60 seconds. HTTP requests performed with for example file_get_contents , fopen , SOAPClient or DOMDocument::load are using this timeout INI setting to decide how long to wait for a response.

Since the socket/stream wait time is not included in PHPs max execution time you are in line for a surprise when requests take up to 30+60=90 seconds of your webservers precious processing queue before getting aborted.

Timeouts are scary, because you don’t know in what state you have left an operation when aborting. But in case of HTTP requests it is usually easy as a client to decide what to do:

  1. Abort my own request and show the user an error
  2. Ignore the timeout and just don’t display the data
  3. Retry (a maximum of 3-5 times for example)

And configuring timeouts has other upsites:

  • If the target server currently has load problems, then aborting with a timeout early could reduce the servers load by enough to automatically recover at some point.
  • You can show users an error quickly and they don’t have to wait several seconds only to be taunted by an error page.

Setting the default timeout

Before doing anything else, you should decrease the default timeout early in your code to a value between 5 and 10 seconds:

You should check your monitoring system (for example Tideways) for clues what a regular HTTP call duration is for calls to internal or third party systems.

If you have many different internal or third-party services in place, then it makes sense to configure individual timeouts based on their usual latency.

A thorough setup defines maximum limits for each internal and third party service and then encodes them in HTTP calls.

Configuring the timeout for individual file_get_contents/fopen calls

In stream based calls you can configure individual timeouts using stream contexts. This applies to for example file_get_contents and fopen :

 array( 'timeout' => 1.0, 'ignore_errors' => true, ))); $data = @file_get_contents("http://127.0.0.1/api", false, $context); if ($data === false && count($http_response_header) === 0) < // request timed out, because $data is false even though we ignore // errors and we dont have response headers >

Be aware the timeout handling of streams seems not very accurate and requests can still take longer than you configured, especially when you go below 1 second.

Читайте также:  Комментарии html горячие клавиши

Configuring the timeout for DOMDocument::load

In general you should not use the DOMDocument::load function to load remove XML or HTML. To allow for better error handling code its easier to use a HTTP client directly and then load with loadXML . But if you must use it or some library does, you can configure timeouts with stream contexts again in this way:

 array('timeout' => 1.0))); libxml_set_streams_context($context); $document = new DOMDocument(); $document->load('http://127.0.0.1/xml'); 

This affects all HTTP calls that PHP does through libxml.

Configuring the timeout for SOAPClient

The SOAPClient class does not use the PHP stream API for historical reasons. This means that timeout configuration works slightly different. Setting the timeout parameter in SOAP Clients stream context does not work.

Instead you can either set the connection_timeout setting that handles timeouts before the connection was established or directly set default_socket_timeout in the code using ini_set. The only other way is to overwrite SoapClient::__doRequest method to use cURL.

 1)); try < $client->add(10, 10); > catch (SOAPFault $e) < if (strpos($e->getMessage(), 'Error Fetching http headers') !== false) < // this can be a timeout! >> 

Configuring the timeout for cURL extension

If you want to have more control about HTTP requests than with PHPs built in stream support there is no way around the cURL extension.

We have much better timeout control with cURL, with two settings one for the connection timeout and one for the maximum execution time:

If you want to be more strict and abort on a millisecond level, then you can alternatively use CURLOPT_TIMEOUT_MS and CURLOPT_CONNECTTIMEOUT_MS constants, but the manual warns that this might still only be checked every full second depending on how cURL was compiled and setting a value below one second usually requires to ignore signals with curl_setopt($ch, CURLOPT_NOSIGNAL, 1); to avoid an immediate timeout error.

One important thing to remember is cURL has an indefinite timeout by default and does not obey the default_socket_timeout INI setting. This means that you have to configure the timeout in every cURL call in your code. With third party code this might even be complicated or impossible.

Источник

Setting Curl’s Timeout in PHP

I’m running a curl request on an eXist database through php. The dataset is very large, and as a result, the database consistently takes a long amount of time to return an XML response. To fix that, we set up a curl request, with what is supposed to be a long timeout.

$ch = curl_init(); $headers["Content-Length"] = strlen($postString); $headers["User-Agent"] = "Curl/1.0"; curl_setopt($ch, CURLOPT_URL, $requestUrl); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERPWD, 'admin:'); curl_setopt($ch,CURLOPT_TIMEOUT,1000); $response = curl_exec($ch); curl_close($ch); 

However, the curl request consistently ends before the request is completed (

Читайте также:  Vectors in java util

7 Answers 7

CURLOPT_CONNECTTIMEOUT — The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.
CURLOPT_TIMEOUT — The maximum number of seconds to allow cURL functions to execute.

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds 

also don’t forget to enlarge time execution of php script self:

set_time_limit(0);// to infinity for example 

@PedroLobito what you mention is the default config of the php on cli, but it is possible that this may have been modified.

@cherouvim is obviously correct here (just run php -d max_execution_time=1 -r ‘while(true)’ or something to observe in action that the cli does not have a magic ‘always unlimited’ flag.

CURLOPT_CONNECTTIMEOUT = 0 doesn’t mean «indefinitely» curl.se/libcurl/c/CURLOPT_CONNECTTIMEOUT.html «Set to zero to switch to the default built-in connection timeout — 300 seconds.»

Hmm, it looks to me like CURLOPT_TIMEOUT defines the amount of time that any cURL function is allowed to take to execute. I think you should actually be looking at CURLOPT_CONNECTTIMEOUT instead, since that tells cURL the maximum amount of time to wait for the connection to complete.

While the docs in PHP say CURLOPT_TIMEOUT is about how long the function takes, the underlying curl library docs seem to say it’s about how long the request takes, which is an interesting distinction — not sure which way to read that!

There is a quirk with this that might be relevant for some people. From the PHP docs comments.

If you want cURL to timeout in less than one second, you can use CURLOPT_TIMEOUT_MS , although there is a bug/»feature» on «Unix-like systems» that causes libcurl to timeout immediately if the value is < 1000 ms with the error "cURL Error (28): Timeout was reached". The explanation for this behavior is:

«If libcurl is built to use the standard system name resolver, that portion of the transfer will still use full-second resolution for timeouts with a minimum timeout allowed of one second.»

What this means to PHP developers is «You can’t use this function without testing it first, because you can’t tell if libcurl is using the standard system name resolver (but you can be pretty sure it is)»

The problem is that on (Li|U)nix, when libcurl uses the standard name resolver, a SIGALRM is raised during name resolution which libcurl thinks is the timeout alarm.

The solution is to disable signals using CURLOPT_NOSIGNAL. Here’s an example script that requests itself causing a 10-second delay so you can test timeouts:

if (!isset($_GET['foo'])) < // Client $ch = curl_init('http://localhost/test/test_timeout.php?foo=bar'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); $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."; >

Источник

Оцените статью