и снова CURL

Discussion in 'PHP' started by Romaxa55, 16 Apr 2011.

  1. Romaxa55

    Romaxa55 Banned

    Joined:
    19 Oct 2005
    Messages:
    144
    Likes Received:
    30
    Reputations:
    4
    Дело в том, что к примеру обратившись к опрделеннму хосту через курл фукцию, на хосте стоит скрипт geoip после чего редеректит

    headers содержит:
    Location: http://blalalalala

    Проблемма в том что на windows на vertrigo работает все отлично, никаких проблем, все редиректится и кукисы сохраняются как нужно, и в результате получаем конечную страницу после всех редиректов.

    Но на платном хосте как не пытался, редиректы не срабатываются, пытался просмотреть результат, получаем заголовок Location: http://blalala и все, как подправить функцию, чтоб на юниксе редирект проходил без проблем, чтоб не парсить ничего.




    На Windows редиректы проходят на ура (FOLLOWLOCATION )
     
  2. b3

    b3 Moderator

    Joined:
    5 Dec 2004
    Messages:
    2,041
    Likes Received:
    933
    Reputations:
    199
    В гугле 814 000 ответов на твой вопрос.

    PHP:
    function curl_redir_exec($ch)  
    {  
        static 
    $curl_loops = 0;  
        static 
    $curl_max_loops = 20;  
        if (
    $curl_loops   >= $curl_max_loops)  
        {  
        
    $curl_loops = 0;  
            return 
    FALSE;  
        }  
        
    curl_setopt($ch, CURLOPT_HEADER, true);  
        
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
        
    $data = curl_exec($ch);  
        list(
    $header, $data) = explode("\n\n", $data, 2);  
        
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);  
        if (
    $http_code == 301 || $http_code == 302)  
        {  
        
    $matches = array();  
            
    preg_match('/Location:(.*?)\n/', $header, $matches);  
        
    $url = @parse_url(trim(array_pop($matches)));  
            if (!
    $url)  
        {  
            
    //couldn't process the url to redirect to  
            
    $curl_loops = 0;  
            return 
    $data;  
            }  
        
    $last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));  
        if (!
    $url['scheme'])  
            
    $url['scheme'] = $last_url['scheme'];  
        if (!
    $url['host'])  
            
    $url['host'] = $last_url['host'];  
        if (!
    $url['path'])  
            
    $url['path'] = $last_url['path'];  
        
    $new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query']?'?'.$url['query']:'');  
        
    curl_setopt($ch, CURLOPT_URL, $new_url);  
        
    //debug('Redirecting to', $new_url);  
        
    return curl_redir_exec($ch);  
        }   else {  
            
    $curl_loops=0;  
            return 
    $data;  
            }  
    }  
     
    _________________________
  3. Romaxa55

    Romaxa55 Banned

    Joined:
    19 Oct 2005
    Messages:
    144
    Likes Received:
    30
    Reputations:
    4
    b3 Спасибо огромное, ответов много, но твой вариант намного лучше предложенных в первых 10 нагуглиных постах. спасибо огромное. Выложу полную функцию здесь чисто для себя.
    PHP:
    <?php
    function curl_redir_exec($ch)  
    {  
        static 
    $curl_loops = 0;  
        static 
    $curl_max_loops = 20;  
        if (
    $curl_loops   >= $curl_max_loops)  
        {  
        
    $curl_loops = 0;  
            return 
    FALSE;  
        }  
        
    curl_setopt($ch, CURLOPT_HEADER, true);  
        
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
        
    $data = curl_exec($ch);  
        list(
    $header, $data) = explode("\n\n", $data, 2);  
        
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);  
        if (
    $http_code == 301 || $http_code == 302)  
        {  
        
    $matches = array();  
            
    preg_match('/Location:(.*?)\n/', $header, $matches);  
        
    $url = @parse_url(trim(array_pop($matches)));  
            if (!
    $url)  
        {  
            
    //couldn't process the url to redirect to  
            
    $curl_loops = 0;  
            return 
    $data;  
            }  
        
    $last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));  
        if (!
    $url['scheme'])  
            
    $url['scheme'] = $last_url['scheme'];  
        if (!
    $url['host'])  
            
    $url['host'] = $last_url['host'];  
        if (!
    $url['path'])  
            
    $url['path'] = $last_url['path'];  
        
    $new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query']?'?'.$url['query']:'');  
        
    curl_setopt($ch, CURLOPT_URL, $new_url);  
        
    //debug('Redirecting to', $new_url);  
        
    return curl_redir_exec($ch);  
        }   else {  
            
    $curl_loops=0;  
            return 
    $data;  
            }  
    }  

    function 
    get_url($url, $ref = '', $header = '', $post = '', $cookie = '', $cookiefile = '', $proxy = '', $timeout = '', $popitok = 10) { 
        
    $ch = curl_init(); 
         
        
    curl_setopt($ch, CURLOPT_URL, $url); 
         
        if (
    $ref != '') 
            
    curl_setopt($ch, CURLOPT_REFERER, $ref); 
        if (
    $header != '') 
            
    curl_setopt($ch, CURLOPT_HEADER, true);
            
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);        
        if (
    $post != '') { 
            
    curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/10.00 (Windows NT 5.1; U; ru) Presto/2.1.1');

            
    curl_setopt($ch, CURLOPT_POST, 1); 
            
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 
        } 
        if (
    $cookie != '') 
            
    curl_setopt($ch, CURLOPT_COOKIE, $cookie); 
        if (
    $cookiefile != '') { 
              
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile); 
              
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefile); 
              
        } 
        if (
    $proxy != '') 
            
    curl_setopt($ch, CURLOPT_PROXY, $proxy); 
        
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  
        
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);    
        
    curl_setopt($ch, CURLOPT_USERAGENT, 'Opera/9.60 (Windows NT 5.1; U; ru) Presto/2.1.1'); 
        
    curl_setopt($ch, CURLOPT_ENCODING, "gzip"); 
        
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
        
    curl_setopt($ch, CURLOPT_HEADER, 1); 
        
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
         
        if (
    $timeout != '') 
            
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); 
             
        
    $i = 0; 
        do { 
            
    $i++; 
            
    flush(); 
            
    $content = curl_redir_exec($ch); 
        } while (
    $i < $popitok && $content == '' || curl_errno($ch) != 0 && $i < $popitok); 
         
        if (
    curl_errno($ch) != 0 || $content == '') { 
             
    curl_close($ch); 
            return 
    false; 
        } else { 
            
    curl_close($ch); 
            return 
    $content; 
        } 
    } 
    ?>
    Поправьте меня, если я допустил ошибку, либо не оптимизировано использую функцию. Может было бы лучше как то объединить 2 функции в одну, как считаете? Нужно ли это, не сильно зависимо время выполнения скрипта.

    P.S. Один раз спросил, усвоил на всю жизнь, попрошу не ругаться. Спасибо :)
     
    #3 Romaxa55, 23 Apr 2011
    Last edited: 23 Apr 2011
  4. Дикс

    Дикс Elder - Старейшина

    Joined:
    16 Apr 2006
    Messages:
    1,194
    Likes Received:
    227
    Reputations:
    26
    частенько followlocation (авто-редирект) не работал, если включена опция open_basedir

    ман по отключению - http://www.lsdeex.ru/archives/18

    это проще чем писать редиректы на пхп, раз уж включен followlocation