Эмулируем CURLOPT_FOLLOWLOCATION

Уроки и готовые решения
Ответить
Аватара пользователя
deepblue
Site Admin
Сообщения: 48
Зарегистрирован: 2008-06-11 23:51:07

Эмулируем CURLOPT_FOLLOWLOCATION

Сообщение deepblue » 2012-04-29 11:45:30

Часто при работе с библиотекой cURL, если вы используете опцию CURLOPT_FOLLOWLOCATION (при получении заголовка Location будет происходить автоматическое перенаправление на указанный URL) может возникать следующая ошибка "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in". Она означает что необходимо выключить safe_mode или деактивировать директиву open_basedir. Часто хостинг-компании не позволяют сделать ни того ни другого.
Для решения этой проблемы воспользуйтесь следующей функцией вместо curl_exec.
Функция curl_redir_exec проверяет в возращаемых заголовках заголовок Location, если он присуствует, то пытается перейти по url указанному в заголовке, если он отсуствует - отдает полученное содержимое.

Код: Выделить всё

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) = explode("\n\n", $data);
	$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(!isset($url['scheme'])) $url['scheme'] = $last_url['scheme'];  
		if(!isset($url['host'])) $url['host'] = $last_url['host'];  
		if(!isset($url['path'])) $url['path'] = $last_url['path'];
		$new_url = $url['scheme'].'://'.$url['host'].$url['path'];
		if(isset($url['query'])) $new_url = $new_url.$url['query'];
		curl_setopt($ch, CURLOPT_URL, $new_url);  
		//debug('Redirecting to', $new_url);  
		$curl_loops++;
		return curl_redir_exec($ch);
	} else {
		$curl_loops = 0;  
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_TIMEOUT, 2);
		$data = curl_exec($ch);
		return $data;  
	}
}
Источник - snippy.ru
Я отредактировал код под свою стилистику и добавил все необходимые для работы исправления, т.к. оригинал не работал.

Ответить