Подтвердить что ты не робот

Как получить реальный URL-адрес после file_get_contents, если произойдет перенаправление?

Я использую file_get_contents() для захвата контента с сайта, и это удивительно работает, даже если URL-адрес, который я передаю как аргумент, перенаправляется на другой URL-адрес.

Проблема в том, что мне нужно знать новый URL-адрес, есть ли способ сделать это?

4b9b3361

Ответ 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);