1

You can measure execution time in php using:

  $inicio = microtime(true);
  ejecutoFunction();
  $fin = microtime(true);
  //here getting the time passed
  $tiempo = $inicio - $fin;
  if($tiempo > $tiempo_limite) {//print it or do something else}

however verification happened "post-mortem", method ended before $tiempo is calculated, so it doesn't helps like this, because I need something that stops execution if it is taking more than x time. For instance,a function that performs a POST request to some URL and it is taking more than 10 sec to respond.

In a very mine fake code would be like this:

ejecutoFunction1(){
$timer = 0 seconds;
if $timer reaches 10 seconds{break ejecutoFunction1; ejecutoOtraFunction2();}
start $timer; //timer starts and allow executions until he reaches value 10.

{body of ejecutoFunction1}

}

How do I do that in real code in PHP ???? I know it is not easy (for me), but world class minds are reading here. Thanks in advance

Laynier Piedra
  • 425
  • 6
  • 16
  • https://www.php.net/manual/en/function.set-time-limit.php – Felippe Duarte Feb 01 '21 at 18:59
  • Does this answer your question? [How can I measure the speed of code written in PHP?](https://stackoverflow.com/questions/1200214/how-can-i-measure-the-speed-of-code-written-in-php) – nice_dev Feb 01 '21 at 19:01
  • See also: http://xdebug.org/docs/profiler – nice_dev Feb 01 '21 at 19:02
  • Please note that set_time_limits "If this is reached, the script returns a fatal error. " and I need to continue execution of script with other functions when limit time is reached. – Laynier Piedra Feb 01 '21 at 19:07
  • I _think_ you want to run your code in a background task that you can control better, right? – Chris Haas Feb 01 '21 at 19:15
  • 3
    PHP is single-threaded, so there is no way to time-out a function from the outside, or when a blocking operation is happening. Some PHP core or module functions have timeouts that can be set, but those are implemented in C. – Sammitch Feb 01 '21 at 20:21
  • The title of your question is misleading. Your problem is not related to measuring time. Your problem is how to interrupt something if it hasn't finished after a certain amount of time. I guess what you are really looking for is a timeout for the expensive thing your doing inside your function. So we need to know what that function does. I assume it is IO related. So maybe you just need to set a curl timeout or a database connection timeout... – simon.ro Feb 01 '21 at 21:49
  • It is a POST request to some URL and wait for response. – Laynier Piedra Feb 01 '21 at 21:58
  • Also Simon, I edited title and wrote what I want to stop. Thanks. – Laynier Piedra Feb 01 '21 at 22:05
  • Much better title! Well then. Whatever library you use to issue that POST request, most certainly it uses curl under the hood and most probably you'll find a timeout option in the docs. – simon.ro Feb 01 '21 at 22:12

2 Answers2

0

If I understand you correctly, you are not looking for anything like set_time_limit as that will kill your entire script. You are looking for a "kill switch" in a loop. It will resemble a "game loop" type structure where it will run the logic inside until a condition is met (i.e. the kill switch).


   // Check if $max number of seconds has elapsed
   function hasReachedTimeout($start, $max = 10) {
      $elapsed = microtime(true) - $start;
      if ($elapsed > $max) { return true; }
      return false;
   }
   
   function myFunction() {
      $start = microtime(true);
      while (!hasReachedTimeout($start, 10)) {
          doFirstThing();
          if (hasReachedTimeout($start, 10)) { break; }
          doSecondThing();
          if (hasReachedTimeout($start, 10)) { break; }
          doThirdThing();
      }
   }

That does a check after each function call just in case and breaks out of the loop. You could also just let the while loop stop if after executing everything inside the timeout has exceeded.

Jeremy Harris
  • 24,318
  • 13
  • 79
  • 133
  • It is not a loop what the function has inside... Actually it is a post call, and I need to cancel the call and execute other function if response takes too much to arrive to me. Also, I think you mean: "while (!hasReachedTimeout(**$startTime**, 10))" right_? I'll give it a try anyway and come back to you... thanks! – Laynier Piedra Feb 01 '21 at 20:28
  • Ah yep, didn't name the variable the same. Fixed it. – Jeremy Harris Feb 01 '21 at 20:39
  • Ok, but see: Your code will execute doFirstThing() anyway, even if it takes more than 10 seconds, and that is what I want to avoid. However It was a clever answer. Any other solution? – Laynier Piedra Feb 01 '21 at 20:58
  • Are you using cURL or how exactly are you issuing this POST request? – Muc Feb 02 '21 at 14:32
  • @Muc I am using simple Js like this: **document.MethodForm.submit();** – Laynier Piedra Feb 02 '21 at 14:49
  • 1
    Oh... I thought you were issuing the POST request from within PHP (To a 3rd party webservice or something)... I don't see any way around it but to isolate the problematic code inside it's own php which you can call from the main one using cURL and setting curl_setopt($ch,CURLOPT_TIMEOUT, X);... kind of complicated but should do the trick – Muc Feb 02 '21 at 19:19
0

As a post call is sent inside, and has to be stopped after sometime, but we need to know that the time limit was reached, solution(and thanks to @muc) would be like this steps:

1-Outside the method: stays like before:

  $inicio = microtime(true);
  ejecutoFunction();
  $fin = microtime(true);
  //here getting the time passed
  $tiempo = $inicio - $fin;
  if($tiempo > 10) {echo "Too much time!";}

2-inside ejecutoFunction() USE cURL timeout option!!!*(borrowed example)

    $html_brand = "www.google.com";
    $tData = '123';
    $ch = curl_init();

$options = array(
    CURLOPT_URL            => $html_brand,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER         => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_POST => 1,
    CURLOPT_POSTFIELDS => $tData,
    CURLOPT_AUTOREFERER    => true,
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 11,
    CURLOPT_MAXREDIRS      => 10,
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch); 
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ( $httpCode != 200 ){
    echo "Return code is {$httpCode} \n"
        .curl_error($ch);
} else {
    echo "<pre>".htmlspecialchars($response)."</pre>";
}

curl_close($ch);

Thanks again to @muc. I didn't know about this PHP library.

Laynier Piedra
  • 425
  • 6
  • 16