259

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?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
John Himmelman
  • 20,084
  • 20
  • 61
  • 79

14 Answers14

410

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.

Community
  • 1
  • 1
Sarfraz
  • 355,543
  • 70
  • 511
  • 562
  • Thanks! That is exactly what I was looking for! – John Himmelman May 12 '10 at 17:20
  • 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 May 12 '10 at 17:21
  • 2
    @Domenic: Yup, the new graph API looks to be cool and promising :) – Sarfraz May 12 '10 at 17:22
  • How can you get the users' ID to put in the url? Normally it's a unique facebook ID but I only have the name/email from the user in my system – Jorre Feb 26 '11 at 16:33
  • 6
    Use `` if you change between HTTP and HTTPS... the protocol is detected by the browser, and you won't get mixed content warnings on HTTPS. – Chris Jacob Nov 23 '11 at 01: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 Feb 14 '12 at 20:01
  • Facebook have included a separate page for the pagination details: https://developers.facebook.com/docs/reference/api/pagination/ – eliocs Nov 19 '12 at 15:13
  • Looks like there are so many user with the same full name , so I am not getting my picture. – Faizan Jan 05 '13 at 13:21
  • This didn't work for me because it redirects to another the cdn url of the photo – SoWhat Jun 08 '13 at 12:59
  • Was wondering how to get the COVER PHOTO instead of the profile picture... Does anyone know that url? – jsetting32 Aug 08 '13 at 05:07
  • Warning : using file_get_contents() can have big performance issues on you hosting or server – ucefkh Feb 01 '14 at 14:30
  • 1
    Now it seems to return a redirect (302) response, but if you follow that you will get the right image. Also you can ?redirect=false to the url to get a JSON response which contains the final URL to the picture. – Gnomet Mar 28 '14 at 11:13
  • I am using this string in my app and choosing a specific width and height; however, Inresolution seems much lower than it really is. Any suggestions? – Camus Mar 30 '14 at 00:14
  • 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 http://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 Nov 10 '14 at 08:43
  • 37
    It's 2015 and I am getting **(#803) Cannot query users by their username (sarfraz.anees)** – Santosh Kumar Jun 19 '15 at 13:35
  • 4
    @SantoshKumar *username* should be replaced with *user id*. `graph.facebook.com/{user-id}/picture` – WeirdElfB0y Oct 06 '15 at 06:56
  • you can use "me" instead of user_id if you need your profile picture – Defuera Apr 11 '17 at 10:02
  • Can we write a chrome extension that creates a notification whenever a particular user id changes profile picture and gets their new profile picture? –  Apr 25 '17 at 08:02
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.

neiker
  • 8,568
  • 3
  • 27
  • 31
  • 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](http://developers.facebook.com/docs/reference/api/) –  Jun 10 '11 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 Aug 12 '14 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. – hello_there_andy Dec 31 '14 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 Jan 13 '15 at 17:25
  • Thanks man i spent around 2 hour searching on this in the api docs and graph explorer with no luck – Antwan Jun 30 '15 at 22:49
  • 7
    In July 2015 this no longer works (error: "Cannot query users by their username") – Flimm Jul 01 '15 at 09: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
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
onosendai
  • 27,850
  • 10
  • 64
  • 70
  • Great explanation, but the return value of url you gave ('https://graph.facebook.com/redbull/picture&width=140&height=110') responds with image url in the location header ('Location: https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/c0.19.180.142/s148x148/2624_134501175351_4831452_a.jpg'). not as a JSON like { "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 } } – Gökhan Barış Aker Nov 22 '12 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. – onosendai Dec 31 '12 at 01:44
  • 2
    @GunnarKarlsson you are missing the `&redirect=false` to return the JSON data instead of redirect to the image – andrewtweber Mar 04 '13 at 05:43
  • @andrewtweber thanks a lot. I've added a clarification to the answer. – onosendai Mar 04 '13 at 07:22
  • nice one... much helped me... i was feeling as new to fb sdk but u made me feel comfortable... – anuj arora Mar 14 '13 at 09:55
  • 3
    It's July 2015 and this no longer works. (error: "Cannot query users by their username") – Flimm Jul 01 '15 at 09:08
  • @Flimm No but you can use the facebook id instead of the username – John Max Dec 14 '17 at 22:48
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/

NaturalBornCamper
  • 3,264
  • 5
  • 30
  • 49
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.

NaturalBornCamper
  • 3,264
  • 5
  • 30
  • 49
Armand
  • 1,788
  • 1
  • 20
  • 30
  • It's July 2015 and this no longer works (error: "Cannot query users by their username") – Flimm Jul 01 '15 at 09: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 Jul 01 '15 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.

sckd
  • 405
  • 3
  • 11
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.

Xawier
  • 167
  • 1
  • 11
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.

Community
  • 1
  • 1
benjaminlotan
  • 171
  • 2
  • 8
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);
            }
        }
    }
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Hamlet
  • 81
  • 1
  • 2
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/

Brady
  • 206
  • 1
  • 8
Erroid
  • 664
  • 1
  • 11
  • 22
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).

Community
  • 1
  • 1
moostring
  • 69
  • 1
  • 2
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/

Sagar Jethi
  • 1,185
  • 11
  • 17
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!

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
tfont
  • 9,576
  • 4
  • 48
  • 51
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

user2119554
  • 320
  • 1
  • 3
  • 13