Ошибка CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in

На днях добавил в InternetSMS поддержку отправки смс на оператор МТС Украина (UMC).
На моем локальном компьютере все работает хорошо, загружаю на хостинг – выдается ошибка:
Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in
CURLOPT_FOLLOWLOCATION – опция, при которой библиотека cURL поддерживает редиректы.
curl_setopt(CURLOPT_FOLLOWLOCATION, 1);
При установке этой опции в ненулевое значение, библиотека cURL будет рекурсивно загружать любой «Location: url» в HTTP header. Для работы с опцией CURLOPT_FOLLOWLOCATION защищенный режим должен быть выключен.
Защищенный режим в PHP – это попытка решить проблему безопасности на совместно используемых серверах. Несмотря на то, что концептуально неверно решать эту проблему на уровне PHP, но поскольку альтернативы уровня веб-сервера или операционной системы на сегодняшний день отсутствуют, многие пользователи, особенно провайдеры, используют именно защищенный режим.

  • safe_mode – Включает/отключает защищенный режим в PHP.
  • open_basedir – Ограничивает список файлов, которые могут быть открыты в PHP, указанным деревом директорий независимо от того, используется защищенный режим или нет.

Параметры 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;
}
}
?>

Функция curl_redir_exec(), при получении страницы, проверяет код http заголовка и при наличии редиректов обходит их самостоятельно, не прибегая к CURL опции CURLOPT_FOLLOWLOCATION.

Метки:cURL, CURLOPT_FOLLOWLOCATION, open_basedir, safe_mode, Защищенный режим в PHP
 

Комментарии: 6

Прокомментировать »

 
 
 

сам столкнулся с такой проблемой, а можно пример использования этой функции ??? буду очень благодарен, а то либо голова уже не соображает не понимаю как ее использовать )))

 

вместо curl_exec($ch) пишется curl_redir_exec($ch)

 

Спасибо за скрипт, он работает! Правда есть нотайсы Notice: Undefined offset: 1 (про header как я понял пишет).

Сергей Жилин
 

А что за функция debug(’Redirecting to’, $new_url);?
У меня рнр не может ее найти

 

замените на echo

 

Та же проблемма с debug(’Redirecting to’, $new_url);
Заменил на ‘echo’, но скрипт все равно не работает.

 

Прокомментировать

 
(will not be published)
 
 
Сообщение