Category Archives: Programming

Geek supreme!

The power of streams

A while ago at work, a customer asked that we add an export of a specific table in his database to his website. It wasn’t a difficult export, just get every row in the database and output it in a format MS Excel understands. I was assigned the task, so I went at it.

I started to just get the data out of the database. That meant having something like this:

require 'php/bootstrap.php';
$rResultset = $oDatabase->query("SELECT * FROM mytable");

Simple enough, right? The next thing to do was decide what format the export should be in. All they said was a format MS Excel can understand, so the simples thing I could think of was the CSV format. And since I had recently used fgetcsv to read some stuff from a csv export, I took a wild guess and typed fputcsv in my editor.

So, I had to take the data I already got from the database, create a csv file, and send that to the user with the correct HTTP headers. Easy enough, that means this:

// Put the data in a file
$rHandle = fopen("export.csv", "w+");
while($aResult = $oDatabase->fetch($rResultset)) {
    fputcsv($rHandle, $aResult);
}
 
// Send the headers
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=mytable-export.csv");
header("Pragma: no-cache");
header("Expires: 0");
 
// Read the file, from the beginning
rewind($rHandle);
 while (($sOutput = fgets($rHandle, 4096)) !== false) {
        echo $sOutput;
 }

Okay, so that should work pretty well. Unless two people run the export at the same time. Better make the filename unique. Oh but then I’ll get huge load of files in my tmp directory, better delete the file afterwards.

Luckily, at this point, I hadn’t actually written any code, it was all just pseudo-code in my head. Writing to a file just so I can output it, and then delete that file… that’s stupid. (Not to mention a waist of IO, which is expensive enough as it is without me throwing it out the door like this.)

This meant I had a mission: I wanted to output the data right away, but using fputcsv since I don’t want to bother with all the csv stuff myself.

Enter fopen(“php://output”, “w”); which allows you to write to stdout (read: the webserver, read: the browser) as if it where a file. With that, my script became as simple as this:

// Send the headers
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=mytable-export.csv");
header("Pragma: no-cache");
header("Expires: 0");
 
$rHandle = fopen("php://output", "w");
while($aResult = $oDatabase->fetch($rResultset)) {
    fputcsv($rHandle, $aResult);
}

Rather simple if you ask me. And to think I considered messing with files.

After that, the script needed some tweaking: as first row, they wanted the column names. And “America style” csv (where the separator as a comma) doesn’t work here in Europe, since we use the comma for decimal numbers. Neither of which was a problem:

$bHeadersDone = false;
$rHandle = fopen("php://output", "w");
while($aResult = $oDatabase->fetch($rResultset)) {
     if(!$bHeadersDone) {
          $bHeadersDone = true;
          fputcsv($rHandle, array_keys($aResult), ";");
    }
    fputcsv($rHandle, $aResult);
}

Et voila, it does exactly what the customer wants, its just 29 lines long, and it learned me something new. :)

PHP’s SoapServer and generating WSDL files

Since PHP5, doing stuff with Soap became way easier. SoapServer and SoapClient where added, giving pretty much everybody the ability to create a simple SOAP provider and consumer. But, as always, there is a but. And the ‘but’ in this case, is that if you go to server.php?wsdl, you get an error stating “WSDL generation isn’t supported.” And anybody who has ever written a WSDL by hand knows that it sucks. So, my mission of tonight: to generate a WSDL file from my PHP code.

Obviously, I started with a search for something like “php generate wsdl from code”.  That exact search gives my over 2m results on Google. To bad non of them had the answer for me. Then, I read somebody directing somebody else in the direction of Zend_Soap_AutoDiscover and decided to take a look myself. It seemed to do what I wanted it to, so I figured, why not have a look at it.

After downloading ZendFramework to my laptop and setting up autoloading for it, the first thing I tried was creating a script separate from my server.php called generate.php. In that script, I included my service class, told Zend_Soap_AutoDiscover I wanted to use that and to handle() requests. Browsed to the file, and voila, I had my WSDL file. So, I saved the file. Then, I found out Zend_Soap_AutoDiscover has a dump($filename) method that can do that for me. Instructed SoapServer and SoapClient to use that WSDL, and it worked!

Well, somewhat. Calling $client->__getFunctions() showed me my functions. But if I tried to call one of them, it threw an exception. After some working, I noticed that the targetNamespace was http://localhost/soap/generate.php, which is plain wrong as I’m calling http://localhost/soap/server.php. Ah, that makes sence – Zend_Soap_AutoDiscover couldn’t have known I wanted to use server.php now could it?

So then I thought, why not put the Zend_Soap_AutoDiscover code in my server.php, detect ?wsdl and give the WSDL in those cases. After first having a small codesnippet in server.php that detects ?wsdl and lets Zend_Soap_AutoDiscover do its thing -which worked- I decided the final step was to extend SoapServer so that it would, in fact, support WSDL generation. (Sure, not native, but for native support it’d need to be done in C, which I don’t know anywhere near well enough to make an appempt.)

So I went ahead and wrote my class, WsdlGeneratingSoapServer (describing names for the win). It didn’t need to do much – just overwrite setClass, setObject and addFunction so that it can keep track of what the SoapServer can do (and then passing on the call to parent::, obviously) and overwrite handle, which should detect ?wsdl and, if found, have Zend_Soap_AutoDiscover do the generating, calling parent::handle otherwise.

Sounds easy enough. And it was, I had the class done in about 10 minutes. And then, I tested it. WSDL generation worked perfectly, so goal accomplished! Or well, not really. Normal soapcalls now result in a SoapFault. So I started to try changing things. Long story short, this simple code caused a soapfault. And since thats crazy, copied that script from my laptop (which has PHP Version 5.3.2-1ubuntu4.2 + Suhosin Patch 0.9.9.1) to my VPS (which has PHP Version 5.3.3RC4-dev) and what do you know, it worked.

I didn’t feel like doing any more PHP tonight, so decided to write this blogpost instead. I’ll try the code at work tomorrow, hopefully it’ll work there as well. :)

In the mean time, here is the code. If you change new SoapServer(…); to new WsdlGeneratingSoapServer(…); (and have Zend_Soap_AutoDiscover, which is part of Zend Framework), you’ll have WSDL generating abillities, too!

Life Changes

A bunch of things changed in my life recently. Some big changes, other small. The first of these, is the half year internship at GeoTax I started on september first. At GeoTax, they develop software to help municipalities execute a bunch of Dutch laws. My job there is that of software developer. They use a pretty cool enviroment with a lot of new toys for me to play with. (Or one, Oracle. Another is JBoss Application Server.) I’m really enjoying it there – lots of nice and really smart people, a great project to work on. The money is nice too, and I really don’t mind working from 8.30 to 5. What does suck, is that in order to be there at 8.30 I have to leave my house at 7.15, and I’m normally home around 6.10.

Another thing that changed, is that for a few months now, I’v been doing squash. Its a pretty fun game and I’m really feeling better, healthier then I did back when I didn’t do any sports. (Even though since I started at GeoTax I’ve been less active when you look at the total picture – I go there by train, while I used to go to school on my bike, which is a 45 minute drive.) Its strange how two 45 minute sessions a week (which is my goal) can make you feel like you have way more energy.

Between the internship and squashing, I have way less time then I used to. As a result of that, I’m making much less hours at work these days (not that big an issue, as the internship also pays pretty good), I’ve had to cut back on the TV shows I follow (all good shows got cancelled anyway) and I’m reading far less (as in, from a few chapters a day, to one or two a week). I’m also spending much less time online. I don’t read half the articles I would have read if I had the time, and my activity at Zetaboards Support has dropped to an all time low.

Oh, and I have a girlfriend these days. I try to spend what little free time I have with her.

Tricking browsers that are storing passwords

For a system that I’m working on that I plan to, at some point, release as open source product, I am going to implement a system so that, to get the specific pages, you need to enter your password even if you are logged in. If you do, you will remain “super-authed” untill you close the browser. This would prevent, ie, my little sister to use my laptop, go to my website and have full power because I’m still logged in. But as I was working on it, a question arose: How good is this, taking into account that most people will just end up storing the password in their browser. Obviously, there are ways around that. (Using a random name for the password field each time is probally enough.) But, by doing that, I will be breaking browser functionalities. Do I really want to do that?