и снова 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($chCURLOPT_HEADERtrue);  
        
    curl_setopt($chCURLOPT_RETURNTRANSFERtrue);  
        
    $data curl_exec($ch);  
        list(
    $header$data) = explode("\n\n"$data2);  
        
    $http_code curl_getinfo($chCURLINFO_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($chCURLINFO_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($chCURLOPT_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($chCURLOPT_HEADERtrue);  
        
    curl_setopt($chCURLOPT_RETURNTRANSFERtrue);  
        
    $data curl_exec($ch);  
        list(
    $header$data) = explode("\n\n"$data2);  
        
    $http_code curl_getinfo($chCURLINFO_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($chCURLINFO_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($chCURLOPT_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($chCURLOPT_URL$url); 
         
        if (
    $ref != ''
            
    curl_setopt($chCURLOPT_REFERER$ref); 
        if (
    $header != ''
            
    curl_setopt($chCURLOPT_HEADERtrue);
            
    curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
            
    curl_setopt($chCURLOPT_FOLLOWLOCATIONtrue);        
        if (
    $post != '') { 
            
    curl_setopt($chCURLOPT_USERAGENT'Opera/10.00 (Windows NT 5.1; U; ru) Presto/2.1.1');

            
    curl_setopt($chCURLOPT_POST1); 
            
    curl_setopt($chCURLOPT_POSTFIELDS$post); 
        } 
        if (
    $cookie != ''
            
    curl_setopt($chCURLOPT_COOKIE$cookie); 
        if (
    $cookiefile != '') { 
              
    curl_setopt($chCURLOPT_COOKIEJAR$cookiefile); 
              
    curl_setopt($chCURLOPT_COOKIEFILE$cookiefile); 
              
        } 
        if (
    $proxy != ''
            
    curl_setopt($chCURLOPT_PROXY$proxy); 
        
    curl_setopt($chCURLOPT_SSL_VERIFYPEERFALSE);  
        
    curl_setopt($chCURLOPT_SSL_VERIFYHOST2);    
        
    curl_setopt($chCURLOPT_USERAGENT'Opera/9.60 (Windows NT 5.1; U; ru) Presto/2.1.1'); 
        
    curl_setopt($chCURLOPT_ENCODING"gzip"); 
        
    curl_setopt($chCURLOPT_FOLLOWLOCATIONtrue); 
        
    curl_setopt($chCURLOPT_HEADER1); 
        
    curl_setopt($chCURLOPT_RETURNTRANSFER1); 
         
        if (
    $timeout != ''
            
    curl_setopt($chCURLOPT_TIMEOUT$timeout); 
             
        
    $i 0
        do { 
            
    $i++; 
            
    flush(); 
            
    $content curl_redir_exec($ch); 
        } while (
    $i $popitok && $content == '' || curl_errno($ch) != && $i $popitok); 
         
        if (
    curl_errno($ch) != || $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