PHP, cURL, CURLOPT FOLLOWLOCATION and open basedir Or Safe Mode

This is post is now quite old and the the information it contains may be out of date or innacurate.

If you find any errors or have any suggestions to update the information please let us know or create a pull request on GitHub

If you are trying to get a curl script which needs follow on location functionality to run on a server which has either open_basedir or safe mode enabled you will get an error message similar to the following:

CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set

After a bit of digging, some kind soul has put a workaround here

Here is how to use the function

function curl($url){
$go = curl_init($url);
curl_setopt ($go, CURLOPT_URL, $url);
//follow on location problems

if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')){

curl_setopt ($go, CURLOPT_FOLLOWLOCATION, $l);

$syn = curl_exec($go);

}else{

$syn = curl_redir_exec($go);

}

curl_close($go);
return $syn;
}

//follow on location problems workaround

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);

return curl_redir_exec($ch);

} else {

$curl_loops=0;

return $data;

}

}