Дело в том, что к примеру обратившись к опрделеннму хосту через курл фукцию, на хосте стоит скрипт geoip после чего редеректит headers содержит: Location: http://blalalalala Проблемма в том что на windows на vertrigo работает все отлично, никаких проблем, все редиректится и кукисы сохраняются как нужно, и в результате получаем конечную страницу после всех редиректов. Но на платном хосте как не пытался, редиректы не срабатываются, пытался просмотреть результат, получаем заголовок Location: http://blalala и все, как подправить функцию, чтоб на юниксе редирект проходил без проблем, чтоб не парсить ничего. На Windows редиректы проходят на ура (FOLLOWLOCATION )
В гугле 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; } }
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. Один раз спросил, усвоил на всю жизнь, попрошу не ругаться. Спасибо
частенько followlocation (авто-редирект) не работал, если включена опция open_basedir ман по отключению - http://www.lsdeex.ru/archives/18 это проще чем писать редиректы на пхп, раз уж включен followlocation