Как получить реальный URL-адрес после file_get_contents, если произойдет перенаправление?
Я использую file_get_contents()
для захвата контента с сайта, и это удивительно работает, даже если URL-адрес, который я передаю как аргумент, перенаправляется на другой URL-адрес.
Проблема в том, что мне нужно знать новый URL-адрес, есть ли способ сделать это?
Ответы
Ответ 1
Вы можете сделать запрос с cURL вместо file_get_contents()
.
Что-то вроде этого должно работать...
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$a = curl_exec($ch);
if(preg_match('#Location: (.*)#', $a, $r))
$l = trim($r[1]);
Источник
Ответ 2
Если вам нужно использовать file_get_contents()
вместо завивки, не следует автоматически переадресации:
$context = stream_context_create(
array(
'http' => array(
'follow_location' => false
)
)
);
$html = file_get_contents('http://www.example.com/', false, $context);
var_dump($http_response_header);
Ответ, вдохновленный: Как игнорировать перемещенный заголовок с файлом_get_contents в PHP?
Ответ 3
Все в одной функции:
function get_web_page( $url ) {
$res = array();
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // do not return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_USERAGENT => "spider", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$res['content'] = $content;
$res['url'] = $header['url'];
return $res;
}
print_r(get_web_page("http://www.example.com/redirectfrom"));
Ответ 4
Полное решение с использованием bare file_get_contents
(обратите внимание на параметр out-out $url
):
function get_url_contents_and_final_url(&$url)
{
do
{
$context = stream_context_create(
array(
"http" => array(
"follow_location" => false,
),
)
);
$result = file_get_contents($url, false, $context);
$pattern = "/^Location:\s*(.*)$/i";
$location_headers = preg_grep($pattern, $http_response_header);
if (!empty($location_headers) &&
preg_match($pattern, array_values($location_headers)[0], $matches))
{
$url = $matches[1];
$repeat = true;
}
else
{
$repeat = false;
}
}
while ($repeat);
return $result;
}
Обратите внимание, что это работает только с абсолютным URL-адресом в заголовке Location
. Если вам нужно поддерживать относительные URL-адреса, см. PHP: как разрешить относительный URL-адрес.
Например, если вы используете решение из ответа от @Joyce Babu, замените:
$url = $matches[1];
с:
$url = getAbsoluteURL($matches[1], $url);