Create Bit.ly Short URLs Using PHP: API Version 3

By  on  

Bit.ly is a great URL shortening service. I love their reliability, shortness of the URL, and the information they provide about a given URL. Recently Bit.ly updated their API to version 3 so I thought I'd update my original Bit.ly post. Here's how you can create short URLs and expand short URLs using Bit.ly.

The PHP

/* returns the shortened url */
function get_bitly_short_url($url,$login,$appkey,$format='txt') {
	$connectURL = 'http://api.bit.ly/v3/shorten?login='.$login.'&apiKey='.$appkey.'&uri='.urlencode($url).'&format='.$format;
	return curl_get_result($connectURL);
}

/* returns expanded url */
function get_bitly_long_url($url,$login,$appkey,$format='txt') {
	$connectURL = 'http://api.bit.ly/v3/expand?login='.$login.'&apiKey='.$appkey.'&shortUrl='.urlencode($url).'&format='.$format;
	return curl_get_result($connectURL);
}

/* returns a result form url */
function curl_get_result($url) {
	$ch = curl_init();
	$timeout = 5;
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
	$data = curl_exec($ch);
	curl_close($ch);
	return $data;
}

/* get the short url */
$short_url = get_bitly_short_url('https://davidwalsh.name/','davidwalshblog','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');

/* get the long url from the short one */
$long_url = get_bitly_long_url($short_url,'davidwalshblog','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');

All you really need to is pass your appkey and login (you must sign up for their API service), the long or short URL, and the format which you'd like the result to be returned in. If you just want a simple URL with no other information, use the default "txt" format. Retrieving the XML or JSON formats will provide you more information about the URL.

Bit.ly is awesome. I mean, Twitter uses them -- what more of an endorsement would you need.

Recent Features

  • By
    Welcome to My New Office

    My first professional web development was at a small print shop where I sat in a windowless cubical all day. I suffered that boxed in environment for almost five years before I was able to find a remote job where I worked from home. The first...

  • By
    Facebook Open Graph META Tags

    It's no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook "Like" and "Recommend" widgets on every website.  One...

Incredible Demos

  • By
    9 Mind-Blowing WebGL Demos

    As much as developers now loathe Flash, we're still playing a bit of catch up to natively duplicate the animation capabilities that Adobe's old technology provided us.  Of course we have canvas, an awesome technology, one which I highlighted 9 mind-blowing demos.  Another technology available...

  • By
    CSS Tooltips

    We all know that you can make shapes with CSS and a single HTML element, as I've covered in my CSS Triangles and CSS Circles posts.  Triangles and circles are fairly simply though, so as CSS advances, we need to stretch the boundaries...

Discussion

  1. Thanks for the tip!

    To simplify a little bit your php code, you can use file_get_contents() http://php.net/manual/en/function.file-get-contents.php) instead of curl.

    • Dawson

      This may be true but not all servers allow file_get_contents() to be run, making CURL the real only solution.

    • Bill

      file_get_contents() slows things down.

  2. Why not just use file_get_contents? It’s built in to PHP and doesn’t need cURL to be installed (not all hosts would have cURL). Simply change “return curl_get_result(” to “return file_get_contents(” and remove the whole curl_get_result function :)

  3. @Saad, @Daniel15: When the host has allow_url_fopen disabled, you can’t use file_get_contents on remote files – which is why I guess David has used cURL. Nowadays, pretty much every host has cURL installed as it’s such a commonly used package.

  4. @Saad, @Daniel15, @Michael: cURL is a billiion times faster than file_get_contents.

  5. @Michael: Barely anyone has allow_url_fopen disabled now, since allow_url_include was added in PHP 5.2.0. The main reason for hosts to disable it was that it could include remote files, but now that’s a separate setting, so there’s no reason to disable it.

    @David: Oh, really? I didn’t know that. Do you have benchmarks for it?

  6. @Daniel15: Ah, I’ve not used a shared host since before 5.2 was released, but I know there were a few that had it disabled before then.

    @David: I’d be interested in seeing some benchmarks too if you have them handy :)

  7. @Daniel15, @Michael: You can see benchmarks here:

    http://stackoverflow.com/questions/555523/filegetcontents-vs-curl-what-has-better-performance

    No question that cURL is a faster by a longshot.

  8. I just benchmarked them myself and couldn’t see much of a difference:

    cURL:
    0.23367691040039
    0.22581005096436
    0.21861100196838
    0.2252950668335
    0.21909284591675
    0.24202489852905
    0.23065900802612
    0.21276307106018
    0.22140598297119
    0.21932482719421

    file_get_contents:
    0.22237586975098
    0.21461701393127
    0.22064304351807
    0.22495198249817
    0.21172213554382
    0.22352600097656
    0.21351790428162
    0.22140502929688
    0.21303987503052
    0.2165310382843

    Code I used is here: http://pastebin.ws/awugtf

  9. Whitey

    While cURL may be faster, not every host has cURL installed, and you should never assume the user will have anything but PHP installed with the default settings.

    Following this rule i’d still opt to using file_get_contents() rather than cURL, just for the compatability.

    But nonetheless, good post. :)

  10. Hi David,

    A few months ago i posted on my Snipplr account how to do the same with Mootools:

    http://snipplr.com/view/29387/connect-to-bitly-api–with-mootools/

    Cheers,
    Stephane.

  11. I love how everyone is fighting and taking the time to benchmark fucking php functions, but no one has released a dual optioned script.. :/

    Some host’s disable both for security reasons.. If you ask me, PHP isn’t exactly the best way to do the script in the first place.

  12. Why would PHP not be the best way to do something like this? What would you do instead?

    And here’s a dual-optioned script… Uses cURL if available, otherwise file_get_contents:

    function get_url($url)
    {
    	if (!function_exists('curl_init'))
    	{
    		return file_get_contents($url);
    	}
    	
    	$ch = curl_init();
    	$timeout = 5;
    	curl_setopt($ch,CURLOPT_URL,$url);
    	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
    	$data = curl_exec($ch);
    	curl_close($ch);
    	return $data;	
    }
    
  13. The <code> tag broke my indentation though. :(

  14. I gave your code a nice OO suite.

    class Bitly {
    	
    	private $login;
    	private $appkey;
    	
    	function __construct($login, $appkey) {
    		$this->login = $login;
    		$this->appkey = $appkey;
    	}
    
    	function shorten($url) {
    		return $this->curl_get_result("http://api.bit.ly/v3/shorten?login={$this->login}&apiKey={$this->appkey}&uri=".urlencode($url)."&format=txt");
    	}
    	
    	function expand($url) {
    		return $this->curl_get_result("http://api.bit.ly/v3/expand?login={$this->login}&apiKey={$this->appkey}&shortUrl=".urlencode($url)."&format=txt");
    	}
    	
    	private function curl_get_result($url) {
    		$ch = curl_init();
    		$timeout = 5;
    		curl_setopt($ch,CURLOPT_URL,$url);
    		curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    		curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
    		$data = curl_exec($ch);
    		curl_close($ch);
    		return $data;
    	}
    
    }
    
    $bitly = new Bitly("login", "apiKey");
    
    $url = $bitly->shorten("url");
    

    Hope you like it.

  15. thanks for posting this — i’m trying to use the bit.ly api to shorten urls before posting on twitter through their api. i was looking at the documentation at http://code.google.com/p/bitly-api/wiki/ApiDocumentation#/v3/shorten and it said to use longUrl, x_login, and x_apiKey instead of uri, login, and apiKey. when i changed to the parameters you use here it started working. now i just have to hook in to the parts of my site that should update twitter and i’ll have finished my first project of integrating with another site!

  16. If you don’t have cURL installed, install it. If you don’t have access to install cURL and its not already there, find a better host. file_get_contents() is slow and if you actually get a moderate amount of traffic volume, don’t use file_get_contents. Programmers, don’t be lazy, use cURL. David, nice post.

  17. WilleNewMedia

    Awesome, thank you so much, David!

  18. This bit.ly script is a joy to use. Thanks so much for posting! :D

  19. This bitly script was a joy to use. Thanks so much for posting! :)

  20. FrankF

    Question. I have a large homepage with 12 news items and I want a fast bit.ly link with every news item. But after one link I receive the erorr:
    Fatal error: Cannot redeclare get_bitly_short_url() (previously declared(…)

    What can i do?

  21. Hi, Thanks for this code. Just to add some. you can use wp_remote_fopen if you are running a WP blog. It will try with fopen first to retrieve the remote url and if it is not present it will switch over to curl.

  22. Koen Heltzel

    If you get the MISSING_ARG_APIKEY error using the above script, you have probably used the “copy” button to copy it to your clipboard, which adds html entity encoding. Replace & with & in the url’s and the error should go away.

  23. Koen Heltzel

    Of course I meant to say: replace “& amp ;” with “&”

  24. My code: http://pastebin.com/CYzuThRV

    The result in browser is: bool(false)

    what’s wrong?

  25. I’m getting an ugly line return after outputting the function. Can’t work out what’s causing it? Any hints? :)

  26. Ok, so I’ve worked out where it’s come from. The file that bit.ly outputs has the data on the first line, but then also outputs a blank second line.

    Any ideas how to remove it?

  27. Solved the problem. I ended up calling it as XML rather than TXT.

    $bitly = get_bitly_short_url('YOUR URI',$username,$api_key,'xml');
    $xml = simplexml_load_file($bitly);
    $short_url = $xml->data->url;
    

    Then for that to work I made a tiny edit in the function so we don’t need CURL.

    function get_bitly_short_url($url,$login,$appkey,$format='txt') {
            $connectURL = 'http://api.bit.ly/v3/shorten?login='.$login.'&apiKey='.$appkey.'&uri='.urlencode($url).'&format='.$format;
            if ($format == 'xml')
                    return $connectURL;
            return curl_get_result($connectURL);
    }
    

    Might help someone out there!

  28. hayate-kun

    Thank you so much! it such big help and very direct for a noob like me! :)

  29. Web

    Thank you!!

  30. In case this helps someone else out – I kept confusing my generic oauth token (link on the main API docs page) for the API_KEY

    You can easily find your API Key here:

    https://bitly.com/a/your_api_key

  31. hey … look this project for make an API .. is cool, http://codecanyon.net/item/our-api-server/5679947

  32. Kelly

    Thanks for the example…it helped alot! It is generating the bitly, but it is wrapped with a
    string(22) “http://bit.ly/1xL48Nx”. Kind of a newbie…how do I get rid of the string(22)””? Any help would be great…thanks.

  33. dikau

    @kelly:

    return trim(curl_get_result($connectURL));

  34. bond

    @dikau Why do you need the trim function? or I mean why is there a line break after the URL? does anyone know?

  35. Adriano

    You Rock , Man

    It worked on the 1st time.

    One question : Is there a limitation in the number of bitly one can generate per day ??
    What if I have multiple users using my code ??( what will create a big number of short links )

  36. Fatal error: Cannot redeclare make_bitly_url() (previously declared in C:\code directory:3) in C:\code directory on line 23

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!