yes i love technology

PHP: File Downloads HTTP Headers

May 16th, 2007 by Pete

In PHP you can provide file downloads by using a PHP page to “pass through” the file. Of course you could just link to the actual file, however this technique means your file can kept outside of your website root. Another advantage is you can integrate this system into a PHP based user/password system easily.

Now this technique is fairly straightforward, but you need to make sure you get the HTTP Headers correct for it to run smoothly. Here’s the code:

PHP:
  1. $file = "/path/to/file.txt";
  2. $file_extension = strtolower(substr(strrchr($basename,"."),1));
  3.  
  4. //This will set the Content-Type to the appropriate setting for the file
  5. switch ($file_extension)
  6. {
  7. case "htm":
  8. case "xhtml";
  9. case "txt";
  10. case "html": $ctype="text/html"; break;
  11. case "pdf": $ctype="application/pdf"; break;
  12. case "doc": $ctype="application/msword"; break;
  13. case "exe": $ctype="application/octet-stream"; break;
  14. case "zip": $ctype="application/zip"; break;
  15. case "xls": $ctype="application/vnd.ms-excel"; break;
  16. case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
  17. case "gif": $ctype="image/gif"; break;
  18. case "png": $ctype="image/png"; break;
  19. case "jpeg":
  20. case "jpg": $ctype="image/jpeg"; break;
  21. case "mp3": $ctype="audio/mpeg"; break;
  22. case "wav": $ctype="audio/x-wav"; break;
  23. case "mpeg":
  24. case "mpg":
  25. case "mpe": $ctype="video/mpeg"; break;
  26. case "mov": $ctype="video/quicktime"; break;
  27. case "avi": $ctype="video/x-msvideo"; break;
  28. default: $ctype="application/force-download";
  29. }
  30.  
  31. //Begin writing headers
  32. header("Pragma: public");
  33. header("Expires: 0");
  34. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  35. header("Cache-Control: public");
  36. header("Content-Description: File Transfer");
  37. //Use the switch-generated Content-Type
  38. header("Content-Type: $ctype");
  39. header("Content-Length: ".filesize($file));
  40.  
  41. // regex stops download prompt for browser associated types
  42. if (!preg_match('/(htm|xhtml|txt|html|gif|png|jpeg|jpg)/', $file_extension, $matches))
  43. header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
  44.  
  45. // output the file
  46. readfile("$file");
  47. exit();

I will be writing a follow up article in the future that shows how this technique can be improvement using Apache's mod-rewrite to provide cleaner URLs for file downloads.

Note: The regular expression on line 42 will make files normally associated with the browser (images, webpages, etc) open inside the browser. If you want to get the “open/save” download prompt for all types of files then comment out this line.

Note: Make sure you use: “Content-Type: image/jpeg” for JPGs, IE doesn’t seems to like “Content-Type: image/jpg”

# Pete Graham

Posted in Website Development, php, regular expressions, programming | 2 Comments »

Away with Applications: The Death of Desktop

May 15th, 2007 by Pete

There is a great talk that went up on Google Videos earlier this month called Away with Applications: The Death of Deskop. In it the speaker, Aza Raskin points out that no work is carried out actually using the computers desktop. He also points out the failing of desktop applications, that you frequently need to switch between applications, moving content, to achieve even relatively simple tasks.

I think his points are particularly relevant as we move into an age where many traditional desktop apps are being converted to web applications. I see an increasing trend in web applications of people trying to recreate desktop applications like interfaces in a browser-based setting. Aza urges us to rethink what we know about computer interfaces and to come up with exciting and innovative alternatives.

Traditional applications have had more and more functionality added to them to an extent that they have become “a portmanteau of all possible features”, again it is worrying that many of today’s successful web apps could suffer the same fate. The speaker encourages open APIs and Mash-ups as an alternative and a may to combine applications without having to switch between multiple programs/services.

One of the most interesting parts of the talk for me is when the speaker demos some systems that he's been developing himself, one is a command-line interface for launching applications that uses almost real language commands and auto-complete. The other is an interesting zoomable desktop, which is much more work orientated than the traditional model, it also centres around the concept of “content as content”.

At nearly an hour and a half the video is quite long but I found it extremely interesting, the speaker also looks a bit like Rick Moranis of “Honey I shrunk the kids” fame, which has got to be a good thing.

# Pete Graham

Posted in Tech, usability, videos | No Comments »

PHP: Get First Index in Associative Array

May 15th, 2007 by Pete

The other day I was programming in PHP and needed to get the first index in an associative array. There doesn’t appear to be a built in function to deal with this so I wrote my own.

PHP:
  1. function getArrayFirstIndex($arr)
  2. {
  3. foreach ($arr as $key => $value)
  4. return $key;
  5. }

Here's a bit of code you can test it on:

PHP:
  1. $arr['banana'] = "yellow";
  2. $arr['apple'] = "apple";
  3. $arr['orange'] = "orange";
  4.  
  5. $first_index = getArrayFirstIndex($arr);
  6.  
  7. echo "first index =".$first_index;

The above code will output 'first index = banana'.

/* Pete Graham */

Posted in Website Development, php, programming | 4 Comments »

JS: Execute JavaScript on Page Load

May 14th, 2007 by Pete

Recently I’ve been making an effort to improve my JavaScript skills, I’m not a JavaScript-Jedi yet but I have been picking up a few, tips, tricks and techniques.

One thing that I find extremely useful is using an init function to call other functions when the page has loaded. I have been using the nifty function below:

JAVASCRIPT:
  1. function WindowOnload(f)
  2. {
  3. var prev=window.onload;
  4. window.onload=function(){ if(prev)prev(); f(); }
  5. }

I save this function in a file called init.js which is then included in my HTML pages using:

HTML:
  1. <script xsrc="/js/init.js" type="text/javascript"></script>

Functions can then be initialised by including the following in the HTML:

JAVASCRIPT:
  1. <script language="JavaScript">
  2. <!--
  3.  
  4. WindowOnload(function()
  5. {
  6. a_function('Sdelete_date');
  7. });
  8.  
  9. WindowOnload(function()
  10. {
  11. another_function('a_parameter');
  12. });
  13.  
  14. //-->
  15. </script>

The above code is inline JavaScript which is often seen as being naughty, obviously you can save the same code to a separate file and include that instead.

I originally saw this technique here. Alternative JS initialisation scripts are available but so far this one has worked well for me, so I’ll be sticking with it.

# Pete Graham

Posted in javascript, Website Development, programming | No Comments »

Vim: Search and Replace, Insert new line

May 3rd, 2007 by Pete

Vim has some really useful commands, especially search and replace ones. Unfortunately I'm always forgetting the finer details of how to use them so here's an example:

CODE:
  1. :%s/$/\rthis is a new line

To break down whats happening above:

  • : switches Vim into command mode
  • % means we're going to apply this command to every line in our file
  • s means we're using the substitute command. The format of the command is s/search/replacement, 'search' can be a regular expression
  • $ tells vim to search for the end of the line
  • \rthis is a new line tells vim to replace with a new line character, and to put the text "this is a new line" on that line.

NOTE: \r is used as the new line character when vim is using DOS file format, to find out which file format you are using type :set ff? You can find out more about Vim file formats here.

#Pete Graham

Posted in regex, regular expressions, vim | 9 Comments »