Get the last effective URL from a series of redirects for the given URL
As some of you may know websites like Facebook or Twitter allow you to fetch user profile images if you know id of the given users. For example, you can fetch the Facebook image for Mark Zuckerberg by going to http://graph.facebook.com/4/picture (4 is Mark's user id), however if you pay attention to the address bar you will notice that the the aforementioned URL actually redirects to http://profile.ak.fbcdn.net/hprofile-ak-snc4/157340_4_3955636_q.jpg.
Same goes for Twitter - I could fetch my user picture by going to http://api.twitter.com/1/users/profile_image/codeaid but it actually redirects to https://si0.twimg.com/profile_images/321201130/twitter_bigger_normal.png.
In one of the projects I've been working on lately, I added a functionality for people to log in using their Facebook, Twitter and other service credentials. I am also storing URLs of their user images in the database for displaying on the comment pages. As you saw earlier it is easy to generate URLs redirecting to the correct destination, however as you can imagine it doesn't make sense to store them as they are as you would have to execute those redirects every time you access the image. Imagine if you have a page with comments and every comment has a picture - it could and would take a long time to resolve and load them all.
That lead me to writing a simple function, which takes the starting URL, follows all the redirects and returns the last effective URL for it. From examples above the last effective URL for http://graph.facebook.com/4/picture would be http://profile.ak.fbcdn.net/hprofile-ak-snc4/157340_4_3955636_q.jpg.
The function looks like this:
- <?php
- /**
- * Get target url from a redirect
- *
- * @param string $url Source url
- * @return string
- */
- function getLastEffectiveUrl($url)
- {
- // initialize cURL
- $curl = curl_init($url);
- curl_setopt_array($curl, array(
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FOLLOWLOCATION => true,
- ));
- // execute the request
- $result = curl_exec($curl);
- // fail if the request was not successful
- if ($result === false) {
- curl_close($curl);
- return null;
- }
- // extract the target url
- $redirectUrl = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
- curl_close($curl);
- return $redirectUrl;
- }
As you can see I am utilizing cURL library for this purpose. First, I am initializing it with the specified starting URL and setting the following two options:
- CURLOPT_RETURNTRANSFER meaning that the output from the call will be returned rather than printed on the screen and...
- CURLOPT_FOLLOWLOCATION, which is a bit more important in this case and as php.net says will "follow any "Location: " header that the server sends as part of the HTTP header" and that is exactly what we need.
You can also set CURLOPT_MAXREDIRS to the number of maximum redirects you want to follow if you wish, however it is usually not needed. You can find more information about the available parameters on the curl_setopt page if you want.
What we do next, is simply fetch the cURL request and return null if it fails. If not, we fetch and return the last effective URL using the curl_getinfo function. Simples :)
The usage is straightforward. If we wanted to fetch the last effective URL for Mark Zuckerberg's profile image we would call the function like this:
- $lastEffectiveUrl = getLastEffectiveUrl('http://graph.facebook.com/4/picture');
The value of $lastEffectiveUrl after the call would be the expected
- 'http://profile.ak.fbcdn.net/hprofile-ak-snc4/157340_4_3955636_q.jpg';
Hope this helps and, as always, please leave your comments if something is still not quite clear.


