PHP file_get_contents () renvoie "échec de l'ouverture du flux: échec de la requête HTTP!"

91

J'ai des problèmes pour appeler une URL à partir de code PHP. J'ai besoin d'appeler un service en utilisant une chaîne de requête de mon code PHP. Si je tape l'url dans un navigateur, cela fonctionne bien, mais si j'utilise file-get-contents () pour faire l'appel, j'obtiens:

Avertissement: file-get-contents (http: // ....) n'a pas pu ouvrir le flux: la requête HTTP a échoué! HTTP / 1.1 202 Accepté dans ...

Le code que j'utilise est:

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

Comme je l'ai dit - appelez depuis le navigateur et cela fonctionne très bien. Aucune suggestion?

J'ai également essayé avec une autre URL telle que:

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

Cela fonctionne bien ... est-ce que l'URL que j'ai besoin d'appeler en contient une seconde http://?

indéfini
la source

Réponses:

110

Essayez d'utiliser 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);

?>
James Hall
la source
10
C'est bien trop compliqué lorsque le vrai problème se situe dans les esperluettes.
Christian
1
@Christian, pouvez-vous élaborer?
vonUbisch
4
Tout le monde n'a pas (mais devrait cependant) installer cURL. cURL est bien sûr plusieurs fois plus rapide, mais file_get_contents n'est pas si lent non plus et ne nécessite pas que vous vous souveniez de toutes les options chaque fois que vous l'utilisez.
Christian
1
C'était CURLOPT_USERAGENTtrès important dans mon cas, merci!
emotality
Je crois que mon problème était avec le délai d'expiration et cela l'a résolu. Je vous remercie!
evadecaptcha
28

Cela pourrait-il être votre problème?

Remarque: Si vous ouvrez un URI avec des caractères spéciaux, tels que des espaces, vous devez encoder l'URI avec urlencode ().

SilentGhost
la source
J'ai eu la même erreur que l'OP, et c'était mon problème - des espaces dans les arguments. urlencode()sur les paramètres GET a résolu le problème.
Walt W
Si vous ne souhaitez pas utiliser la solution CURL, celle-ci fonctionne! Utilisez l'URLecnode sur les paramètres.
Aaron Gong
C'est la vraie solution à ce problème.
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 );
    }
}


?>
pangeli
la source
5
Merci pour le code, on dirait que vous l'avez obtenu à partir de: php.net/manual/en/ref.curl.php Le problème principal est que l'appel de la fonction get_urldevrait en fait être get_fcontentpuisque vous avez changé le nom de la fonction elle-même. Il s'agit en fait d'un appel de fonction récursif qui tente à nouveau d'obtenir le contenu de l'URL en modifiant certains paramètres.
SSH ce
tu l'as eu! essayait de https et était refusé. Vous avez réussi. UPVOTED;)
tony gil
21

file_get_contents()utilise les fopen()wrappers, il est donc interdit d'accéder aux URL via l' allow_url_fopenoption dans php.ini.

Vous devrez soit modifier votre php.ini pour activer cette option, soit utiliser une méthode alternative, à savoir cURL - de loin le moyen le plus populaire et, pour être honnête, standard d'accomplir ce que vous essayez de faire.

Michael Wales
la source
Peu importe, je viens de remarquer qu'il a dit qu'il file_get_contents()travaillait sur une URL différente. Néanmoins, c'est toujours un bon conseil pour les autres ayant ce problème.
Michael Wales
oui, j'ai regardé d'autres options et j'ai vu que cURL est la méthode standard, mais j'ai essayé cela car c'était plus facile et fonctionnait avec d'autres URL, je pense que je dois redémarrer apache pour intsall cURL? et je ne sais pas comment faire cela (une autre question) ... merci pour votre réponse rapide
undefined
11

Vous devez essentiellement envoyer des informations avec la demande.

Essaye ça,

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

Cela a fonctionné pour moi

d_bhatnagar
la source
2
Cela a fonctionné pour moi aussi! On dirait qu'il avait besoin d'un agent utilisateur
bryan
Si l'URL semble correctement codée, cela pourrait très bien être le problème. Certains sites restreindront «User-Agent», peut-être «Accepter» également.
Jahmic le
1
super réponse. votez pour promouvoir celui-ci au sommet. tout en php et a également fonctionné pour la demande https. juste deux lignes de code supplémentaires. Et si le serveur partagé fournissait curl? c'est très utile.
ndasusers
9

Je remarque que votre URL contient des espaces. Je pense que c'est généralement une mauvaise chose. Essayez d'encoder l'URL avec

$my_url = urlencode("my url");

puis appeler

file_get_contents($my_url);

et voyez si vous avez plus de chance.

svelte
la source
4

J'ai eu un problème similaire, j'ai analysé l'url youtube. Le code est;

$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'] : '';

Ensuite, je me rends compte que $this->video_urlcomprennent les espaces. J'ai résolu cela en utilisant trim($this->video_url).

Peut-être que cela vous aidera. Bonne chance

Emre Karataşoğlu
la source
3

Je ne suis pas sûr des paramètres (mpaction, format), s'ils sont spécifiés pour la page amazonaws ou ##. ##.

Essayez de urlencode () l'url.

Alexn
la source
merci - ce sont des paramètres pour l'instance mediaplug. Si j'encode l'URL, cela ne fonctionne toujours pas - j'obtiens une URL très déformée dans l'erreur ... ??
undefined
Vous ne devez encoder que la chaîne de paramètres: "convert format" doit être "convert% 20format" (ou encore "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')));
Sergey
la source
2

J'ai un problème similaire.

En raison du délai d'attente!

Le délai d'expiration peut être indiqué comme ceci:

$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);
Jerry
la source
lol qui a réglé mon problème, merci beaucoup!
Niggo
-3

Utilisez ceci

file_get_contents($my_url,null,null);
Amit Chawla
la source