2009-09-17 9 views
31

Come posso ottenere l'URL di destinazione utilizzando cURL quando il codice di stato HTTP è 302?Come posso ottenere l'URL di destinazione usando 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

Hai avuto fortuna con le altre domande irrisolte? – GZipp

+0

dovresti accettare la risposta corretta (-1) – John

risposta

5

si deve afferrare la posizione intestazione per l'URL di reindirizzamento.

+1

Che ha bisogno di ulteriori inconvenienti, come verificare se è relativo, risolverlo (all'URL di base probabilmente precedente in un reindirizzamento intermedio se ci sono più ecc. Pp.), È solo altro facile da usare ['CURLINFO_EFFECTIVE_URL'] (http://stackoverflow.com/a/4917416/367456). – hakre

2

La nuova destinazione per un reindirizzamento 302 si trova nel campo dell'intestazione http "posizione". Esempio:

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 

Basta grep con una regex.

Per includere tutte le informazioni dell'intestazione HTTP, includerlo nel risultato con l'opzione di arricciatura CURLOPT_HEADER. Set con:

curl_setopt($c, CURLOPT_HEADER, true); 

Se si vuole semplicemente curl per seguire usare il reindirizzamento CURLOPT_FOLLOWLOCATION:

curl_setopt($c, CURLOPT_FOLLOWLOCATION, true); 

In ogni caso, non si dovrebbe usare il nuovo URI perché HTTP StatusCode 302 è solo una reindirizzamento temporaneo.

1

Ecco un modo per ottenere tutte le intestazioni restituite da una richiesta http di curl, nonché il codice di stato e una matrice di righe di intestazione per ogni intestazione.

$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

Usa curl_getinfo($ch), e il primo elemento (url) indicherebbe l'URL efficace.

37

È possibile utilizzare:

echo curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); 
+0

Questo metodo è molto più pulito/generalmente meglio di quello che analizza l'url dall'intestazione Location. –

+10

CURLINFO_EFFECTIVE_URL restituisce la pagina corrente (richiesta) per me. Non ci sono redirect (Location :) url nei risultati curl_getinfo. Sembra, analizzare le intestazioni è la migliore pratica ... –

+0

'CURLINFO_EFFECTIVE_URL' non sempre funziona per alcuni casi, specialmente quelli senza usare il reindirizzamento dell'intestazione. – 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

perfetto! Grazie per aver condiviso – ladieu

+1

E se non c'è un'intestazione di posizione? –

+0

A volte i siti utilizzano il meta reindirizzamento o 'window.location.replace' per reindirizzare la pagina. In tal caso, sostituire l'espressione regolare per acquisire il risultato. – Raptor

5

un po 'datato di una risposta, ma volevo mostrare un esempio di lavoro pieno, alcune delle soluzioni là fuori sono pezzi:

$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); 

Questo funziona con qualsiasi reindirizzamento come 301 o 302, tuttavia su 404 restituirà solo l'url originale richiesto (poiché non è stato trovato). Questo può essere usato per aggiornare o rimuovere link dal tuo sito. Questa era comunque la mia esigenza.

2

In risposta al commento di user437797 sulla risposta Tamik Soziev (io purtroppo non hanno la reputazione di commentare non direttamente):

Il CURLINFO_EFFECTIVE_URL funziona bene, ma per consentirle di operare come op vuole si hanno anche per impostare CURLOPT_FOLLOWLOCATION A VERO, certo. Questo perché CURLINFO_EFFECTIVE_URL restituisce esattamente ciò che dice, l'url effettivo che finisce per essere caricato. Se non segui i reindirizzamenti, questo sarà il tuo URL richiesto, se segui i reindirizzamenti, sarà l'url finale a cui viene reindirizzato.

La cosa bella di questo approccio è che funziona anche con reindirizzamenti multipli, mentre quando si recupera e si analizza l'intestazione HTTP, potrebbe essere necessario farlo più volte prima che venga visualizzato l'URL di destinazione finale.

Si noti inoltre che il numero massimo di reindirizzamenti seguiti da arricciatura può essere controllato tramite CURLOPT_MAXREDIRS.Di default è illimitato (-1) ma questo potrebbe metterti nei guai se qualcuno (forse intenzionalmente) configurato e un ciclo di reindirizzamento infinito per qualche URL.

Problemi correlati