2

I have a php file called testResponse.php which is only :

<?php
 sleep(5);
 echo"go";
?>

Now, I'm calling this file from a another page using file_get_contents like this :

$start= microtime(true);
$opts = array('http' =>
    array(
        'method'  => 'GET',
        'timeout' => 1
    )
);

$context  = stream_context_create($opts);

$loc = @file_get_contents("http://www.mywebsite.com/testResponse.php", false, $context);
$end= microtime(true);
echo $end - $start, "\n";

The output is more than 5 sec, which means that my timeout has been ignored... I followed the advice of this post : stackoverflow.com/questions/3689371

But it seems that hostname cannot be a path (like www.mywebsite.com/testResponse.php) but directly the hostname like www.mywebsite.com.

So I'm stuck to achieve this goal :

Get content of page www.test.com/x.php with constraint :

  • if test.com doesn't exist or the page x.php doesn't exist returns nothing quickly
  • if the page exist but takes more than 1 sec to load, abort
  • else get the content of the file

Edit : By the way, it seems to work when I call this page (testResponse.php) from my local server. Well, it multiply the timeout by 2. For instance, If I have 1 for timeout, I will have echoed something like "2.0054645". But only from local...

Community
  • 1
  • 1
Mansur Khan
  • 1,675
  • 1
  • 12
  • 24

1 Answers1

4

The solution is to use PHP's cURL functions. The other question you linked to explains things properly, about the read timeouts vs. the connection timeouts, and so on, but neither of those are truly what you're looking for here. Even the connection timeout won't work, because the connection to testResponse.php is always successful; after that it's waiting, so what you need is an execution timeout. This is where cURL comes in handy.

So, testResponse.php doesn't need to be altered. In your main file, though, try the following code (this is tested and it works on my server):

$start = microtime(true);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.mywebsite.com/testResponse.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$output = curl_exec($ch);
$errno = curl_errno($ch);
if ($errno > 0) {
    if ($errno === 28) {
        echo "Connection timed out.";
    }
    else {
        echo "Error #" . $errno . ": " . curl_error($ch);
    }
}
else {
    echo $output;
}
$end = microtime(true);
echo "<br><br>" . ($end - $start);
curl_close($ch);

This sets the execution time of the cURL session, via the CURLOPT_TIMEOUT option you see on line 5. So, when the connection is timed out, $errno will equal 28, the code for cURL's operation timeout error. The rest of the error codes are listed in the cURL documentation, so you can expand the script above to act accordingly.

Finally, because of the CURLOPT_RETURNTRANSFER option that's set, curl_exec($ch) will be set to the content of the retrieved page if the session succeeds. Otherwise, it will equal false.

Hope this helps!

Edit: Removed the statement setting CURLOPT_HEADER. I also, for some reason, was under the impression that curl_exec($ch) set the value of $ch to the returned contents, forgetting that the contents are returned by curl_exec().

theftprevention
  • 5,083
  • 3
  • 18
  • 31
  • It seems it is almost good. To use a timeout less than 1 sec, I used `curl_setopt($ch, CURLOPT_NOSIGNAL, 1); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 3000);`. Is it OK? And also, how do I get the content of the page ? In my case it's an XML. `echo $ch;` is returning : "Resource id #8" – Mansur Khan Sep 18 '13 at 16:03
  • `CURLOPT_TIMEOUT_MS` should be fine, but depending on your version of PHP, that constant [**might not actually be set properly**](http://www.php.net/manual/en/function.curl-setopt.php#107314), and you might have to use the integer `155` instead of the constant. As for the XML, once you've retrieved `$ch`, you can create a new XML element like so: `$xml = new SimpleXMLElement($ch);` See [**this answer**](http://stackoverflow.com/questions/561816/php-curl-extract-an-xml-response) for more details. – theftprevention Sep 18 '13 at 16:11
  • Ok I found it. I had to remove `curl_setopt($ch, CURLOPT_HEADER, true);` and also the content is returned by `curl_exec($ch);`. THanks mate – Mansur Khan Sep 18 '13 at 16:30