PHP Rest Server (part 1 of 3)

I recently had reason to write a REST server in PHP, which was very interesting. There aren’t a whole lot of resources on this topic around so I thought I’d write an outline of what I did. There is quite a lot to it so I’m publishing in multiple sections – this is part 1, which covers the central functionality and handling the incoming request.

Wrapping an Existing Class

The main functionality of the service was written in a class that had no awareness that it was a service – this is a similar approach to the one I described when I wrote about the PHP Soap Server – start with a normal functioning class and write some unit tests for it. The example I’m using today looks like this (my real version actually connects to the database and stuff but this is a nice mock of passing in a number and getting back an array):

class Library {
    public function getUserDetails($user_id) {
        $details = array(
            "user_id" => $user_id,
            "name" => 'Joe Bloggs',
            "email" => '[email protected]');
        return $details;
    }
}

In the soap article, you can see that wrapping a class takes just a few lines – for REST more code is required, but the idea is completely the same. In actual fact we started out with this as a soap service but then it was switched to rest – I only had to re-write the wrapper stuff and not any of the core functionality. Using the wrapper approach would also allow services to be published in multiple ways with the same underlying codebase.

Incoming Requests – Intialising the Wrapper

First of all I wrote a .htaccess file to direct all requests to the one controller file – so that all the different URLs would be handled in the same way.

As the requests came into here, I grabbed the data I needed and initialised the service class, something like this:

$service = new Rest_Service();
// instantiate the main functional class and pass to service
$library = new Library();
$service->setLibrary($library);
// create a response object and pass to service
$response = new Response();
$service->setResponse($response);

// set up some useful variables
$service->url = $_SERVER['REQUEST_URI'];
$service->method = $_SERVER['REQUEST_METHOD'];
$service->getArgs = $_GET;
$service->postArgs = $_POST;
parse_str(file_get_contents('php://input'), $service->putArgs);
parse_str(file_get_contents('php://input'), $service->deleteArgs);

$service->handle();

The variables are all read here and passed in to help decouple the systems – doing it this way allows us to initialise the Service with different incoming variables and/or a different library which can be really useful when testing, as it allows isolation of individual components. The syntax for getting the put and delete data is an interesting one, I wrote about this already in my post on accessing incoming PUT data from PHP, there are some helpful comments on that post as well.

To be continued … later parts will cover the service itself and the response format used.

PHPNW Site and Call for Papers Launched

Yay! The PHPNW site is now online with all the details of the PHP North West Conference to be held on November 22nd, 2008 in Manchester, UK. The conference is specific to PHP and aims to develop the skills of the developers in the local area. Look out for local speakers, some drinking, and generally a good crowd. Put the date in your diary, tickets will go on sale soon.

We’re also launching the call for papers for this event – it runs til 21st September and I’m really hoping we’ll see some good entries covering a wide range of topics. We are including some shorter slots as well as the traditional 1-hour presentations, so hopefully you can think of something you’d like to talk about for one of those units of time.

If you’ve got any comments or questions about the event, the talks, submitting a paper or anything else PHP-north-west-y, then add a comment or drop me a line.

PHPNW 2008 – 22nd November

I’m wildly excited to be able to tell you that the PHP North West Conference now has a date and venue confirmed! The event will be at Manchester Central (apparently this used to be the GMex), on Saturday 22nd November with an early bird ticket price of £50. At the moment we have no website, no confirmed speakers, and no other information to release … but rest assured there are lots of plans being worked on behind the scenes!! The site for the PHPNW user group and conference will be at http://phpnw.org.uk and there is a mailing list you can sign up to already.

The event is aimed at people working with, or wanting to work with, PHP in the north of England. We’ll have a selection of sessions, with the technical content intended to be accessible to a whole range of audiences – it will also be multi-track so there’s sure to be plenty of material to interest you, whatever your background. We will be having a call for papers for the sessions, and we’re hoping that we’ll get some good submissions – particularly from senior developers around the area and the wider UK. Whether you’re hoping to speak, hoping to learn, looking for a good crowd to mingle with on a Saturday, or you just really like PHP geeks – put 22nd November in your diary and I hope I’ll see you there!!

If you have any questions, comments or suggestions about this event, just let me know (I’m not organising the whole thing but I’m helping!), either by leaving a comment or by contacting me directly.

Accessing Incoming PUT Data from PHP

Recently I started writing a REST service. I began in the usual way, writing a php script, calling it with a GET request, accessing the variables using the PHP superglobal variable $_GET. I wrote code to handle a POST request and used the variables I found in $_POST. Then I tried to write a PUT request.

PHP doesn’t have a built-in way to do this, and at first I was a little confused as to how I could reach this information. It turns out that this can be read from the incoming stream to PHP, php://input.

file_get_contents("php://input");

The above line provided me with a query string similar to what you might see on the URL with a GET request. key/value pairs separated by question marks. I was rescued from attempting to parse this monster with a regex by someone pointing out to me that parse_str() is intended for this purpose (seriously, I write a lot of PHP, I don’t know how I miss these things but its always fun when I do “discover” them) – it takes a query string and parses out the variables. Look out for a major health warning on str_parse() – by default it will create all the variables all over your local scope!! Pass in the second parameter though and it will put them in there as an associatvive array instead – I’d strongly recommend this approach and I’ve used it here with my $post_vars variable.

parse_str(file_get_contents("php://input"),$post_vars);

This loads the variable $post_vars with the associative array of variables just like you’d expect to see from a GET request.

Simple Example

Its a bit of a contrived example but it shows use of the REQUEST_METHOD setting from the $_SERVER variable to figure out when we need to grab the post vars. Firstly, here’s the script:

if($_SERVER['REQUEST_METHOD'] == 'GET') {
    echo "this is a get request\n";
    echo $_GET['fruit']." is the fruit\n";
    echo "I want ".$_GET['quantity']." of them\n\n";
} elseif($_SERVER['REQUEST_METHOD'] == 'PUT') {
    echo "this is a put request\n";
    parse_str(file_get_contents("php://input"),$post_vars);
    echo $post_vars['fruit']." is the fruit\n";
    echo "I want ".$post_vars['quantity']." of them\n\n";
}

And here’s what happened when I request the same script using two different HTTP verbs. I’m using cURL to show the example simply because I think it shows it best.

Via GET:

curl "http://localhost/rest_fruit.php?quantity=2&fruit=plum"
this is a get request
plum is the fruit
I want 2 of them

Via PUT:

curl -X PUT http://localhost/rest_fruit.php -d fruit=orange -d quantity=4
this is a put request
orange is the fruit
I want 4 of them

Purists will tell me that I shouldn’t be returning data from a PUT request, and they’d be right! But this does show how to access the incoming variables and detect which verb was being used. If you’re going to write a REST service then the correct naming of resources and the correct response to each resource being accessed in various ways is really important, but its a story I’ll save for another day. If you use this, or perhaps you access the variables another way, then do post a comment – there aren’t a lot of resources available on this topic for PHP.

Ibuildings Seminar, Leeds

My employers, Ibuildings, have been running a series of seminars where we invite a few people (and it is a few, they are generally small events), bring some of our developers along, and have some technical tutorials, demonstrations and general discussions, and some food. The previous events have all been well-received and sound very civilised (and there’s food, which is always good!)

I’m happy to announce that Ibuildings is venturing north of the Watford Gap – and the next event will be in Leeds, on the 9th September, the full details are at http://www.ibuildings.com/events/leeds. The main tutorial session will cover source control with Subversion, including advanced concepts such as merging and repository structures. We’ll also look at deployment strategies for different types of software development processes and tools that can be helpful in this area. I’m delivering the main tutorial at this event, and if that wasn’t enough incentive, I’m also bringing the nabaztag as my glamourous assistant!

We’ll be running events in a lot of other areas of the UK as well, so if you can’t make this one then watch out for more announcements or tell us where we should be running the next one! If you have any queries about any of these events then feel free to contact me, I hope I’ll see some of you in Leeds in September.

DPC Talk Review

A couple of days ago I had the pleasure of speaking at the excellent Dutch PHP Conference in Amsterdam. I haven’t done anything like this before and I did a lot of preparation – as you’ll know if you read this blog regularly.

My talk was entitled “PHP Deployment with Subversion” and was a series of suggested tricks for using Subversion, both tools and structure, to help with deployment. I’m on holiday in Amsterdam for a few days (since I haven’t visited the city before) so I’m currently not able to upload my slides but I will post them here in a day or two. You can get a sneak preview though as there is flickr evidence of my presentation available.

I included a demonstration in my talk which showed a nabaztag (electronic funky rabbit device) notifying of different events, such as tests failing. What I hadn’t really taken into account was that I’d be speaking in such a large room – there was seating for 400 people (about half full I think) and the rabbit is only 8 inches high or so, he was a bit little! I wasn’t following the chatter at the time but I was hugely amused to see this tweet from Breuls when I checked twitter the next day!!

Overall my talk was relatively successful in the sense that I said what I wanted to, I didn’t talk too much or too little, and my nabaztag demo actually worked. I do feel however that my nerves got the better of me – I’m rarely intimidated but having never spoken at a conference before I found it very difficult to adapt to speaking in the main hall. This is the first time I’ve used a microphone, they clipped it onto me and then I started giving the presentation, that was really strange. And also having a large stage with my slides projected on a screen the size of a small house … you can’t look at them, or point at them, or anything. I thought I’d become less nervous with time but I’m afraid it never happened! On a personal level, to give a talk like that, perfectly competently, is an achievement in itself and I’m trying to forget how hard it really was and just feel proud instead :) After the talk I only got one question, which was “Where can I get one of those rabbits?”, so I wasn’t sure if I had put my technical content across well. However quite a few people came to pick my brain afterwards so I guess I did OK.

I owe huge thanks to everyone who provided moral support and tried to convince me I’d be fine, and even more thanks to my boyfriend Kevin who did the setup for the nabaztag (Naz the nabaztag needed his own wireless network) and helped me write the code to run the demo. I’ll write more about the rabbit and the demo at a later point, looks like a lot of people will be getting them :)

Speaking aside, I had a great few days meeting old friends and new ones at the conference, and attending some really interesting sessions. Speaking was very very stressful although perhaps only because I didn’t handle it as well as I might have. The definite upside though is getting to hang out with the very cool kids at the Speakers Dinner afterwards – thanks guys, I had a wonderful night. All in all I can’t wait for next year!

Visit To PHP London

Last night I had the opportunity to speak at the PHP London group, giving a talk entitled “PHP Deployment with Subversion”. This is the talk I will be giving next week at the Dutch PHP Conference in Amsterdam, and giving the same talk last night was the last step in a whole series of preparation for next week. (The slides will be available after the Dutch conference)

As ever it was great to get to the event and meet the people there, I don’t make it to the PHP London meetings very often but I always have a good time when I do. Although this talk was supposed to be a “test drive” for next week, I was actually very squeaky happy to get the invite to speak! Anyway the guys there were great as usual, helping me get set up with the projector, providing a pep talk, and buying me a beer afterwards.

The talk itself went fine, nothing more and nothing less. It was perfect for time, which is excellent as I had absolutely no idea how long I would talk for. I was greatly helped by using Powerpoint (yes, I had to boot into windows, scary!) with its Presenter View which has a timer. This view also shows you your current slide, the notes for this slide, and the upcoming slides which is all good (so long as you can read very tiny writing from standing 4 feet away from your laptop – happily I’m long-sighted!). The content I think is OK – lots of questions came out after the talk which was really interesting, and I certainly realised there were a few points that I need to mention when I give the talk again. The slides perhaps leave something to be desired, colours look different projected and there was a particularly horrible shade of yellow which appears on quite a few slides – oops!

I had a great night and although I wouldn’t say I’m feeling confident for next week, I feel like there are fewer unknowns. I also came to terms with the idea that feeling terrible about a talk is just not something I’m going to get over until I have done the talk – its all part of the preparation I guess.