Use PHP to generate a file download

July 9th, 2008

Introduction:

At work I have recently been given a few projects that involve writing php web interfaces.  Two weeks ago I probably wouldn’t have had to take off my shoes to count how many lines of php I have written (I dream in Java), so this has given me an opportunity to dust the cobwebs out of my brain and learn a little bit.  The most recent project involved generating a report in a table then having a button to download csv file that had the same data.  Generating the file in php would be no problem but I didn’t want to have a files cluttering up the server for each report.  Instead my goal was to dynamically generate it and send it to the client browser with a download file message.  The example I will walk through involves generating a table and corresponding csv with elevations given longitude and latitude points.

The method:

  • First populate an array with all of the table data.  In my example I take a few inputs from a form then use them to query for data to fill in the form.
  • Print out the array in a table
              echo “<table border=\”1\”>”;
              for($i=0;$i<count($elevationarray);$i++){
                 echo “<tr>”;
                 for($j=0;$j<count($elevationarray);$j++){
                    echo “<td>”;
                    echo $elevationarray[$i][$j];
                    echo “</td>”;
                 }
                 echo “<tr>”;
              }
              echo “</table>”;
  • Serialize and URL encode the table for exporting as a post variable.
              $elevationarray=rawurlencode(serialize($elevationarray));
  • On the page that generates the csv decode and deserialize the array.
              $elevationarray = !isset($_POST['elevationarray'])? “” : $_POST['elevationarray'];
              $elevationarray=unserialize(rawurldecode($elevationarray));
  • Echo out the header information.  This is what lets the browser know that this is a file and not a page for it to render.  This must be the first thing passed to the browser.
              header(”Expires: 0″);
              header(”Cache-control: private”);
              header(”Cache-Control: must-revalidate, post-check=0, pre-check=0″);
              header(”Content-Description: File Transfer”);
              header(”Content-Type: application/vnd.ms-excel”);
              header(”Content-disposition: attachment; filename=elevationreport.csv”);
  • Finally you print out whatever data you want in the csv and you are done!
              for($i=0;$i<count($elevationarray);$i++){
                 for($j=0;$j<count($elevationarray[$i]);$j++){
                    echo $elevationarray[$i][$j];
                    if($j<count($elevationarray)-1)
                      echo “,”;
                  }
                  echo “\n”;
               }
  • One thing to take note of is that if there is empty whitespace before or after the <?php ?> tags in the file or in any of the included php file the browser will try to render them then give you an error because you tried to modify the header information after it had already decided what type of page it was.

Here is a link to the finished page

Download the source code


Switch to Ubuntu on my laptop

July 5th, 2008

I recently purchased a new Thinkpad T-61 laptop and decided to use Ubuntu 8.04 as my primary operating system.  There are many things I love about Linux, especially the glib feeling of superiority I get over those i-can-do-significant-things-with-my-operating-system-without-a-command-line windows and mac users.  I haven’t yet figured out why using the command line is superior, but I trust the scores of newsnet users out there who claim to have written apps with eleventy billion lines of code using vim that it is.  The reason I chose the Ubuntu flavor of Linux is I feel that an operating system should promote ethnic diversity, so if their logo depicts people with different skin pigmentation holding hands, count me in.  I also like that it seems to be the predominant Linux distro these days so hopefully there will be enough how to’s to supplement my areas of ignorance

My current setup includes the following:

  • A 30 gig Windows XP SP3 partition
  • Cygwin installed on the windows partition to add some *nix spice to it
  • A 140 gig Ubuntu 8.04 partition
  • Wine running on Ubuntu for those windows apps that actually work with wine (sometime here shortly I will probably install Starcraft so I can reminisce those heady days when I would pwn n00bs)
  • VMWare Server in Ubuntu which loads my Windows XP partition

My hope is that this setup will allow me to be a Linux user emulating a Windows user and at the same time still virtually be a windows user emulating a linux user, except at those rare occations when I really want to be a windows user emulating a linux user.  I know that wine and cygwin are technically not emulators but I refuse believe it.