Search code examples
phpfile-get-contentsconnection-timeout

Timeout for file_get_contents don't works in PHP


I created a class to englobe some HTTP methods in PHP. Here, I have a method for HTTP POST

public function post ($content, $timeout=null)
{
    $timeInit = new DateTime();

    $this->method = 'POST';


    $header = array();
    $header['header'] = null;
    $header['content'] = is_array($content) ? http_build_query($content) : $content;
    $header['method'] = $this->method;
    if ($timeout != NULL) {
        $header['header'] .= "timeout: $timeout"
    }
    $header['header'] .= "Content-length: ".strlen($header['content']);


    $headerContext =  stream_context_create(array('http' => $header));
    $contents = file_get_contents($this->url, false, $headerContext);
    $this->responseHeader = $http_response_header;

    $timeFinal = new DateTime();
    $this->time = $timeInit->diff($timeFinal);

    return $contents;
}

Basically, I create a $header and use file_get_contents to POST some $content into a URL. Aparently, all works fine, except for $timeout. It is not considered. Even when I set it to 1, for example.

I don't see anything wrong and I can't get the headers that I'm sending.

Other similar questions here in SO, suggests to use Curl (I was using it, but I'm changing for file_get_contents for other reasons) or fsockopen, but this is not that I need.

Exists some way to set timeout using file_get_contents?


Solution

  • for stream_context_create() http://php.net/manual/en/function.stream-context-create.php it needs [ array $options [, array $params ]] when you pass your $header it doesnt appear that your building the array correctly. would something like this work?

    public function myPost($content, $timeout = null)
    {
        $timeInit = new DateTime();
    
        $this->method = 'POST';
    
    
        $header = array();
        $header['header'] = null;
        $header['content'] = is_array($content) ? http_build_query($content) : $content;
        $header['method'] = $this->method;
    
        if ($timeout) {
            $header['header']['timeout'] = $timeout;
        }
    
        $header['header']['Content-length'] . strlen($header['content']);
        $headerContext = stream_context_create(array('http' => $header));
        $contents = file_get_contents($this->url, false, $headerContext);
        $this->responseHeader = $http_response_header;
    
        $timeFinal = new DateTime();
        $this->time = $timeInit->diff($timeFinal);
    
        return $contents;
    }
    

    but a better way would be to use it like the example says, e.g.

    $timeInit = new DateTime();
    
    // all your defaults go here
    $opts = array(
        'http'=>array(
            'method'=>"POST",
        )
    );
    
    //this way, inside conditions if you want
    $opts['http']['header']  = "Accept-language: en\r\n" .  "Cookie: foo=bar\r\n";
    $context = stream_context_create($opts);