How to extend access token validity since offline_access deprecation

//using a javascript for popup for facebook login

FB.login(function(response) {

            if (response.authResponse) {

                   var accessToken = response.authResponse.accessToken;

//got the accesstoken with 1-2 hours expire time

//got the accesstoken into a controller called facebook controller

        $request = $this->getRequest();
        $params = $request->getParams();
        $token=$params['accessToken'];

//taking the access token to extend to 60days

        $conf = $this->getConfigs();
        $appid = $conf['fbdetails']['appid'];
        $secret = $conf['fbdetails']['secret'];
        $baseurl = $conf['app']['baseurl'];

//After the execution of below code , we will have a response with acess token expire time to 60days.

        $token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$appid."&client_secret=".$secret."&grant_type=fb_exchange_token&fb_exchange_token=".$token;

// Above response is given for parsing.

        $c = curl_init();
        curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($c, CURLOPT_URL, $token_url);
        $contents = curl_exec($c);
        $err  = curl_getinfo($c,CURLINFO_HTTP_CODE);
        curl_close($c);

        $paramsfb = null;
        parse_str($contents, $paramsfb);

//after the parsing the contents in the above execution code the new extended accesstoken is stored.

        $user_session = new Zend_Session_Namespace('fbuser');
        $user_session->access_token = $paramsfb['access_token'];

//stored to session.

        $this->_redirect('/home');

//Have a nice coding


Actually what was said:

If the access_token is generated from a server-side OAuth call, the resulting access_token will have the longer expiration time. If the call is made while there is still a valid access_token for that user, the returned access_token from this second call will remain the same and only the expiration time will be extended. Again, calling this multiple times during the same day will result only in the first call extending the expiration time.

Which means that it will be just longer than client-side generated token, and to receive extended token (60 days) you need do it manually by issuing request to:

https://graph.facebook.com/oauth/access_token?             
    client_id=APP_ID&
    client_secret=APP_SECRET&
    grant_type=fb_exchange_token&
    fb_exchange_token=EXISTING_ACCESS_TOKEN

This token can still became invalid for several reasons, and how to handle this described in How-To: Handle expired access tokens blog post.

Update:
As of Aug 07, 2012 you can use setExtendedAccessToken method to extend access_token instead of manually constructing URL and retrieving details.


Edit (August 14th 2012):
A week ago the official Facebook PHP SDK was updated. The function name was changed to setExtendedAccessToken, and it was decided we actually needed to destroy the session afterwards, to remove the risk of having two active sessions.
Also, the function no longer actually returns the token, but instead stores it within the persistant data. You can therefore get the new access token with the public function getAccessToken afterwards. Grab the new SDK from official Facebook PHP SDK github page to make sure you're up to date.

Original Answer:

I have added a new public function to the base_facebook.php file, which returns an new access token which expires in 60 days. You can make a request to this function after you've received the normal access token. I've not tested, but I assume you also need to enable 'deprecate offline_access" in your Advanced settings of the Developer App.

Just add this to your base_facebook.php inside the facebook class and make a call to it. It works for me.

 public function getExtendedAccessToken(){

    try {
        // need to circumvent json_decode by calling _oauthRequest
          // directly, since response isn't JSON format.
        $access_token_response =
            $this->_oauthRequest(
                $this->getUrl('graph', '/oauth/access_token'), array(
                    'client_id' => $this->getAppId(),
                    'client_secret' => $this->getAppSecret(),
                    'grant_type'=>'fb_exchange_token',
                    'fb_exchange_token'=>$this->getAccessToken()
                )
            );
    } catch (FacebookApiException $e) {
      // most likely that user very recently revoked authorization.
      // In any event, we don't have an access token, so say so.
      return false;
    }

    if (empty($access_token_response)) {
      return false;
    }

    $response_params = array();
    parse_str($access_token_response, $response_params);
    if (!isset($response_params['access_token'])) {
      return false;
    }

    return $response_params['access_token'];
}