Nasıl cURL kullanarak hedef URL alabilirim?

7 Cevap php

Nasıl HTTP durum kodu 302 iken cURL kullanarak hedef URL alabilirim?

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

7 Cevap

Sen kullanabilirsiniz:

echo curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);

Sen yeniden yönlendirilen URL için Location başlık kapmak zorunda.

The new destination for a 302 redirect ist located in the http header field "location". Example:

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

Sadece bir regex ile grep.

Tüm HTTP başlık bilgileri içerecek kıvırmak seçeneği ile sonuca eklemeniz CURLOPT_HEADER. Ile ayarlayın:

curl_setopt($c, CURLOPT_HEADER, true);

Sadece kıvırmak yönlendirme kullanımını takip etmek istiyorsanız CURLOPT_FOLLOWLOCATION:

curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);

HTTP StatusCode 302 sadece bir temporary yönlendirme çünkü Neyse, yeni URI kullanmak gerekir.

İşte tüm başlıklar bir kıvırmak http isteği yanı sıra, durum kodu ve her başlık için başlık satırları bir dizi tarafından döndürülen almak için bir yoldur.

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

Tamik Soziev cevabı üzerine user437797 yorumuna yanıt olarak (ne yazık ki orada doğrudan Yorumlamak için itibar yok):

CURLINFO_EFFECTIVE_URL çalışıyor, ama op istediği gibi bunu yapmak için de elbette DOĞRU CURLOPT_FOLLOWLOCATION ayarlamak zorunda. CURLINFO_EFFECTIVE_URL o biter etkili url yüklenmiş oluyor, diyor tam olarak ne verir, çünkü bu. Eğer yönlendirmeleri takip etmiyorsanız o zaman bu yönlendirmeleri takip yaparsanız o yönlendirildi son url olacak, senin talep url olacaktır.

Bu yaklaşım hakkında güzel bir şey almak ve HTTP kendinizi header ayrıştırma zaman nihai hedef url önce birden çok kez maruz kaldığı yapmak zorunda oysa aynı zamanda, birden fazla yönlendirmeler ile çalışır.

Ayrıca kıvırmak izler yönlendirmelerin azami sayısı CURLOPT_MAXREDIRS üzerinden kontrol edilebilir olduğunu unutmayın. Varsayılan olarak (-1) sınırsızdır ama birisi (belki de kasıtlı) yapılandırılmış ve bazı url için sonsuz yönlendirme döngüsü bu sorun içine alabilirsiniz.

curl_getinfo($ch) kullanın ve birinci eleman (url) etkili URL'sini işaret eder.

Biraz bir yanıt tarihli ama tam bir çalışma örneği göstermek istedim, orada çözümleri bazı parçalar:

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

Bu, örneğin 301 veya 302 gibi herhangi bir yönlendirme ile çalışır ancak 404 yıllardan üzerine sadece (o bulunmadı çünkü) istenen orijinal url dönecektir. Bu sitede bağlantıları güncellemek veya kaldırmak için kullanılabilir. Bu zaten benim ihtiyaç oldu.