file_get_contents 的超时不适用于 PHP

Timeout for file_get_contents don't works in PHP

我创建了一个 class 以在 PHP 中包含一些 HTTP 方法。在这里,我有一个用于 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;
}

基本上,我创建了一个 $header 并使用 file_get_contents 将一些 $content POST 变成了 URL。 显然,除了 $timeout 之外,一切正常。不予考虑。例如,即使我将其设置为 1。

我没有发现任何错误,也无法收到我发送的 header。

SO 中的其他类似问题,建议使用 Curl(我正在使用它,但由于其他原因我正在更改 file_get_contents)或 fsockopen,但这不是我需要的。

是否存在使用 file_get_contents 设置超时的方法?

当然有,但是您的上下文 options 不正确,请检查以下示例:

<?php

set_time_limit(0);
ignore_user_abort(1);

$opts = array('http' =>
  array(
    'method'=>"POST",
    'timeout' => 60
  )
);

$context  = stream_context_create($opts);
$result = file_get_contents($url, false, $context);

注:

根据远程服务器配置,您可能需要在上下文选项中设置 Content-LengthContent-type


参考文献:

file_get_contents

对于 stream_context_create() http://php.net/manual/en/function.stream-context-create.php 它需要 [ array $options [, array $params ]] 当您通过 $header 时,您似乎没有正确构建数组。这样的东西行得通吗?

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;
}

但更好的方法是像示例中所说的那样使用它,例如

$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);