Table Of Contents:
You want to access linkedIn API using OAuth Protocol handshake?
Here is a Screencast and a written tutorial showing you how to access linkedIn API in PHP using Zend_Oauth Zend module.
The LinkedIn API Access ScreenCast
http://blip.tv/file/get/Formatix-linkedInAPIPhpZendOauthEng748.mp4The LinkedIn API Access Written Tutorial
Get Zend FrameWork Library
svn checkout http://framework.zend.com/svn/framework/standard/trunk/library/
Get Zend FrameWork Incubator Library
svn checkout http://framework.zend.com/svn/framework/standard/incubator/library/
If you are under Windows you can Download Tortoise SVN to be able to extract the Zend Sources
To do so we first need to add Zend Library and Zend Incubator Library to the Include Path:
set_include_path( '/home/mywebspace/libray/' . PATH_SEPARATOR . '/home/mywebspace/incubator/libray/' . PATH_SEPARATOR . get_include_path() );
Of Course /home/mywebspace/libray/ and /home/mywebspace/incubator/libray/ must be replaced with your own paths.
If you are under windows this Paths will look like C:/mylibrariesfolder/library’
Now we can include the Zend_Oauth Class definition we need that is to say Zend_Oauth_Consumer
require_once('Zend/Oauth/Consumer.php');
At the time I am writing this tutorial there is a little issue that prevents us to use Zend_Oauth as it is to connect to LinkedIn using Oauth Protocol 0.1 Rev A
To Bypass this issue:
public function assembleParams()
{
$params = array();
$params['oauth_token'] = $this->_consumer->getLastRequestToken()->getToken();
$callback = $this->_consumer->getCallbackUrl(); // callback correct? Not user auth uri?
// if (!empty($callback)) {
// $params['oauth_callback'] = $callback;
// }
if (!empty($this->_parameters)) {
$params = array_merge($params, $this->_parameters);
}
return $params;
}
You must tune the $options inputs such as localUrl, callbackUrl, and fill in the blanks for consumerKey and consumerSecret with the Keys you retreived at Step 0.
$options = array( 'version' => '1.0', 'localUrl' => 'http://localhost/Projets/API/oauth.php', 'callbackUrl' => 'http://localhost/Projets/API/oauth.php', 'requestTokenUrl' => 'https://api.linkedin.com/uas/oauth/requestToken', 'userAuthorisationUrl' => 'https://api.linkedin.com/uas/oauth/authorize', 'accessTokenUrl' => 'https://api.linkedin.com/uas/oauth/accessToken', 'consumerKey' => 'YOUR_CONSUMER_KEY', 'consumerSecret' => 'YOUR_SECRET_KEY' ); $consumer = new Zend_Oauth_Consumer( $options );
// Start Session to be able to store Request Token and Access Token
session_start ();
if ( !isset ( $_SESSION ['ACCESS_TOKEN'] )) {
// We do not have any access token Yet
if (! empty ( $_GET )) {
// But We have some parameters passed throw the URL
// Get the LinkedIn Access Token
$token = $consumer->getAccessToken ( $_GET, unserialize ( $_SESSION ['REQUEST_TOKEN'] ) );
// Store the LinkedIn Access Token
$_SESSION ['ACCESS_TOKEN'] = serialize ( $token );
} else {
// We have Nothing
// Start Requesting a LinkedIn Request Token
$token = $consumer->getRequestToken ();
// Store the LinkedIn Request Token
$_SESSION ['REQUEST_TOKEN'] = serialize ( $token );
// Redirect the Web User to LinkedIn Authentication Page
$consumer->redirect ();
}
} else {
// We've already Got a LinkedIn Access Token
// Restore The LinkedIn Access Token
$token = unserialize ( $_SESSION ['ACCESS_TOKEN'] );
}
Now that authentication is done we can request data from LinkedIn
// Use HTTP Client with built-in OAuth request handling
$client = $token->getHttpClient($options);
// Set LinkedIn URI
$client->setUri('https://api.linkedin.com/v1/people/~');
// Set Method (GET, POST or PUT)
$client->setMethod(Zend_Http_Client::GET);
// Get Request Response
$response = $client->request();
// Get the XML containing User's Profile
$content = $response->getBody();
XML content looks like this:

// Use simplexml to transform XML to a PHP Object
$xml = simplexml_load_string($content);
echo 'First Name: ' . $xml->{'first-name'};
echo '<br/>';
echo 'Last Name: ' . $xml->{'last-name'};
echo '<br/>';
echo 'Headline: ' . $xml->{'headline'};
SimpleXml Object Structure looks like this:

You can create a file called oauth.php and paste the following php code in it
<?php
set_include_path( 'C:/Users/Formatix.Eu/Desktop/MesProjets/API/library' . PATH_SEPARATOR . 'C:/Users/Formatix.Eu/Desktop/MesProjets/API/incubator/library' . PATH_SEPARATOR . get_include_path() );
require_once('Zend/Oauth/Consumer.php');
$options = array(
'version' => '1.0',
'localUrl' => 'http://localhost/Projets/API/oauth.php',
'callbackUrl' => 'http://localhost/Projets/API/oauth.php',
'requestTokenUrl' => 'https://api.linkedin.com/uas/oauth/requestToken',
'userAuthorisationUrl' => 'https://api.linkedin.com/uas/oauth/authorize',
'accessTokenUrl' => 'https://api.linkedin.com/uas/oauth/accessToken',
'consumerKey' => 'YOUR_CONSUMER_KEY',
'consumerSecret' => 'YOUR_CONSUMER_SECRET_KEY'
);
$consumer = new Zend_Oauth_Consumer( $options );
// Start Session to be able to store Request Token and Access Token
session_start ();
if ( !isset ( $_SESSION ['ACCESS_TOKEN'] )) {
// We do not have any access tokem Yet
if (! empty ( $_GET )) {
// But We have some parameters passed throw the URL
// Get the LinkedIn Access Token
$token = $consumer->getAccessToken ( $_GET, unserialize ( $_SESSION ['REQUEST_TOKEN'] ) );
// Store the LinkedIn Access Token
$_SESSION ['ACCESS_TOKEN'] = serialize ( $token );
} else {
// We have Nothing
// Start Requesting a LinkedIn Request Token
$token = $consumer->getRequestToken ();
// Store the LinkedIn Request Token
$_SESSION ['REQUEST_TOKEN'] = serialize ( $token );
// Redirect the Web User to LinkedIn Authentication Page
$consumer->redirect ();
}
} else {
// We've already Got a LinkedIn Access Token
// Restore The LinkedIn Access Token
$token = unserialize ( $_SESSION ['ACCESS_TOKEN'] );
}
// Use HTTP Client with built-in OAuth request handling
$client = $token->getHttpClient($options);
// Set LinkedIn URI
$client->setUri('https://api.linkedin.com/v1/people/~');
// Set Method (GET, POST or PUT)
$client->setMethod(Zend_Http_Client::GET);
// Get Request Response
$response = $client->request();
// Get the XML containing User's Profile
$content = $response->getBody();
// Uncomment Following Line To display XML result
// header('Content-Type: ' . $response->getHeader('Content-Type'));
// echo $content;
// exit;
// Use simplexml to transform XML to a PHP Object
$xml = simplexml_load_string($content);
// Uncomment Following Line To display Simple XML Object Structure
// echo '<pre>';
// print_r($xml);
// echo'</pre>';
// Display Profile Information as you wish
echo 'First Name: ' . $xml->{'first-name'};
echo '<br/>';
echo 'Last Name: ' . $xml->{'last-name'};
echo '<br/>';
echo 'Headline: ' . $xml->{'headline'};
?>
<?php
/*
*
* @abstract: This Class can be used to Access LinkedIn API using Oauth Authentication Protocol
* @author: Christophe Fiat
* @version: 0.1 2009-11-30
* @copyright: FormatiX.EU
*
*/
class linkedIn
{
private $options;
private $consumer;
private $client;
private $token;
public function __construct($params)
{
set_include_path( 'C:/Users/Formatix.Eu/Desktop/MesProjets/API/library' . PATH_SEPARATOR . 'C:/Users/Formatix.Eu/Desktop/MesProjets/API/incubator/library' . PATH_SEPARATOR . get_include_path() );
require_once('Zend/Oauth/Consumer.php');
$this->options = array(
'version' => '1.0',
'localUrl' => 'http://localhost/Projets/API/oauth.php',
'callbackUrl' => 'http://localhost/Projets/API/oauth.php',
'requestTokenUrl' => 'https://api.linkedin.com/uas/oauth/requestToken',
'userAuthorisationUrl' => 'https://api.linkedin.com/uas/oauth/authorize',
'accessTokenUrl' => 'https://api.linkedin.com/uas/oauth/accessToken',
'consumerKey' => $params['consumerKey'],
'consumerSecret' => $params['consumerSecret']
);
$this->consumer = new Zend_Oauth_Consumer( $this->options );
}
public function connect()
{
// Start Session to be able to store Request Token and Access Token
session_start ();
if ( !isset ( $_SESSION ['ACCESS_TOKEN'] )) {
// We do not have any Access token Yet
if (! empty ( $_GET )) {
// But We have some parameters passed throw the URL
// Get the LinkedIn Access Token
$this->token = $this->consumer->getAccessToken ( $_GET, unserialize ( $_SESSION ['REQUEST_TOKEN'] ) );
// Store the LinkedIn Access Token
$_SESSION ['ACCESS_TOKEN'] = serialize ( $this->token );
} else {
// We have Nothing
// Start Requesting a LinkedIn Request Token
$this->token = $this->consumer->getRequestToken ();
// Store the LinkedIn Request Token
$_SESSION ['REQUEST_TOKEN'] = serialize ( $this->token );
// Redirect the Web User to LinkedIn Authentication Page
$this->consumer->redirect ();
}
} else {
// We've already Got a LinkedIn Access Token
// Restore The LinkedIn Access Token
$this->token = unserialize ( $_SESSION ['ACCESS_TOKEN'] );
}
// Use HTTP Client with built-in OAuth request handling
$this->client = $this->token->getHttpClient($this->options);
}
public function whoAmI()
{
// Set LinkedIn URI
$this->client->setUri('https://api.linkedin.com/v1/people/~');
// Set Method (GET, POST or PUT)
$this->client->setMethod(Zend_Http_Client::GET);
// Get Request Response
$response = $this->client->request();
// Get the XML containing User's Profile
$content = $response->getBody();
// Uncomment Following Line To display XML result
// header('Content-Type: ' . $response->getHeader('Content-Type'));
// echo $content;
// exit;
// Use simplexml to transform XML to a PHP Object
$xml = simplexml_load_string($content);
// Uncomment Following Line To display Simple XML Object Structure
// echo '<pre>';
// print_r($xml);
// echo'</pre>';
// Display Profile Information as you wish
echo 'First Name: ' . $xml->{'first-name'};
echo '<br/>';
echo 'Last Name: ' . $xml->{'last-name'};
echo '<br/>';
echo 'Headline: ' . $xml->{'headline'};
}
} // Class End
$params = Array( 'consumerKey' => 'YOUR_CONSUMER_KEY',
'consumerSecret' => 'YOUR_CONSUMER_SECRET_KEY'
);
$linkedin = new linkedIn($params);
$linkedin->connect();
$linkedin->whoAmI();
?>
32 Responses
George Carter
11|Jan|2010 1Hi Chris,
I am new to the Linkedin API and have been looking for a simple tutorial to introduce me to its use. I’ve found your tutorial to be very useful. At first, I thought reading your message and ignoring the video would be enough. But I found that both go together nicely. Your video not only allows me to “look over your shoulder” as you code but gives an idea of how to test your code as you proceed, and how to troubleshoot some errors you may come across. Are there any websites that use your imlpementation?
I consider myself a beginner-to-intermediate level PHP programmer and had little difficulty following your code. But if you could please elaborate on one thing for me.
Your code includes:
$_SESSION ['ACCESS_TOKEN'] = serialize ( $token );
$_SESSION ['REQUEST_TOKEN'] = serialize ( $token );
$token = unserialize ( $_SESSION ['ACCESS_TOKEN'] );
Why do you have to use the serialize and unserialize commands?
Let me first guess:
1. $token is an object, not a scalar like 1, 100, ‘g’, etc. To assign an object to a variable, it MUST be serialized to retain the object structure.
So we do: $_SESSION ['REQUEST_TOKEN'] = serialize ( $token );
2. Now $_SESSION ['REQUEST_TOKEN'] is not usable because it is in a serialized form. It is in a string form that represents an object. To use the value of $_SESSION ['REQUEST_TOKEN'] as in object, we must unserialize it.
So we do: $token = unserialize ( $_SESSION ['ACCESS_TOKEN'] );
What do you think?
Thanks,
George
Chris
18|Jan|2010 2Hi George!
Sorry for late response but I was on a time consuming project lately.
All you say is totally correct I can just confirm your guesses! Happy you enjoyed the screencast and happy to see that the screencast and the written tutorail are complementary :)
Chris
Julien
11|Feb|2010 3Thank you for your super great tutorial.
Nevertheless, i have a problem.
I use a Macbook and MAMP.
PHP version > 5.2.6
Session Support enabled
Registered save handlers files user sqlite
Registered serializer handlers php php_binary
My test URL is http://localhost:8888/API/test.php.
I precise it into integration url on my application into developper linkedin platform.
I have checkout the files, modify the lines with the callback.
this is the content of my test.php file: http://pastie.org/820356
this is the content of the function getRedirectUrl : http://pastie.org/820359
I put it so that you can compare the result below.
The result of the execution of test.php is always:
“We have Nothing 1 3 ”
So, do you know where i am wrong please?
Thank you very much.
Chris
12|Feb|2010 4Hi Julien
Note that Zend Framework 1.10.0 was not released when I made the tutorial. So If you use Zend 1.10.0 you might not need to use the workaround I provided.
So first I let you check your Zend Framework version. I plan doing a new Linkedin API screencast using Zend Framework 1.10 soon.
Second Make sure Php is configured to display ALL errors
Then I assume that you are not Redirected to LinkedIn Login Form.
So before digging into getRedirectUrl lets look at “public function redirect” in Consumer.php
Just print the $redirectUrl returned by getRedirectUrl.
By printing debug data you might/should have a “header already sent” error when hitting header(‘Location: ‘ . $redirectUrl);
Then maybe you’ll have a clue to solve your problem otherwise share your results with us and will try to continue solving it.
Warm Regards,
Chris.
Julien
12|Feb|2010 5OK thanks. Indeed i’m not redirected to linkedinPage.
So, i use the last version of Zend, i guess, because i have downloaded files with svn link yesterday.
i have allowed all errors to be displayed and this is the error:
Fatal error: Uncaught exception ‘Zend_Uri_Exception’ with message ‘$uri is not a string’ in /Applications/MAMP/htdocs/API/library/Zend/Uri/Http.php:174 Stack trace: #0 /Applications/MAMP/htdocs/API/library/Zend/Oauth/Http/UserAuthorization.php(45): Zend_Uri_Http::fromString(NULL) #1 /Applications/MAMP/htdocs/API/library/Zend/Oauth/Consumer.php(157): Zend_Oauth_Http_UserAuthorization->getUrl() #2 /Applications/MAMP/htdocs/API/library/Zend/Oauth/Consumer.php(187): Zend_Oauth_Consumer->getRedirectUrl(NULL, NULL) #3 /Applications/MAMP/htdocs/API/test.php(50): Zend_Oauth_Consumer->redirect() #4 {main} thrown in /Applications/MAMP/htdocs/API/library/Zend/Uri/Http.php on line 174
These are my options:
$options = array(
‘version’ => ‘1.0′,
‘localUrl’ => ‘http://localhost:8888/API/test.php’,
‘callbackUrl’ => ‘http://localhost:8888/API/test.php’,
‘requestTokenUrl’ => ‘https://api.linkedin.com/uas/oauth/requestToken’,
‘userAuthorisationUrl’ => ‘https://api.linkedin.com/uas/oauth/authorize’,
‘accessTokenUrl’ => ‘https://api.linkedin.com/uas/oauth/accessToken’,
‘consumerKey’ => ‘blabla’,
‘consumerSecret’ => ‘blabla’
);
Thank you!
Chris
14|Feb|2010 6Hi Julien
In fact if you look at my screencast you’ll see that I went through the same error.
I had written userAuthorizationUrl instead of userAuthorisationUrl.
The thing funny is that in the New Zend Oauth that you find in Zend 1.10 they spelt it userAuthorizationUrl !
So if you use the new spelling I bet you should get rid of this error.
Julien
15|Feb|2010 7It’s great! Thank you very much.
Bugorr
25|Feb|2010 8Hi Chris,
This seems to be the most complete guided tutorial.
What would cause error: Call to a member function setUri() on a non-object in….
$this->client->setUri(‘https://api.linkedin.com/v1/people/~’);
My setup: Windows 7, latest XAMPP with latest Zend Framework.
Authorization works – no problem
Array
(
[REQUEST_TOKEN] => O:24:”Zend_Oauth_Token_Request”:1:{s:10:”�*�_params”;a:3:{s:11:”oauth_token”;s:36:”b1cc21e9-e793-4c35-a065-dccca24094f3″;s:18:”oauth_token_secret”;s:36:”4488f172-3f5b-4d56-9e97-7527db49b83f”;s:24:”oauth_callback_confirmed”;s:4:”true”;}}
)
Can you tell from this information what possibly could go wrong?
Thanks a lot.
Chris
26|Feb|2010 9Hi Bugorr,
Thx!
Since you are using the latest version of the Zend Framework did you replace userAuthorisationUrl by userAuthorizationUrl as stated in the comment just above.
Do make sure ALL the errors are displayed, this is a must have when debugging. You can add an error_reporting(E_ALL); call to be sure.
Looks like $this->client is not a proper Object, so something went wrong in connect class. So that is in this class that you must first start debugging.
BR,
Chris.
Bugorr
03|Mar|2010 10Hi Chris,
Believe it or not, but I was able to solve the problem.
I’ve realized that I’ve created an error spreading source
in different files and authentication was not able to be
completed.
This approach was used on purpose and that’s how…
Anyhow, thanks a ton with a bunch and cherry on top.
Take care,
Bugorr.
Chris
03|Mar|2010 11Hi Bugorr,
Glad to hear you problem is solved.
Feel free to share any other issues or any tutorial suggestions.
Warm regards,
Chris.
Jeroen Bourgois
21|Mar|2010 12Hi, just wanted to let you know I used and extended your class a bit, to be able to do network updates to linkedin. I also fixed that spelling mistake and tested with Zend 1.10. Hope this can be as useful as your script was! Tnx!
http://jeroenbourgois.be/blog/2010/03/21/linkedin-using-zend-oauth/
Chris
29|Mar|2010 13Nice Job! I’ll give a look at it.
Luis M
02|Jul|2010 14Awesome job!
Extremely helpful, thanks a lot…
Alex
02|Jul|2010 15Hi Chris,
I’m having trouble with connecting and i think it has something to with that i’m using Zend 1.10.
Could you write a small how-to-connect tutorial so i understand what’s new in Zend 1.10?
Cheers,
Alex
Alex
02|Jul|2010 16Oh i got it :P was a problem with my keys,, worked around it. thanks for the great tutorial anyway.
Christos Constantinou
02|Jul|2010 17To work, change userAuthorisationUrl to userAuthorizationUrl (with a z)
Chris
02|Jul|2010 18Exactly Christos! That’s what I say in the comment above ;)
This spelling change happened when Zend_Oauth was included in 1.10 officially…. So from Zend 1.10 it is userAuthorizationUrl !
Chris
02|Jul|2010 19Thx Alex, Happy you enjoyed.
Diogo
19|Aug|2010 20Using this example, which works fine, how can i do a “offline_access” ?
I tried to store in DB the tokens passed through the URL when the user first accepts the application (oauth_token and oauth_verifier). but when i try to call the
$this->token = $this->consumer->getAccessToken ( $myarray, unserialize ( $_SESSION ['REQUEST_TOKEN'] ) )
it gives me an error like “‘Response from Service Provider is not a valid authorized request token”
Diogo Mendonça
19|Aug|2010 21can someone please help me to get data from user when he’s offline? instead of getting variables through session, they would be stored in a database… as it happens with facebook or twitter
Skzzy
02|Sep|2010 22Hi Chris.
Thank you very much for ScreenCast. It’s very useful.
I have found one issue. This scripts works perfectly in IE and FF browsers but don’t work in Opera. Can you check this from your side?
You wrote: “…But I will plan to demonstrate LinkedIn Search API in the Next Screencast.”. What about next Screencast?
Thanks again.
Chris
02|Sep|2010 23Hey Skzzy,
This should work on any browser. Probably something to do with Session handling by Opera. Did you check your Opera accepts cookies? I’ll for sure give it a try for next tutorial… But as you mentionned I promised a screencast sometime ago and didn’t do anything yet. Time flows. Next tutorial I will continu the Linkedin/Zend serie. Hope you’ll enjoy it.
Chris.
Raquel
17|Nov|2010 24Hi Chris,
Great tutorial I congratulate you.
Thank you very much
Raquel
lucas
28|Nov|2010 25J’ai trouvee ton tutoriel de tres grande qualitee, et celui-ci m’a sauve de longues heures de travail, je te remercie beacoup.
Antoine
Vitaly
08|Jun|2011 26Hey Chris. I have the same question as Diogo: how to store access tokens in DB to be able to use it later?
Stephan Vierkant
09|Jun|2011 27I’ve got the same problem as Julien (12 Feb 2010):
Fatal error: Uncaught exception ‘Zend_Uri_Exception’ with message ‘$uri is not a string’ in /home/(..)/public_html/Zend/Uri/Http.php:174 Stack trace: #0 /home/(..)/public_html/Zend/Oauth/Http/UserAuthorization.php(45): Zend_Uri_Http::fromString(NULL) #1 /home/(..)/public_html/Zend/Oauth/Consumer.php(145): Zend_Oauth_Http_UserAuthorization->getUrl() #2 /home/(..)/public_html/Zend/Oauth/Consumer.php(168): Zend_Oauth_Consumer->getRedirectUrl(NULL, NULL, NULL) #3 /home/(..)/public_html/zend_oauth/LinkedIn.php(65): Zend_Oauth_Consumer->redirect() #4 /home/(..)/public_html/zend_oauth/LinkedIn.php(124): linkedIn->connect() #5 {main} thrown in /home/(..)/public_html/Zend/Uri/Http.php on line 174a
How can I fix this problem?
Sandhya
23|Jun|2011 28Hi Chris,
I am getting this error msg with PHP code…when trying to authenticate login information
Unknown authentication scheme
everything was working well when I used JavaScript. Please help me. Thanks!
siva
20|Jul|2011 29We were unable to find the authorization token in my localsystem. please help me..
sashi
14|Sep|2011 30how can i use this for mobile based application. now i am using android emulator . anyone can explain how it works in these emulatror
Alok
23|Sep|2011 31Hi i am using group API for the most popular discussion and i am using this code in zend
public function mostPopularDisc()
{
$arr = array(
‘accessToken’ => $this->_accessToken,
‘url’ => ‘http://api.linkedin.com/v1/groups/43875/posts:(title,summary,creator:(first-name,last-name,picture-url,headline),likes,attachment:(image-url,content-domain,content-url,title,summary))?category=discussion&order=popularity’,
‘method’ => Zend_Http_Client::GET
);
try {
$xml = $this->_apiCall($arr);
return (array)$xml;
} catch(Exception $e) {
return false;
}
}
this function show following error:
401 1316770542591 MAW7X05OIJ 0 [unauthorized]. OAU:QF4UJke7V164I7BHwNDRnsUxDl6qIA84lmHk_PJU8EjYCtkvAq3RaNn_hK7Afdz5|5695fdf4-f5c4-4a91-8139-282746ba3bac|*01|*01:1316770542:iMtryl44psh5dGxUF04wYvLmYx4=
Please help me……………
Kate
04|Nov|2011 32Hi, I don’t know if anyone is still using this tutorial (they should, it’s awesome) but how do I extract more information from the user’s profile into XML?
Thanks
Leave a reply