cURL CURLOPT_FOLLOWLOCATION issue with safe_mode/open_basedir

CURLOPT_FOLLOWLOCATION doesn't workToday I've encountered problem with the CURLOPT_FOLLOWLOCATION. I tried to get user profile picture from facebook with cURL. Unfortunately, on production server we have set open_basedir and follow location is not working;/ So I found some workaround of this issue. I created function that provides similar functionality for CURLOPT_FOLLOWLOCATION option. It's working when you are in safe_mode or you have open_basedir set.

CURLOPT_FOLLOWLOCATION fix

function curl_follow_exec($ch)
{
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if ($http_code == 301 || $http_code == 302) {
        preg_match('/(Location:|URI:)(.*?)\n/', $data, $matches);
        if (isset($matches[2])) {
            $redirect_url = trim($matches[2]);
            if ($redirect_url !== '') {
                curl_setopt($ch, CURLOPT_URL, $redirect_url);
                return curl_follow_exec($ch);
            }
        }
    }
    return $data;
}

It just check if response code is 301 or 302, getting the location URL from headers and perform another cURL request for location URL. It is recurrence function and it will end when there's no redirection left. You can always add some counter and check if there's no more than 10 redirections for example. Just not to get into infinite loop with redirections.

Real-life usage

Example use here for grabbing profile image from facebook

public function getUserPicture($uid)
{
    $url = 'http://graph.facebook.com/' . $uid . '/picture?type=large';
    $ch = curl_init($url);
    $image = curl_follow_exec($ch);
    curl_close($ch);
    return $image;
}

$uid is facebook user id, you can get it for example from facebook api, when user will authorize your website for such informations. Function curl_follow_exec is taking one parameter which is curl handle. You can create curl handle with curl_init, set any option as you like and call curl_follow_exec instead of curl_exec.

You can read more about cURL, CURLOPT_FOLLOWLOCATION and other useful options in php manual here: http://php.net/manual/en/book.curl.php

Our services: