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

Может это быть твоей проблемой?

Примечание. Если вы открываете URI со специальными символами, такими как пробелы, вам необходимо закодировать URI с помощью urlencode ().

Тихий призрак
источник
У меня была та же ошибка, что и у 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);

Это сработало для меня

d_bhatnagar
источник
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, это устранило мою проблему, большое спасибо!
Нигго,
-3

Использовать это

file_get_contents($my_url,null,null);
Амит Чавла
источник