2009-09-17 6 views
31

Comment puis-je obtenir l'URL de destination en utilisant cURL lorsque le code d'état HTTP est 302?Comment puis-je obtenir l'URL de destination en utilisant cURL?

<?PHP 
$url = "http://www.ecs.soton.ac.uk/news/"; 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$html = curl_exec($ch); 
$status_code = curl_getinfo($ch,CURLINFO_HTTP_CODE); 

if($status_code=302 or $status_code=301){ 
    $url = ""; 
    // I want to to get the destination url 
} 
curl_close($ch); 
?> 
+2

Avez-vous de la chance pour vos autres questions non résolues? – GZipp

+0

vous devriez accepter la bonne réponse (-1) – John

Répondre

5

Vous devez saisir l'emplacement -tête pour l'URL de redirection.

+1

Qui a besoin de plus de tracas, comme vérifier si c'est relatif, le résoudre (à l'URL de base probablement précédente dans une redirection intermédiaire s'il y a plusieurs etc. pp.), C'est juste plus facile à utiliser ['CURLINFO_EFFECTIVE_URL'] (http://stackoverflow.com/a/4917416/367456). – hakre

2

La nouvelle destination pour une redirection 302 est située dans le champ d'en-tête http "location". Exemple:

HTTP/1.1 302 Found 
Date: Tue, 30 Jun 2002 1:20:30 GMT 
Server: Apache 
Location: http://www.foobar.com/foo/bar 
Content-Type: text/html; charset=iso-8859-1 

Juste grep avec une expression régulière.

Pour inclure toutes les informations d'en-tête HTTP, incluez-le au résultat avec l'option curl CURLOPT_HEADER. Réglez-le avec:

curl_setopt($c, CURLOPT_HEADER, true); 

Si vous voulez simplement boucle à suivre la redirection utiliser CURLOPT_FOLLOWLOCATION:

curl_setopt($c, CURLOPT_FOLLOWLOCATION, true); 

Quoi qu'il en soit, vous ne devriez pas utiliser la nouvelle URI parce que HTTP statusCode 302 est seulement redirection temporaire.

1

Voici un moyen d'obtenir tous les en-têtes retournés par une requête curl http, ainsi que le code d'état et un tableau de lignes d'en-tête pour chaque en-tête.

$url = 'http://google.com'; 
$opts = array(CURLOPT_URL => $url, 
       CURLOPT_RETURNTRANSFER => true, 
       CURLOPT_HEADER => true, 
       CURLOPT_FOLLOWLOCATION => true); 

$ch = curl_init(); 
curl_setopt_array($ch, $opts); 
$return = curl_exec($ch); 
curl_close($ch); 

$headers = http_response_headers($return); 
foreach ($headers as $header) { 
    $str = http_response_code($header); 
    $hdr_arr = http_response_header_lines($header); 
    if (isset($hdr_arr['Location'])) { 
     $str .= ' - Location: ' . $hdr_arr['Location']; 
    } 
    echo $str . '<br />'; 
} 

function http_response_headers($ret_str) 
{ 
    $hdrs = array(); 
    $arr = explode("\r\n\r\n", $ret_str); 
    foreach ($arr as $each) { 
     if (substr($each, 0, 4) == 'HTTP') { 
      $hdrs[] = $each; 
     } 
    } 
    return $hdrs; 
} 

function http_response_header_lines($hdr_str) 
{ 
    $lines = explode("\n", $hdr_str); 
    $hdr_arr['status_line'] = trim(array_shift($lines)); 
    foreach ($lines as $line) { 
     list($key, $val) = explode(':', $line, 2); 
     $hdr_arr[trim($key)] = trim($val); 
    } 
    return $hdr_arr; 
} 

function http_response_code($str) 
{ 
    return substr(trim(strstr($str, ' ')), 0, 3); 
} 
0

Utilisez curl_getinfo($ch), et le premier élément (url) indiquerait l'URL efficace.

37

Vous pouvez utiliser:

echo curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); 
+0

Cette méthode est beaucoup plus propre/généralement meilleure que l'analyse de l'URL de l'en-tête de localisation. –

+10

CURLINFO_EFFECTIVE_URL renvoie la page en cours (demandée) pour moi. Il n'y a pas de redirection (Location :) dans les résultats de curl_getinfo. Il semble, pour analyser les en-têtes est la meilleure pratique ... –

+0

'CURLINFO_EFFECTIVE_URL' ne fonctionne pas toujours pour certains cas, en particulier ceux sans utiliser la redirection d'en-tête. – Raptor

21
$ch = curl_init($url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($ch, CURLOPT_HEADER, TRUE); // We'll parse redirect url from header. 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE); // We want to just get redirect url but not to follow it. 
$response = curl_exec($ch); 
preg_match_all('/^Location:(.*)$/mi', $response, $matches); 
curl_close($ch); 
echo !empty($matches[1]) ? trim($matches[1][0]) : 'No redirect found'; 
+0

parfait! Merci de partager – ladieu

+1

Et s'il n'y a pas d'en-tête de localisation? –

+0

Parfois, les sites utiliseront meta redirect ou 'window.location.replace' pour rediriger la page. Dans ce cas, remplacez l'expression régulière pour capturer le résultat. – Raptor

5

Un peu vieillotte d'une réponse, mais voulait montrer un exemple de travail complet, quelques-unes des solutions là-bas sont des pièces:

$ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); //set url 
    curl_setopt($ch, CURLOPT_HEADER, true); //get header 
    curl_setopt($ch, CURLOPT_NOBODY, true); //do not include response body 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //do not show in browser the response 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //follow any redirects 
    curl_exec($ch); 
    $new_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); //extract the url from the header response 
    curl_close($ch); 

Cette fonctionne avec toutes les redirections telles que 301 ou 302, mais sur 404 il retournera simplement l'URL d'origine demandée (puisqu'il n'a pas été trouvé). Cela peut être utilisé pour mettre à jour ou supprimer des liens de votre site. C'était mon besoin de toute façon.

2

En réponse au commentaire de user437797 sur la réponse de TAMIK Soziev (malheureusement je n'ai pas la réputation de commenter là directement):

Le CURLINFO_EFFECTIVE_URL fonctionne très bien, mais pour ce faire comme op veut que vous aussi de mettre CURLOPT_FOLLOWLOCATION à VRAI bien sûr. C'est parce que CURLINFO_EFFECTIVE_URL renvoie exactement ce qu'il dit, l'URL efficace qui finit par être chargée. Si vous ne suivez pas les redirections, cela sera votre URL demandée, si vous suivez les redirections, ce sera l'URL finale qui sera redirigée vers. La bonne chose à propos de cette approche est qu'elle fonctionne également avec plusieurs redirections, alors que lors de la récupération et l'analyse de l'en-tête HTTP vous-même, vous devrez le faire plusieurs fois avant que l'URL de destination finale soit exposée.

Notez également que le nombre maximal de redirections que curl suit peut être contrôlé via CURLOPT_MAXREDIRS.Par défaut, il est illimité (-1), mais cela peut vous causer des problèmes si quelqu'un (peut-être intentionnellement) configuré et boucle de redirection sans fin pour une URL.