Click the box titles below to expand:

How to's

XSLT

GOOGLE MAPS API

PHP

Perl

Document Object Model (DOM)

UNIX

Generic Mapping Tools (GMT)

Miscellaneous

Projects

Courses Taught

Latest Favorites

Mac OS X

Web Development

Beta

How To :: PHP and Flickr – accessing online photos through the phpFlickr class

1. What is Flickr?

If you haven't heard about Flickr, here is the blurb from their 'about us' page:

What is Flickr?

Flickr is almost certainly the best online photo management and sharing application in the world. Let us show you why!

Flickr is a way to get your photos to the people who matter to you. With Flickr you can:

  • Show off your favorite photos to the world
  • Blog the photos you take with a cameraphone
  • Securely and privately show photos to your friends and family around the world
  • ... and much, much more!

Basically, Flickr is what butters the borders between your photos to the people you want to see them. And basic accounts are free!

For me, Flickr is a great way to easily store lots of photos. And I mean LOTS. We use it for the ANF project, and have over 4,000 high resolution photos (1024x768 minimum). What I think is the most cool thing about Flickr is that it does not limit you with disk space (ie. storage of your photos) but for upstream data flow (ie. uploading photos to their servers). With a Pro account you have 2GB per month(!) of upstream data flow. To me, this is incredible.

Anyway, enough of why I use it, I am sure if you are reading this then you already use it. Onto the meat of the how-to...

2. PHP saves the day

So here is the scenario. You have thousands of cool photos in your Flickr account. You reallylike the Flickr interface, but you really want to have them displayed on your own website. You don't like the fact that the only way you can get people to see you photos is by viewing the photo yourself, viewing the different sizes, then copying and pasting the HTML code of the URL into your home website. If you are like me and like to play with PHP, then there is a saviour here to help. His name is Dan Coulter and his website is http://www.phpflickr.com. What he has done is build the Flickr API (which is open source) into a PHP(4) class. To me, this is an incredible achievement and my hat goes off to him. He has several examples to get you going, but to really explore the guts of the class requires diving in head–first. Hence this tutorial, to hopefully save you all some time...

So, first up, download the phpFlickr class from SourceForge. Then copy this to you own website directory. I recommend putting the directory in the configuration area of your website, away from the publicly accessible directories.

Then in the webpage that you wish to display the photos from your Flickr photostream:

  1. <?php
  2. require_once( 'phpFlickr/phpFlickr.php' ) ;
  3. $f = new phpFlickr( $phpFlickr_api_key, $phpFlickr_secret ) ;
  4. $f->setToken( $phpFlickr_token ) ;
  5. $f->enableCache( $phpFlickr_cache[0], $phpFlickr_cache[1], $phpFlickr_cache[2] ) ;
  6. ?>

3. Putting it all together

So now I have my connection to Flickr running, how do I go about retrieving my photos? Here are a couple of case studies.

3a. Get the representative photo

For each of our installed stations we have a representative photo with a unique tag. Typically this is a photo of the station from 20 feet away with a nice background. Also it is important that no information such as serial numbers or personal information is in the photograph.

We have connected to Flickr (see above) so now we need to access our photosets...

  1. <?php
  2. $flickr_i = 0 ;
  3. $flickr_sta = $snet . "_" . $sta ;
  4.  
  5. $nsid = $f->people_findByUsername( 'username' ) ;
  6. $list = $f->photosets_getList( $nsid ) ;
  7.  
  8. foreach( $list['photoset'] as $photoset ) {
  9. if( eregi( $flickr_sta, $photoset['title'] ) ) {
  10. $photos[$flickr_i] = $f->photosets_getPhotos( $list['photoset'][$flickr_i]['id'], NULL, NULL ) ;
  11. }
  12. $flickr_i++ ;
  13. }
  14. // Get array keys
  15. $photoset_keys = array_keys( $photos ) ;
  16.  
  17. // Get the friendly URL of the user's photos
  18. $photos_url = $f->urls_getUserPhotos( $nsid ) ;
  19. ?>

Discussion: We first access our photos by selecting a username to grab (replace 'username' with your Flickr/Yahoo! account username by using the $f->people_findByUsername() method. Then we need to get a list of the photosets, using the $f->photosets_getList() method.

I only want photosets that match my station name, so to ensure I only get those I do a regular expression (case insensitive) search (eregi) through the photoset titles. I then get the photos for the set(s) using the $f->photosets_getPhotos() method.

So we now have the photosets that match my station name in an associative array. I grab the array keys for the array $photos and also the URLs for all the photos in my photostream using $f->urls_getUserPhotos() .

To get the representative photo (with the tag top_pick) I need to traverse the $photos associative array and grab the id of the photo that has the unique tag:

  1. <?php
  2. foreach( $photoset_keys as $keys ) {
  3. foreach( $photos[$keys]['photo'] as $photo ) {
  4. $photo_info = $f->photos_getInfo( $photo['id'] ) ;
  5. if( array_search_recursive( "top_pick", $photo_info ) ) {
  6. echo "<a href=" . $photos_url . $photo['id'] . ">" ;
  7. echo "<img style=\"border: 1px solid black;\" alt=\"" . $photo['title'] . "\" src=\"" . $f->buildPhotoURL($photo, "Medium") . "\">" ;
  8. echo "</a>" ;
  9. $its_there = 1 ;
  10. }
  11. }
  12. }
  13. if( $its_there != 1 ) {
  14. echo "<p>No representative photograph yet.</p>" ;
  15. }
  16. ?>

We first only go through the array keys that matched the initial station name query. Then within that we go through all the photos in each set, grabbing the tag information using $f->photosets_getInfo() method.

Then we have a custom function that recursively searches the array for the value top_pick. If that tag value is found we grab that photos URL with the $f->buildPhotoURL() method and display it on the screen. Finally, if there is a tag found with the unique value we set $its_there equal to one. Exiting the loops we do a check to see if $its_there is not equal to one, and if so we display some text showing that we don't have a representative photo yet.

For completeness, here is the array_search_recursive() function, written by Mark Meves (manicdepressive[at]mindless[dot]com). It was lifted from the PHP.net array_search page.

  1. <?php
  2. function array_search_recursive( $needle, $haystack ) {
  3. $path = NULL;
  4. $keys = array_keys($haystack);
  5. while (!$path && (list($toss,$k)=each($keys))) {
  6. $v = $haystack[$k];
  7. if (is_scalar($v)) {
  8. if ($v===$needle) {
  9. $path = array($k);
  10. }
  11. } elseif (is_array($v)) {
  12. if ($path=array_search_recursive( $needle, $v )) {
  13. array_unshift($path,$k);
  14. }
  15. }
  16. }
  17. return $path;
  18. }
  19. ?>

It occurred to me that this is a very inefficient way of grabbing one photo per station. To get all the photos from all the sets and then traverse the associative arrays to get the one photo/tag combination I need is very poor coding.

Within the Flickr interface, the fastest way to retrieve relevant photos is by using the search feature to search only your photos. Dan implemented this nicely in phpFlickr, allowing you specify the search criteria in an associative array. A cursory glance at the Flickr API for this function shows that you can add the key=>value pair "user_id"=>"me" to just search your own photos.

So, we search only my photos that have the tags "top_pick" and the station code, and define tag_mode as "all". The values for the latter are "any" or "all". "All" will only return those photos that match all the tags.

Very neat....

  1. <?php
  2. $sta = "station_code" ;
  3. $nsid = $f->people_findByUsername( 'username' ) ;
  4. $flickr_top_pick = $f->photos_search( array( "user_id"=>"me", "tags"=>"top_pick, $sta", "tag_mode"=>"all" ) ) ;
  5. ?>

And to output the result, we just rip out the first foreach() loop...

  1. <?php
  2. foreach( $flickr_top_pick['photo'] as $photo ) {
  3. $photo_info = $f->photos_getInfo( $photo['id'] ) ;
  4. echo "<a href=" . $photos_url . $photo['id'] . ">" ;
  5. echo "<img style=\"border: 1px solid black;\" alt=\"" . $photo['title'] . "\" src=\"" . $f->buildPhotoURL($photo, "Medium") . "\">" ;
  6. echo "</a>" ;
  7. $its_there = 1 ;
  8. }
  9. if( $its_there != 1 ) {
  10. echo "<p>No representative photograph yet.</p>" ;
  11. }
  12. ?>

3b. Get photo by tag name

To be updated

4. Examples of how I am using it...

To be updated

Gotcha's to be aware of

Permissions on the photos in the getPhotoset query

To be updated

Disclaimer

This information is freely provided as–is. Messing around with the command line and creating files is a serious business, and I accept no liability for errors created, systems corrupted, or hard–disk damage by you following these instructions. They worked for me but may not work for you. Remember to back–up EVERYTHING before you try any of this stuff — it is not simple OR easy!!!

If you have any questions about this please email me at rlnewman@ucsd.edu and I will try my best to help you out.

made with CSS     Valid XHTML 1.0!      Valid CSS!