PHP file_get_contents()返回“无法打开流:HTTP请求失败!”


91

我在从PHP代码调用URL时遇到问题。我需要使用我的PHP代码中的查询字符串来调用服务。如果我在浏览器中键入url,它可以正常工作,但是如果我使用file-get-contents()进行调用,则会得到:

警告:file-get-contents(http:// ....)无法打开流:HTTP请求失败!HTTP / 1.1 202接受...

我使用的代码是:

$query=file_get_contents('http://###.##.##.##/mp/get?mpsrc=http://mybucket.s3.amazonaws.com/11111.mpg&mpaction=convert format=flv');
echo($query);

就像我说的那样-从浏览器中调用即可正常运行。有什么建议?

我也尝试了另一个网址,例如:

$query=file_get_contents('http://www.youtube.com/watch?v=XiFrfeJ8dKM');

效果很好...可能是我需要调用的网址中包含第二个网址http://吗?

Answers:


111

尝试使用cURL。

<?php

$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_URL,'http://###.##.##.##/mp/get?mpsrc=http://mybucket.s3.amazonaws.com/11111.mpg&mpaction=convert format=flv');
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Your application name');
$query = curl_exec($curl_handle);
curl_close($curl_handle);

?>

10
当真正的问题在于“&”号时,这太复杂了。
基督教徒

1
@Christian,您能详细说说吗?
vonUbisch 2015年

4
并非每个人都(但应该)安装了cURL。当然,cURL的速度要快很多倍,但是file_get_contents也没有那么慢,并且不需要每次使用时都记住所有选项。
基督教徒

1
CURLOPT_USERAGENT是在我的情况非常重要的,谢谢!
情绪化,2016年

我相信我的问题是它超时了,并且此问题得以解决。谢谢!
evadecaptcha

28

我在OP中遇到了同样的错误,这就是我的问题-参数中的空格。 urlencode()关于GET参数解决了这个问题。
Walt W 2010年

如果您不想使用CURL解决方案,那么可以使用该解决方案!在参数上使用URLecnode。
亚伦·贡

这是此问题的实际解决方案。
Henrik Petterson

23
<?php

$lurl=get_fcontent("http://ip2.cc/?api=cname&ip=84.228.229.81");
echo"cid:".$lurl[0]."<BR>";


function get_fcontent( $url,  $javascript_loop = 0, $timeout = 5 ) {
    $url = str_replace( "&amp;", "&", urldecode(trim($url)) );

    $cookie = tempnam ("/tmp", "CURLCOOKIE");
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1" );
    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookie );
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
    curl_setopt( $ch, CURLOPT_ENCODING, "" );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );    # required for https urls
    curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
    curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
    curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
    $content = curl_exec( $ch );
    $response = curl_getinfo( $ch );
    curl_close ( $ch );

    if ($response['http_code'] == 301 || $response['http_code'] == 302) {
        ini_set("user_agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1");

        if ( $headers = get_headers($response['url']) ) {
            foreach( $headers as $value ) {
                if ( substr( strtolower($value), 0, 9 ) == "location:" )
                    return get_url( trim( substr( $value, 9, strlen($value) ) ) );
            }
        }
    }

    if (    ( preg_match("/>[[:space:]]+window\.location\.replace\('(.*)'\)/i", $content, $value) || preg_match("/>[[:space:]]+window\.location\=\"(.*)\"/i", $content, $value) ) && $javascript_loop < 5) {
        return get_url( $value[1], $javascript_loop+1 );
    } else {
        return array( $content, $response );
    }
}


?>

5
感谢您提供的代码,您似乎是从以下位置获得的:php.net/manual/en/ref.curl.php主要问题是函数调用get_url实际上应该是get_fcontent因为您更改了函数本身的名称。这实际上是一个递归函数调用,它通过更改一些参数来重新尝试获取URL内容。
SSH

你说对了!正在尝试https并且被拒绝了。你钉了它。已更新;)
托尼·吉尔

21

file_get_contents()利用fopen()包装器,因此限制了通过allow_url_fopenphp.ini中的选项访问URL 。

您可能需要更改php.ini才能启用此选项,或者使用替代方法,即cURL-到目前为止,这是最流行且坦率地说是完成您要执行的操作的标准方法。


没关系,只是注意到他说file_get_contents()使用其他URL。但是,对于其他遇到此问题的人来说,这仍然是一个很好的技巧。
Michael Wales

是的,我已经查看了其他选项,并看到cURL是标准的处理方式,但是我尝试了此操作,因为它更容易并且可以与其他url一起使用,我想我必须重新启动apache才能安装intall cURL吗?并无法弄清楚该怎么做(另一个问题)...感谢您的快速回复
未定义,2009年

11

基本上,您需要随请求发送一些信息。

试试这个,

$opts = array('http'=>array('header' => "User-Agent:MyAgent/1.0\r\n")); 
//Basically adding headers to the request
$context = stream_context_create($opts);
$html = file_get_contents($url,false,$context);
$html = htmlspecialchars($html);

这对我来说很有效


2
这也对我有用!看起来它需要一个用户代理
bryan

如果该网址似乎已正确编码,则很可能是问题所在。某些站点将限制“用户代理”,也可能会限制“接受”。
Jahmic

1
超级答案。投票支持将这一活动推向最高。所有在PHP中,也为https请求工作。仅有两行代码。如果共享服务器确实提供卷曲怎么办?这非常有帮助。
ndasusers

9

我注意到您的网址中有空格。我认为通常这是一件坏事。尝试使用

$my_url = urlencode("my url");

然后打电话

file_get_contents($my_url);

看看你是否有更好的运气。


4

我遇到了类似的问题,我解析了youtube网址。该代码是;

$json_is = "http://gdata.youtube.com/feeds/api/videos?q=".$this->video_url."&max-results=1&alt=json";
$video_info = json_decode ( file_get_contents ( $json_is ), true );     
$video_title = is_array ( $video_info ) ? $video_info ['feed'] ['entry'] [0] ['title'] ['$t'] : '';

然后我意识到$this->video_url包括空格。我用解决了trim($this->video_url)

也许会帮到你。祝好运


3

我不确定参数(mpaction,格式),如果它们是为amazonaws页面或##。##指定的。

尝试urlencode()网址。


谢谢-这些是mediaplug实例的参数。如果我对网址进行urlencode仍然无法正常工作-我在错误中得到一个非常乱码的网址... ??
不确定

您应该只对参数字符串进行编码:“转换格式”应为“ convert%20format”(或“ convert + format”)。
bobince

2
$query=file_get_contents('http://###.##.##.##/mp/get?' . http_build_query(array('mpsrc' => 'http://mybucket.s3.amazonaws.com/11111.mpg&mpaction=convert format=flv')));

2

我遇到了类似的问题。

由于超时!

超时可以这样表示:

$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => "POST",
        'content' => http_build_query($data2),
        'timeout' => 30,
    ),
);
$context = stream_context_create($options); $retour =
$retour = @file_get_contents("http://xxxxx.xxx/xxxx", false, $context);

大声笑,解决了我的问题,非常感谢!
黑哥

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.