PHP file_get_contents () возвращает «не удалось открыть поток: HTTP-запрос не выполнен!»


91

У меня проблемы с вызовом URL из кода PHP. Мне нужно вызвать службу, используя строку запроса из моего 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);

Как я уже сказал - звоните из браузера и все работает нормально. Какие-либо предложения?

Я также пробовал использовать другой URL-адрес, например:

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

Это отлично работает ... может быть, в URL-адресе, который мне нужно вызвать, есть секунда http://?

Ответы:


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

?>

11
Это слишком сложно, когда настоящая проблема заключается в амперсандах.
Christian

1
@ Кристиан, ты можешь уточнить?
vonUbisch

4
Не у всех установлен (но должен) cURL. Конечно, cURL во много раз быстрее, но file_get_contents тоже не такой медленный и не требует, чтобы вы запоминали все параметры всякий раз, когда вы его используете.
Christian

1
В CURLOPT_USERAGENTмоем случае это было очень важно, спасибо!
эмоция 07

Я считаю, что моя проблема заключалась в том, что время ожидания истекло, и это исправило ее. Спасибо!
evadecaptcha

28

У меня была та же ошибка, что и у OP, и это была моя проблема - пробелы в аргументах. urlencode()по параметрам GET решил проблему.
Walt W

Если вы не хотите использовать решение CURL, оно работает! Используйте URLecnode для параметров.
Аарон Гонг

Это реальное решение этой проблемы.
Хенрик Петтерсон

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, но получал отказ. ты сделал это. ОБНОВЛЕНО;)
tony gil

21

file_get_contents()использует fopen()оболочки, поэтому ему запрещен доступ к URL-адресам с помощью allow_url_fopenпараметра в php.ini.

Вам нужно будет либо изменить свой php.ini, чтобы включить эту опцию, либо использовать альтернативный метод, а именно cURL - безусловно, самый популярный и, честно говоря, стандартный способ выполнить то, что вы пытаетесь сделать.


Неважно, только заметил, что он сказал, что file_get_contents()работал с другим URL. Тем не менее, это хороший совет для других, у кого есть такая проблема.
Майкл Уэльс,

да, я просмотрел другие варианты и увидел, что cURL - это стандартный способ, но я попробовал это, так как это было проще и работал с другими URL-адресами, я думаю, мне нужно перезапустить apache, чтобы intsall cURL? и не могу понять, как это сделать (другой вопрос) ... спасибо за быстрый ответ
undefined

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

Если URL-адрес закодирован правильно, это вполне может быть проблемой. Некоторые сайты будут ограничивать "User-Agent", возможно, также "Accept".
Jahmic

1
супер ответ. проголосуйте за продвижение в топ. все на php и тоже работал с запросом https. всего две лишние строки кода. что, если общий сервер предоставляет завиток? это очень полезно.
ndasusers

10

Я заметил, что в вашем URL есть пробелы. Я думаю, что это обычно плохо. Попробуйте закодировать URL с помощью

$my_url = urlencode("my url");

а затем позвонив

file_get_contents($my_url);

и посмотрите, не повезет ли вам.


4

У меня похожая проблема, я разобрал url 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, format), если они указаны для страницы amazonaws или ##. ##.

Попробуйте urlencode () URL-адрес.


спасибо - это параметры для экземпляра mediaplug. Если я кодирую URL-адрес, он все равно не работает - я получаю очень искаженный URL-адрес в ошибке ... ??
undefined

Вы должны кодировать только строку параметра: "convert format" должен быть "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);

lol, это устранило мою проблему, большое спасибо!
Нигго,

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.