Fetch User Posts from Facebook Timeline with Graph API using PHP

Facebook PHP SDK provides an easy way to access Facebook API. The PHP SDK helps to authenticate and login with Facebook account on the web application. After the authentication, various information can be fetched from the user’s Facebook account using Graph API. Facebook Graph API is very useful to retrieve the profile data and feed from the user timeline.

If you want to enhance the Facebook OAuth functionality and get additional information from the FB account, Graph API is the best option. After the authentication with Facebook, you can retrieve the profile and posts data from the user’s account. In this tutorial, we will show you how to fetch the user post from the Facebook timeline with Graph API using PHP.

In this Facebook post parser script, the following functionality will be implemented using PHP.

  • Login with Facebook using PHP SDK v5.
  • Fetch profile information from Facebook using Graph API.
  • Fetch the user’s posts from Facebook Timeline using Graph API.

Before you begin to read Facebook posts from the user timeline with PHP, take a look at the files structure.

facebook_user_post_feed_php/
├── config.php
├── index.php
├── logout.php
├── User.class.php
├── facebook-php-graph-sdk/
├── images/
│   ├── fb-login-btn.png
└── css/
    └── style.css

Create Facebook App

The App ID and App Secret are required to access Facebook API. To generate App ID & Secret create Facebook APP in Developers Panel.

  • Go to the Facebook for Developers and log in with your Facebook account.
  • At the top navigation menu, click the My Apps and select Add New App.
    • Enter the Display Name and Contact Email.
    • Click on the Create App ID button.
    • You will be redirected to the App Dashboard.
  • Navigate to the Settings » Basic page.
    • Specify the App Domains and select the Category of your App.
    • Click Save Changes.
  • At the left navigation menu panel, click the PRODUCTS(+) and navigate to the Add a Product page.
    • Select Facebook Login to Set Up.
    • Select Web as the App platform.
    • Enter the Site URL and Save.
  • Navigate to the Facebook Login » Settings page.
    • In the Valid OAuth Redirect URIs field, enter the Redirect URL.
    • Click Save Changes.
  • In the Settings » Basic page, the App ID and App Secret will be displayed. This App ID and App secret allow you to access Facebook APIs.
create-facebook-developer-app-id-secret-codexworld

Note that: The App ID and App secret need to be specified in the script at the time of Facebook API call. Also, the Valid OAuth Redirect URIs must be matched with the Redirect URL that specified in the script.

How to create Facebook App and get the App ID & App secret

Get Permission to Access Feed of Posts

To grants app permission and retrieve the user’s Facebook timeline posts, you need to submit a request for user_posts permission.

  • Go to the App Review » Permissions and Features page.
  • Request for user_posts permission and submit the required information.
facebook-app-permissions-user_posts-retrieve-timeline-feed-codexworld

Once the review process is completed and approved by Facebook, you will be able to get the user posts from the timeline with Facebook Graph API.

Note that: It will take time to complete the review process by Facebook. Meanwhile, you can test the functionality in development mode.

How to Test Facebook OAuth in Development Mode

Create Database Tables

Two tables are required to hold the user’s profile information and feed posts data in the database.

1. The following SQL creates a users table with some basic fields in the MySQL database to store the account information from Facebook.

CREATE TABLE `users` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `oauth_provider` enum('','facebook','google','twitter') COLLATE utf8_unicode_ci NOT NULL,
 `oauth_uid` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `first_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `last_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `gender` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
 `picture` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
 `link` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

2. The following SQL creates a user_posts table in the MySQL database to store the user’s posts information from Facebook.

CREATE TABLE `user_posts` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `user_id` int(11) NOT NULL,
 `post_id` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `message` text COLLATE utf8_unicode_ci NOT NULL,
 `created_time` datetime NOT NULL,
 `published_by` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `attach_type` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
 `attach_title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `attach_image` text COLLATE utf8_unicode_ci NOT NULL,
 `attach_link` text COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Facebook SDK for PHP

Facebook PHP SDK is used to authenticate with Facebook API. The files of the Facebook PHP SDK (v5) are included in the facebook-php-graph-sdk/ directory. You don’t need to download it separately, Facebook PHP SDK library is included in our source code.

Database and API Configuration (config.php)

The database settings and Facebook API configuration constant variables are defined in the config.php file.

Database Constants:

  • DB_HOST – Specify the database host.
  • DB_USERNAME – Specify the database username.
  • DB_PASSWORD – Specify the database password.
  • DB_NAME – Specify the database name.
  • DB_USER_TBL – Specify the table name where the user’s account data will be stored.
  • DB_POST_TBL – Specify the table name where the user’s feed data will be stored.

Facebook API Constants:

  • FB_APP_ID – Specify the Facebook App ID.
  • FB_APP_SECRET – Specify the Facebook App Secret.
  • FB_REDIRECT_URL – Specify the Callback URL.
  • FB_POST_LIMIT – Number of posts that will be fetched from the timeline and display in the web page.

Call Facebook API:
The PHP SDK library is used to connect with Facebook API and working with OAuth client.

<?php 
/*
 * Database and API Configuration
 */

// Database configuration
define('DB_HOST''MySQL_Database_Host');
define('DB_USERNAME''MySQL_Database_Username');
define('DB_PASSWORD''MySQL_Database_Password');
define('DB_NAME''MySQL_Database_Name');
define('DB_USER_TBL''users');
define('DB_POST_TBL''user_posts');

// Facebook API configuration
define('FB_APP_ID''Insert_Facebook_App_ID'); // Replace {app-id} with your app id
define('FB_APP_SECRET''Insert_Facebook_App_Secret'); // Replace {app-secret} with your app secret
define('FB_REDIRECT_URL''Callback_URL'); 
define('FB_POST_LIMIT'10);

// Start session
if(!session_id()){
    
session_start();
}

// Include the autoloader provided in the SDK
require_once __DIR__ '/facebook-php-graph-sdk/autoload.php';

// Include required libraries
use Facebook\Facebook;
use 
Facebook\Exceptions\FacebookResponseException;
use 
Facebook\Exceptions\FacebookSDKException;

// Call Facebook API
$fb = new Facebook(array(
    
'app_id' => FB_APP_ID,
    
'app_secret' => FB_APP_SECRET,
    
'default_graph_version' => 'v3.2',
));

// Get redirect login helper
$helper $fb->getRedirectLoginHelper();

// Try to get access token
try {
    if(isset(
$_SESSION['facebook_access_token'])){
        
$accessToken $_SESSION['facebook_access_token'];
    }else{
          
$accessToken $helper->getAccessToken();
    }
} catch(
FacebookResponseException $e) {
     echo 
'Graph returned an error: ' $e->getMessage();
      exit;
} catch(
FacebookSDKException $e) {
    echo 
'Facebook SDK returned an error: ' $e->getMessage();
      exit;
}

Note that: You’ll find the App ID and App Secret on your Facebook App settings page.

User Class (User.class.php)

The User class handles the database related operations (connect, insert, update, and delete) using PHP and MySQL.

  • __construct() – Connect to the database as per the credentials specified in the config.php file.
  • checkUser()
    • Insert or update the user profile data based on the OAuth provider and ID.
    • Returns the user’s account data as an array.
  • getPosts() – Fetch posts data from the user_posts table.
  • insertPost() – Insert post data in the user_posts table.
  • deletePosts() – Delete post data based on the user ID.
<?php 
/*
 * User Class
 * This class is used for database related (connect, insert, update, and delete) operations
 * @author    CodexWorld.com
 * @url        http://www.codexworld.com
 * @license    http://www.codexworld.com/license
 */

class User {
    private 
$dbHost     DB_HOST;
    private 
$dbUsername DB_USERNAME;
    private 
$dbPassword DB_PASSWORD;
    private 
$dbName     DB_NAME;
    private 
$userTbl    DB_USER_TBL;
    private 
$postTbl    DB_POST_TBL;
    
    function 
__construct(){
        if(!isset(
$this->db)){
            
// Connect to the database
            
$conn = new mysqli($this->dbHost$this->dbUsername$this->dbPassword$this->dbName);
            if(
$conn->connect_error){
                die(
"Failed to connect with MySQL: " $conn->connect_error);
            }else{
                
$this->db $conn;
            }
        }
    }
    
    function 
checkUser($userData = array()){
        if(!empty(
$userData)){
            
// Check whether user data already exists in database
            
$prevQuery "SELECT * FROM ".$this->userTbl." WHERE oauth_provider = '".$userData['oauth_provider']."' AND oauth_uid = '".$userData['oauth_uid']."'";
            
$prevResult $this->db->query($prevQuery);
            if(
$prevResult->num_rows 0){
                
// Update user data if already exists
                
$query "UPDATE ".$this->userTbl." SET first_name = '".$userData['first_name']."', last_name = '".$userData['last_name']."', email = '".$userData['email']."', gender = '".$userData['gender']."', picture = '".$userData['picture']."', link = '".$userData['link']."', modified = NOW() WHERE oauth_provider = '".$userData['oauth_provider']."' AND oauth_uid = '".$userData['oauth_uid']."'";
                
$update $this->db->query($query);
            }else{
                
// Insert user data
                
$query "INSERT INTO ".$this->userTbl." SET oauth_provider = '".$userData['oauth_provider']."', oauth_uid = '".$userData['oauth_uid']."', first_name = '".$userData['first_name']."', last_name = '".$userData['last_name']."', email = '".$userData['email']."', gender = '".$userData['gender']."', picture = '".$userData['picture']."', link = '".$userData['link']."', created = NOW(), modified = NOW()";
                
$insert $this->db->query($query);
            }
            
            
// Get user data from the database
            
$result $this->db->query($prevQuery);
            
$userData $result->fetch_assoc();
        }
        
        
// Return user data
        
return $userData;
    }
    
    public function 
getPosts($conditions = array()){
        
$sql 'SELECT *';
        
$sql .= ' FROM '.$this->postTbl;
        if(
array_key_exists("where",$conditions)){
            
$sql .= ' WHERE ';
            
$i 0;
            foreach(
$conditions['where'] as $key => $value){
                
$pre = ($i 0)?' AND ':'';
                
$sql .= $pre.$key." = '".$value."'";
                
$i++;
            }
        }
        
        if(
array_key_exists("order_by",$conditions)){
            
$sql .= ' ORDER BY '.$conditions['order_by']; 
        }else{
            
$sql .= ' ORDER BY created_time DESC '
        }
        
        if(
array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
            
$sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit']; 
        }elseif(!
array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
            
$sql .= ' LIMIT '.$conditions['limit']; 
        }
        
        
$result $this->db->query($sql);
        
        if(
array_key_exists("return_type",$conditions) && $conditions['return_type'] != 'all'){
            switch(
$conditions['return_type']){
                case 
'count':
                    
$data $result->num_rows;
                    break;
                case 
'single':
                    
$data $result->fetch_assoc();
                    break;
                default:
                    
$data '';
            }
        }else{
            if(
$result->num_rows 0){
                while(
$row $result->fetch_assoc()){
                    
$data[] = $row;
                }
            }
        }
        return !empty(
$data)?$data:false;
    }
    
    function 
insertPost($data){
        if(!empty(
$data) && is_array($data)){
            
$columns '';
            
$values  '';
            
$i 0;
            foreach(
$data as $key=>$val){
                
$pre = ($i 0)?', ':'';
                
$columns .= $pre.$key;
                
$values  .= $pre."'".$this->db->real_escape_string($val)."'";
                
$i++;
            }
            
$query "INSERT INTO ".$this->postTbl." (".$columns.") VALUES (".$values.")";
            
$insert $this->db->query($query);
            return 
$insert?$this->db->insert_id:false;
        }else{
            return 
false;
        }
    }
    
    public function 
deletePosts($userID){
        
$query "DELETE FROM ".$this->postTbl." WHERE user_id = $userID";
        
$delete $this->db->query($query);
        return 
$delete?true:false;
    }
}

Login and Fetch User Feed from Facebook Timeline (index.php)

In this file, the authentication process is hanlded with Facebook API using PHP.

  • Initially, the OAuth URL is generated using the getLoginUrl() method of Login Helper class and Facebook Sign-in button is displayed on the web page.
  • After the authentication with Facebook account, the following happens:
    • The profile info is retrieved from the Facebook account using Facebook Graph API.
    • The account data is inserted into the database using checkUser() function of User class.
    • The user’s account info is stored in the SESSION.
    • The post feed is retrieved from the user’s timeline using the Facebook Graph API (/{user-id}/feed).
    • Fetch the single post info using Facebook Graph API (/{post-id}).
    • Fetch the post attachment info using Facebook Graph API (/{post-id}/attachments).
    • Delete old posts data from the database and insert the latest post data in the database.
  • The Facebook profile details (Name, First name, Last name, Email, Gender, Picture, and Profile link) is displayed on the webpage.
  • The Posts and links which are published by the authenticated user are listed on the web page.
  • The Logout link is generated using getLogoutUrl() method of the login helper class.
<?php 
// Include configuration file
require_once 'config.php';

// Include User class
require_once 'User.class.php';

if(isset(
$accessToken)){
    if(isset(
$_SESSION['facebook_access_token'])){
        
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
    }else{
        
// Put short-lived access token in session
        
$_SESSION['facebook_access_token'] = (string) $accessToken;
        
          
// OAuth 2.0 client handler helps to manage access tokens
        
$oAuth2Client $fb->getOAuth2Client();
        
        
// Exchanges a short-lived access token for a long-lived one
        
$longLivedAccessToken $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']);
        
$_SESSION['facebook_access_token'] = (string) $longLivedAccessToken;
        
        
// Set default access token to be used in script
        
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
    }
    
    
// Redirect the user back to the same page if url has "code" parameter in query string
    
if(isset($_GET['code'])){
        
header('Location: ./');
    }
    
    
// Getting user's profile info from Facebook
    
try {
        
$graphResponse $fb->get('/me?fields=name,first_name,last_name,email,link,gender,picture');
        
$fbUser $graphResponse->getGraphUser();
    } catch(
FacebookResponseException $e) {
        echo 
'Graph returned an error: ' $e->getMessage();
        
session_destroy();
        
// Redirect user back to app login page
        
header("Location: ./");
        exit;
    } catch(
FacebookSDKException $e) {
        echo 
'Facebook SDK returned an error: ' $e->getMessage();
        exit;
    }
    
    
// Initialize User class
    
$user = new User();
    
    
// Getting user's profile data
    
$fbUserData = array();
    
$fbUserData['oauth_uid']  = !empty($fbUser['id'])?$fbUser['id']:'';
    
$fbUserData['first_name'] = !empty($fbUser['first_name'])?$fbUser['first_name']:'';
    
$fbUserData['last_name']  = !empty($fbUser['last_name'])?$fbUser['last_name']:'';
    
$fbUserData['email']      = !empty($fbUser['email'])?$fbUser['email']:'';
    
$fbUserData['gender']     = !empty($fbUser['gender'])?$fbUser['gender']:'';
    
$fbUserData['picture']    = !empty($fbUser['picture']['url'])?$fbUser['picture']['url']:'';
    
$fbUserData['link']       = !empty($fbUser['link'])?$fbUser['link']:'';
    
    
// Insert or update user data to the database
    
$fbUserData['oauth_provider'] = 'facebook';
    
$userData $user->checkUser($fbUserData);
    
$userID $userData['id'];
    
    
// Storing user data in the session
    
$_SESSION['userData'] = $userData;
    
    if(
$userData){
        
// Fetch the user's feed
        
$userFeeds $fb->get("/".$fbUser['id']."/feed?limit=".FB_POST_LIMIT$accessToken);
        
$feedBody $userFeeds->getDecodedBody();
        
$feedData $feedBody["data"];
        
        if(!empty(
$feedData)){
            
// Delete old posts from the database
            
$user->deletePosts($userID);
            
            
$postData = array();
            foreach(
$feedData as $row){
                if(!empty(
$row['id'])){
                    
$postID $row['id'];
                    
                    
// Fetch the post info
                    
$response $fb->get('/'.$postID$accessToken);
                    
$data $response->getDecodedBody();
                    
                    
// Fetch post attachment info
                    
$response $fb->get('/'.$postID.'/attachments'$accessToken);
                    
$attchData $response->getDecodedBody();
                    
                    
$postData['user_id'] = $userID;
                    
$postData['post_id'] = $data['id'];
                    
$postData['message'] = $data['message'];
                    
$postData['created_time'] = $data['created_time'];
                    
$postData['published_by'] = $fbUser['id'];
                    
$postData['attach_type'] = !empty($attchData['data'][0]['type'])?$attchData['data'][0]['type']:'';
                    
$postData['attach_title'] = !empty($attchData['data'][0]['title'])?$attchData['data'][0]['title']:'';
                    
$postData['attach_image'] = !empty($attchData['data'][0]['media']['image']['src'])?$attchData['data'][0]['media']['image']['src']:'';
                    
$postData['attach_link'] = !empty($attchData['data'][0]['url'])?$attchData['data'][0]['url']:'';
                    
                    
// Insert post data in the database
                    
$insertPost $user->insertPost($postData);
                }
            }
        }
    }
    
    
// Get logout url
    
$logoutURL $helper->getLogoutUrl($accessTokenFB_REDIRECT_URL.'logout.php');
    
    
// Render Facebook profile data
    
if(!empty($userData)){
        
$output  '<h2>Facebook Profile Details</h2>';
        
$output .= '<div class="ac-data">';
        
$output .= '<img src="'.$userData['picture'].'"/>';
        
$output .= '<p><b>Facebook ID:</b> '.$userData['oauth_uid'].'</p>';
        
$output .= '<p><b>Name:</b> '.$userData['first_name'].' '.$userData['last_name'].'</p>';
        
$output .= '<p><b>Email:</b> '.$userData['email'].'</p>';
        
$output .= '<p><b>Gender:</b> '.$userData['gender'].'</p>';
        
$output .= '<p><b>Logged in with:</b> Facebook'.'</p>';
        
$output .= '<p><b>Profile Link:</b> <a href="'.$userData['link'].'" target="_blank">Click to visit Facebook page</a></p>';
        
$output .= '<p><b>Logout from <a href="'.$logoutURL.'">Facebook</a></p>';
        
$output .= '</div>';
    }else{
        
$output '<h3 style="color:red">Some problem occurred, please try again.</h3>';
    }
}else{
    
// Get login url
    
$permissions = ['email']; // Optional permissions
    
$loginURL $helper->getLoginUrl(FB_REDIRECT_URL$permissions);
    
    
// Render Facebook login button
    
$output '<a href="'.htmlspecialchars($loginURL).'"><img src="images/fb-login-btn.png"></a>';
}
?> <!DOCTYPE html> <html lang="en-US"> <head> <title>Login with Facebook using PHP by CodexWorld</title> <meta charset="utf-8"> <!-- stylesheet file --> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <div class="fb-box"> <!-- Display login button / Facebook profile information --> <?php echo $output?> </div> <!-- List user posts --> <?php     <?php
    
if(!empty($userID)){
        
// Fetch posts from the database
        
$con = array(
            
'where' => array('user_id' => $userID),
            
'limit' => FB_POST_LIMIT
        
);
        
$posts $user->getPosts($con);
        
        if(!empty(
$posts)){
    
?> <div class="post-list"> <h2>Facebook Feeds</h2>             <?php foreach($posts as $row){
                
$image = !empty($row['attach_image'])?'<img src="'.$row['attach_image'].'"/>':'';
                
$title = (strlen($row['attach_title'])>55)?substr($row['attach_title'],0,55):$row['attach_title'];
                
$message = (strlen($row['message'])>120)?substr($row['message'],0,110).'...':$row['message'];
            
?> <a href="<?php echo $row['attach_link']; ?>" target="_blank"> <div class="pbox"> <div class="img"><?php echo $image?></div> <div class="cont"> <h4><?php echo $title?></h4> <p><?php echo $message?></p> </div> </div> </a> <?php ?> </div>     <?php }
    } 
?> </div> </body> </html>

Logout (logout.php)

When the user wishes to log out from their Facebook account, the logout.php file is loaded.

  • Remove access token and user data from the SESSION.
  • Redirect the user to the login page.
<?php 
// Include configuration file
require_once 'config.php';

// Remove access token from session
unset($_SESSION['facebook_access_token']);

// Remove user data from session
unset($_SESSION['userData']);

// Redirect to the homepage
header("Location:index.php");
?>

Facebook Login without page refresh using JavaScript.

Conclusion

If you want to add social login feature on the website, Facebook authentication is the most reliable way to allow the user to login with their social account. This script helps you to enhance the Facebook login functionality. The logged-in user can view their timeline posts on the website without visiting Facebook using PHP SDK and Graph API. You can use the Facebook posts parser functionality for many purposes in the web application.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

1 Comment

  1. Joel Said...

Leave a reply

keyboard_double_arrow_up