J'utilise file_get_contents()
pour récupérer le contenu d'un site, et étonnamment cela fonctionne même si l'URL que je passe en argument redirige vers une autre URL.
Le problème est que j'ai besoin de connaître la nouvelle URL, existe-t-il un moyen de le faire?
Vous pouvez faire une demande avec cURL au lieu de file_get_contents()
.
Quelque chose comme ça devrait fonctionner ...
$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]);
Si vous devez utiliser file_get_contents()
au lieu de curl, ne suivez pas automatiquement les redirections:
$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);
Réponse inspirée par: Comment ignorer un en-tête déplacé avec file_get_contents en PHP?
Tout dans une seule fonction:
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"));
Une solution complète utilisant le nu file_get_contents
(notez l'entrée-sortie $url
paramètre):
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;
}
Notez que cela ne fonctionne qu'avec une URL absolue dans l'en-tête Location
. Si vous devez prendre en charge des URL relatives, consultez PHP: Comment résoudre une URL relative .
Par exemple, si vous utilisez la solution du réponse de @Joyce Bab , remplacez:
$url = $matches[1];
avec:
$url = getAbsoluteURL($matches[1], $url);