260

I'm working on a CMS that fetches a user's profile image from their Facebook URL (that is, http://facebook.com/users_unique_url). How can I accomplish this? Is there a Faceboook API call that fetches a user's profile image URL without the user needing to Allow the application?

14 Answers 14

409

Simply fetch the data through this URL:

http://graph.facebook.com/userid_here/picture

Replace userid_here with id of the user you want to get the photo of. You can also use HTTPS as well.

You can use the PHP's file_get_contents function to read that URL and process the retrieved data.

Resource:

http://developers.facebook.com/docs/api

Note: In php.ini, you need to make sure that the OpenSSL extension is enabled to use thefile_get_contents function of PHP to read that URL.

17
  • 74
    Looking through that page further, another useful thing might be the ?type=large querystring you can add on. Props for coming up with a totally much better answer than the screen-scraping I was typing up, BTW :).
    – Domenic
    Commented May 12, 2010 at 17:21
  • 6
    Use <img src="//graph.facebook.com/sarfraz.anees/picture" /> if you change between HTTP and HTTPS... the protocol is detected by the browser, and you won't get mixed content warnings on HTTPS. Commented Nov 23, 2011 at 1:45
  • 39
    It should be emphasized, some users do NOT have a username set for their FB account. When this is the case, and you are trying to implement this answer, you will receive FB's default profile picture, the question mark. To easily avoid this problem, use the user's FB ID instead.
    – Josh
    Commented Feb 14, 2012 at 20:01
  • 8
    It should be noted that in V2 of the graph api this no longer works using a username. So now you need the userid first, and you can no longer use a username to get this. Userid's also change per app, so you will have to have some kind of proper authentication to retrieve a userid you can use. Technically the profile pic is still public and available at graph.facebook.com/v2.2/4/picture?redirect=0 however figuring out the userid (4 in previous link) seems impossible based just on the user's profile. The old graph url still works until April 2015.
    – sckd
    Commented Nov 10, 2014 at 8:43
  • 37
    It's 2015 and I am getting (#803) Cannot query users by their username (sarfraz.anees) Commented Jun 19, 2015 at 13:35
268

To show:

50x50 pixels

<img src="//graph.facebook.com/{{fid}}/picture">

200 pixels width

<img src="//graph.facebook.com/{{fid}}/picture?type=large">

To save (using PHP)

NOTE: Don't use this. See @Foreever's comment below.

$img = file_get_contents('https://graph.facebook.com/'.$fid.'/picture?type=large');
$file = dirname(__file__).'/avatar/'.$fid.'.jpg';
file_put_contents($file, $img);

Where $fid is your user id on Facebook.

NOTE: In case of images marked as "18+" you will need a valid access_token from a 18+ user:

<img src="//graph.facebook.com/{{fid}}/picture?access_token={{access_token}}">

UPDATE 2015:

Graph API v2.0 can't be queried using usernames, you should use userId always.

6
  • 6
    Here's more info on the type parameter: "You can specify the picture size you want with the type argument, which should be one of square (50x50), small (50 pixels wide, variable height), normal (100 pixels wide, variable height), and large (about 200 pixels wide, variable height)" Via Graph API on Facebook
    – user603284
    Commented Jun 10, 2011 at 20:37
  • 3
    To use this method, you have to set allow_url_fopen to on. The allow_url_fopen directive is disabled by default. You should be aware of the security implications of enabling the allow_url_fopen directive. PHP scripts that can access remote files are potentially vulnerable to arbitrary code injection. When the allow_url_fopen directive is enabled, you can write scripts that open remote files as if they are local files.
    – Foreever
    Commented Aug 12, 2014 at 10:24
  • Looks useful, so cheers in advance, but being one level too newb to understand I'd like to know which programming language this is in? My guess is PHP. Commented Dec 31, 2014 at 23:00
  • @hello_there_andy Yep! It's PHP (actually the question is tagged as PHP and it was the only language I use 4 years ago)
    – neiker
    Commented Jan 13, 2015 at 17:25
  • 7
    In July 2015 this no longer works (error: "Cannot query users by their username")
    – Flimm
    Commented Jul 1, 2015 at 9:07
164

UPDATE:

Starting end August 2012, the API has been updated to allow you to retrieve user's profile pictures in varying sizes. Add the optional width and height fields as URL parameters:

https://graph.facebook.com/USER_ID/picture?width=WIDTH&height=HEIGHT

where WIDTH and HEIGHT are your requested dimension values.

This will return a profile picture with a minimum size of WIDTH x HEIGHT while trying to preserve the aspect ratio. For example,

https://graph.facebook.com/redbull/picture?width=140&height=110

returns

    {
      "data": {
        "url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/c0.19.180.142/s148x148/2624_134501175351_4831452_a.jpg",
        "width": 148,
        "height": 117,
        "is_silhouette": false
      }
   }

END UPDATE

To get a user's profile picture, call

https://graph.facebook.com/USER_ID/picture

where USER_ID can be the user id number or the user name.

To get a user profile picture of a specific size, call

https://graph.facebook.com/USER_ID/picture?type=SIZE

where SIZE should be replaced with one of the words

square
small
normal
large

depending on the size you want.

This call will return a URL to a single image with its size based on your chosen type parameter.

For example:

https://graph.facebook.com/USER_ID/picture?type=small

returns a URL to a small version of the image.

The API only specifies the maximum size for profile images, not the actual size.

Square:

maximum width and height of 50 pixels.

Small

maximum width of 50 pixels and a maximum height of 150 pixels.

Normal

maximum width of 100 pixels and a maximum height of 300 pixels.

Large

maximum width of 200 pixels and a maximum height of 600 pixels.

If you call the default USER_ID/picture you get the square type.

CLARIFICATION

If you call (as per above example)

https://graph.facebook.com/redbull/picture?width=140&height=110

it will return a JSON response if you're using one of the Facebook SDKs request methods. Otherwise it will return the image itself. To always retrieve the JSON, add:

&redirect=false

like so:

https://graph.facebook.com/redbull/picture?width=140&height=110&redirect=false
7
  • Great explanation, but the return value of url you gave ('graph.facebook.com/redbull/…) responds with image url in the location header ('Location: fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/c0.19.180.142/…). not as a JSON like { "data": { "url": "fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/c0.19.180.142/…", "width": 148, "height": 117, "is_silhouette": false } } Commented Nov 22, 2012 at 12:11
  • I still get the same response as in my answer. You can try it out in the Graph Explorer on Facebook Developers at developers.facebook.com/tools/explorer. Enter 'redbull/picture?width=140&height=110' and see the response. My answer assumes you're calling this using one of the Facebook SDKs API / request methods, which will return a JSON response. Commented Dec 31, 2012 at 1:44
  • 2
    @GunnarKarlsson you are missing the &redirect=false to return the JSON data instead of redirect to the image Commented Mar 4, 2013 at 5:43
  • @andrewtweber thanks a lot. I've added a clarification to the answer. Commented Mar 4, 2013 at 7:22
  • 3
    It's July 2015 and this no longer works. (error: "Cannot query users by their username")
    – Flimm
    Commented Jul 1, 2015 at 9:08
20

To get the image URL, NOT binary content:

$url = "http://graph.facebook.com/$fbId/picture?type=$size";

$headers = get_headers($url, 1);

if( isset($headers['Location']) )
    echo $headers['Location']; // string
else
    echo "ERROR";

You must use your FACEBOOK ID, NOT USERNAME. You can get your facebook id there:

http://findmyfbid.com/

3
  • 1
    It's July 2015 and this no longer works (error: "Cannot query users by their username")
    – Flimm
    Commented Jul 1, 2015 at 9:08
  • 3
    You got it all wrong friend :) It's your facebook ID, not username findmyfbid.com Commented Aug 3, 2015 at 16:37
  • 1
    Best of here. It's crazy definitely, I tried to getting data in body and then data appear in header @.@
    – Davuz
    Commented Jun 9, 2016 at 15:34
19

Simple one-line code to save FULL size profile image on your server.

<?php

copy("https://graph.facebook.com/FACEBOOKID/picture?width=9999&height=9999", "picture.jpg");

?>

This will only work if openssl is enabled in php.ini.

2
  • It's July 2015 and this no longer works (error: "Cannot query users by their username")
    – Flimm
    Commented Jul 1, 2015 at 9:08
  • Yes, v1.0 calls will stop working after April 30th 2015. You can't get application specific ID unless the user has authorised your app
    – Armand
    Commented Jul 1, 2015 at 16:16
11

Added this as a comment to accepted answer, but felt it deserved a longer explanation. Starting around April 2015 this will probably be raised a few times.

As of V2 of the graph api the accepted answer no longer works using a username. So now you need the userid first, and you can no longer use a username to get this. To further complicate matters, for privacy reasons, Facebook is now changing userid's per app (see https://developers.facebook.com/docs/graph-api/reference/v2.2/user/ and https://developers.facebook.com/docs/apps/upgrading/#upgrading_v2_0_user_ids ), so you will have to have some kind of proper authentication to retrieve a userid you can use. Technically the profile pic is still public and available at /userid/picture (see docs at https://developers.facebook.com/docs/graph-api/reference/v2.0/user/picture and this example user: http://graph.facebook.com/v2.2/4/picture?redirect=0) however figuring out a user's standard userid seems impossible based just on their profile - your app would need to get them to approve interaction with the app which for my use case (just showing a profile pic next to their FB profile link) is overkill.

If someone has figured out a way to get the profile pic based on username, or alternatively, how to get a userid (even an alternating one) to use to retrieve a profile pic, please share! In the meantime, the old graph url still works until April 2015.

9

One way is to use the code Gamlet posted in his answer:

  • Save it as curl.php

  • Then in your file:

    require 'curl.php';
    
    $photo="https://graph.facebook.com/me/picture?access_token=" . $session['access_token'];
    $sample = new sfFacebookPhoto;
    $thephotoURL = $sample->getRealUrl($photo);
    echo $thephotoURL;
    

I thought I would post this, because it took me a bit of time to figure out the particulars... Even though profile pictures are public, you still need to have an access token in there to get it when you curl it.

9

Working PHP (HTTP GET) solution from April 2015 (without PHP 5 SDK):

function get_facebook_user_avatar($fbId){
        $json = file_get_contents('https://graph.facebook.com/v2.5/'.$fbId.'/picture?type=large&redirect=false');
        $picture = json_decode($json, true);
        return $picture['data']['url'];
}

You can change 'type' in parametr:

Square:

maximum width and height of 50 pixels.

Small

maximum width of 50 pixels and a maximum height of 150 pixels.

Normal

maximum width of 100 pixels and a maximum height of 300 pixels.

Large

maximum width of 200 pixels and a maximum height of 600 pixels.

8

There is way to do that ;)

Thanks to "http://it.toolbox.com/wiki/index.php/Use_curl_from_PHP_-_processing_response_headers":

<?php

    /**
     * Facebook user photo downloader
     */

    class sfFacebookPhoto {

        private $useragent = 'Loximi sfFacebookPhoto PHP5 (cURL)';
        private $curl = null;
        private $response_meta_info = array();
        private $header = array(
                "Accept-Encoding: gzip,deflate",
                "Accept-Charset: utf-8;q=0.7,*;q=0.7",
                "Connection: close"
            );

        public function __construct() {
            $this->curl = curl_init();
            register_shutdown_function(array($this, 'shutdown'));
        }

        /**
         * Get the real URL for the picture to use after
         */
        public function getRealUrl($photoLink) {
            curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->header);
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, false);
            curl_setopt($this->curl, CURLOPT_HEADER, false);
            curl_setopt($this->curl, CURLOPT_USERAGENT, $this->useragent);
            curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, 10);
            curl_setopt($this->curl, CURLOPT_TIMEOUT, 15);
            curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
            curl_setopt($this->curl, CURLOPT_URL, $photoLink);

            //This assumes your code is into a class method, and
            //uses $this->readHeader as the callback function.
            curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, array(&$this, 'readHeader'));
            $response = curl_exec($this->curl);
            if (!curl_errno($this->curl)) {
                $info = curl_getinfo($this->curl);
                var_dump($info);
                if ($info["http_code"] == 302) {
                    $headers = $this->getHeaders();
                    if (isset($headers['fileUrl'])) {
                        return $headers['fileUrl'];
                    }
                }
            }
            return false;
        }


        /**
         * Download Facebook user photo
         *
         */
        public function download($fileName) {
            curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->header);
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($this->curl, CURLOPT_HEADER, false);
            curl_setopt($this->curl, CURLOPT_USERAGENT, $this->useragent);
            curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, 10);
            curl_setopt($this->curl, CURLOPT_TIMEOUT, 15);
            curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
            curl_setopt($this->curl, CURLOPT_URL, $fileName);
            $response = curl_exec($this->curl);
            $return = false;
            if (!curl_errno($this->curl)) {
                $parts = explode('.', $fileName);
                $ext = array_pop($parts);
                $return = sfConfig::get('sf_upload_dir') . '/tmp/' . uniqid('fbphoto') . '.' . $ext;
                file_put_contents($return, $response);
            }
            return $return;
        }

        /**
         * cURL callback function for reading and processing headers.
         * Override this for your needs.
         *
         * @param object $ch
         * @param string $header
         * @return integer
         */
        private function readHeader($ch, $header) {

            //Extracting example data: filename from header field Content-Disposition
            $filename = $this->extractCustomHeader('Location: ', '\n', $header);
            if ($filename) {
                $this->response_meta_info['fileUrl'] = trim($filename);
            }
            return strlen($header);
        }

        private function extractCustomHeader($start, $end, $header) {
            $pattern = '/'. $start .'(.*?)'. $end .'/';
            if (preg_match($pattern, $header, $result)) {
                return $result[1];
            }
            else {
                return false;
            }
        }

        public function getHeaders() {
            return $this->response_meta_info;
        }

        /**
         * Cleanup resources
         */
        public function shutdown() {
            if($this->curl) {
                curl_close($this->curl);
            }
        }
    }
7

I was thinking - maybe ID will be a useful tool. Every time a user creates a new account it should get a higher ID. I googled and found that there is a method to estimate the account creation date by ID and Massoud Seifi from metadatascience.com gathered some good data about it.

Enter image description here

Read this article:

http://metadatascience.com/2013/03/11/inferring-facebook-account-creation-date-from-facebook-user-id/

And here are some IDs to download:

http://metadatascience.com/2013/03/14/lookup-table-for-inferring-facebook-account-creation-date-from-facebook-user-id/

1
  • 2
    How does this answer the question?
    – Flimm
    Commented Jun 10, 2015 at 13:13
6

The blog post Grab the Picture of a Facebook Graph Object might offer another form of solution. Use the code in the tutorial along with the Facebook's Graph API and its PHP SDK library.

... And try not to use file_get_contents (unless you're ready to face the consequences - see file_get_contents vs curl).

4

Are you concerned about the profile picture size? at the time of implementing login with Facebook using PHP. We’ll show you the simple way to get large size profile picture in Facebook PHP SDK. Also, you can get the custom size image of Facebook profile.

Set the profile picture dimension by using the following line of code.

$userProfile = $facebook->api('/me?fields=picture.width(400).height(400)');

check this post:http://www.codexworld.com/how-to-guides/get-large-size-profile-picture-in-facebook-php-sdk/

3

@NaturalBornCamper,

Nice code! Here is a clean-cut code function for such process!

function get_raw_facebook_avatar_url($uid)
{
    $array = get_headers('https://graph.facebook.com/'.$uid.'/picture?type=large', 1);
    return (isset($array['Location']) ? $array['Location'] : FALSE);
}

This will return the raw Facebook avatar image URL. Feel free to do whatever you want with it then!

3
URI  = https://graph.facebook.com/{}/picture?width=500'.format(uid)

You can get the profile URI via online facebook id finder tool

You can also pass type param with possible values small, normal, large, square.

Refer the official documentation

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.