PHPNW: Schedule and Crowd-Sourcing

Plans for the second annual PHP North West conference (Manchester, 10th October) are coming along rather nicely, so I thought I’d share an update and some headline news. First of all – tickets cost 50 GBP + VAT. This is about 57 euros or 81 dollars. I don’t know where else you can buy conference attendance for that kind of money, we even have concessionary prices for students, OAPs, anyone else who can persuade us they deserve it. So – buy your tickets and come join in the fun!

Since I last posted here we also published the schedule. We were overwhelmed by the quality of the call for papers and there are some cracking sessions, excellent speakers, and lots of overlap between the two! Already grumbling can be heard about good sessions which clash with one another … which is rather a wonderful problem to have :)

Finally, this year PHPNW is expanding and has added an informal schedule on the Sunday morning since we know lots of people will be staying over. This will run from 9 til 1 and we’ve put out a call to ask what people would like to see on the schedule. So far a few regulars have already made themselves heard and we’re looking forward to seeing the outcome of crowd-sourcing a schedule in this way! The Sunday event is at Museum of Science and Industry, which a fun place to go for geeks and, like the morning event, is free entry!

Hoping to see lots of you there at the conference this year – last year’s event was brilliant with an excellent atmosphere, and this year looks to be better again. I can’t wait :)

PHPWomen Merchandise

A few weeks ago, phpwomen.org put out an announcement about merchandise. When we first started the group (almost 3 years ago, believe it or not) we printed t-shirts and gave them out at conferences. Once the various founder members and a few benefactors had paid for a set of t-shirts each it became clear that this wasn’t a sustainable venture. So, after much happening in the background getting set up as a non-profit and getting a bank account (thanks mostly to lig!) and a bunch of time spent sorting out two spreadshirt shops (thanks Elizabeth!), it is now possible to buy merchandise online in both North America and Europe! The big problem with cafepress is the shipping costs for everyone outside of North America so spreadshirt seemed like a better option … still not ideal for our members further afield however and perhaps we can work out some better alternatives over time.

So, with great excitement I ordered my new phpwomen shirt (in girl fit!) – and here it is:

New PHPWomen Shirt

Note: This is the large size … I’m not small but I’m not really that large either so order a bigger size if you are ordering the girl fit shirts.

So, what are you waiting for? Head over to the announcement post and follow the links to order your shirt and support the organisation – just in time for the autumn conference season!

Adding PUT variables to Request Object in Zend Framework

When I wrote recently about testing web services within Zend Framework, I missed out a really key piece of information! I didn’t explain how I was reading the PUT vars in my controller code in the first place – so I’ll rectify that omission now.

Its very simple: I have extended Zend_Controller_Action with my own, and all controllers inherit from here. This has a routeAction() which grabs the incoming variables from a PUT request and sets them as parameters within the usual $this->getRequest() scope, then forwards on the request. Here is my class:

class My_Controller_Action extends Zend_Controller_Action
{
    public function routeAction()    
    {
        // handle grabbing PUT vars
        if($this->getRequest()->isPut()) {
            parse_str($this->getRequest()->getRawBody(), $params);
            foreach($params as $key => $value) {
                $this->getRequest()->setParam($key, $value);
            }
        }
        $this->_forward(strtolower($this->getRequest()->getMethod()));
    }
}

So in my controller code, I simply call out to $this->getRequest()->getParam(‘name’) or whatever, and in my tests I can set those parameters as I showed in my other article.

I hope this makes sense, its one of those things I set up once and use a lot (and now I’ll be able to refer to how I did it!), if you have any queries, comments, improvements or if this helps you then please leave a comment – I haven’t come across anyone else doing anything similar but I know there must be, so let me know!

Using Zend_Test for Web Services

Recently I had cause to develop a web service and so I wrote some tests to go along with it – or I was about to. When I looked at the asserts available in Zend_Test, they were all geared towards HTML/CSS output – but we can test just as effectively on another output.

Using Zend_Test, I set up the request object I wanted to send, and dispatched it. Then I retrieved the body and, since this service returns JSON, I json_decoded it. This gives me an object – and I can go ahead and use all the functionality of PHPUnit, with or without Zend_Test’s additions, to test my service. Its perhaps easiest to show this in a few steps.

Setting up the request object

The idea here is that you set up any parameters you need to including the HTTP verb to use and cookies if needed, then despatch the request. Here’s a few examples, first a simple GET method, with a cookie.

        $request = $this->getRequest();
        $request->setMethod('GET');
        $request->setCookie('token','xxxx');
        $this->dispatch('/user/24');

Including data with a POST request:

        $request = $this->getRequest();
        $request->setMethod('POST');
        $request->setPost(array(
            'name' => 'new user',
            'organisation' => 49
            ));
        $this->dispatch('/user');

This is a REST service, so I also tested PUT and DELETE methods. DELETE just needs the setMethod() call since it doesn’t have any data with it, but PUT was a bit trickier – here’s an example of what I used:

        $request = $this->getRequest();
        $request->setMethod('PUT');
        $params = array('name' => 'Harry Potter');
        $request->setRawBody(http_build_query($params));
        $this->dispatch('/user/48');

Decoding the Response

This is the easy part, all I do is check the status code is what was expected, and then decode the response. My web service returns JSON so this part of each test looks something like:

        $this->assertResponseCode('200');

        $response = json_decode($this->getResponse()->getBody());

Testing the content of the response

Here we get into classic PHPUnit territory and simply use the assertTrue and assertEquals calls we’d use when testing anything else, an example is included for completeness:

        $this->assertEquals($response->contentType, 'user');
        $this->assertTrue(is_numeric($response->id));
        $this->assertEquals($response->name, 'new user');
        $this->assertEquals($response->organisation, 49);

In Conclusion

By combining the request/response awareness of Zend_Test with standard PHPUnit testing strategies, its easy to test web services as well as web pages. I hope the examples are helpful – if they help you or if you have anything to add, then leave a comment!

5 Ways to Make Friends at a Technical Conference

These are my top tips for getting along and meeting new people at a technical conference.

Take an extension cable

Conferences are notorious for having too few and too short power leads, and everyone needs to recharge laptops, especially in hands-on sessions like tutorial day. Having an extension cable will make you instant friends as you bring power to more people.

Join in the pre-conference hype

Follow the nominated twitter tag and log into the IRC channel if there is one. Find out who is staying in the same place as you or arriving at the same time, arrange to travel together or meet for a pre-conference drink to break the ice.

Attend the extra-curricular events

Don’t think for a moment that when the official schedule ends, you are off-duty for the night! Find out about any social activities going on – and if there is an informal track such as an unconference, make sure you attend, or even participate. This is a great opportunity to meet more people and see more talks in a much less structured environment.

Take business cards

Or if you don’t have that kind of job (or even if you do!) get some moo cards to take with you so you can pass on your blog/email address, name and twitter details to people you want to stay in touch with after the event.

Stay an extra day

The party starts when the conference ends, so hang around for 24 hours or so and join in :) Especially for the speakers (whose rooms are paid for) and those travelling internationally, there’s no need to rush off straight away. Some of the best times I’ve had at conferences have been after the main event.

Keep in touch

Write up your experiences on your blog (do you have a blog? If not, this is a great place to start) and tag it appropriately. Comment on other people’s and stay in touch with the new friends that you made at the conference.

OK, so technically this is six ways to make friends, but I won’t apologise for that :) What’s your top tip for conference attendees?

PHPUnit with Zend_Controller_Action_Helper

I’m currently working on a REST service built in Zend Framework and I ran into problems very quickly – when I tried to write the first unit test for the first action in fact! PHPUnit was just dying when I asked it to dispatch() any URL which didn’t return HTML, it wasn’t even giving its usual output.

What was actually happening was I was making use of Zend_Controller_Action_Helper_Json, my service returns JSON and this action helper takes input, transforms it into JSON, sets the content-type correctly and tells ZF not to look for a view since we don’t need one. I thought this was pretty neat.

But look at the start of the declaration for the action helper:

class Zend_Controller_Action_Helper_Json extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * Suppress exit when sendJson() called
     * @var boolean
     */
    public $suppressExit = false;
...

By default the JSON action helper will exit() – which of course when run from phpunit causes that to exit as well! There is the class variable there so it was simple to turn off – I just extended my class and changed the value of that $suppressExit variable.

class Zend_Controller_Action_Helper_ServiceJson extends Zend_Controller_Action_Helper_Json {
    public $suppressExit = true;
}

My tests now run successfully and I can build my application, hopefully next time I’ll realise what I’m doing wrong faster!

PUTting data fields with PHP cURL

This is a little post about how to PUT multiple data fields using the PHP cURL extension. Why I wanted to do this in the first place is beyond the scope of this post, since its quite a long story. The curl command line allows data fields to be sent with a PUT request, and I wanted to do the same from PHP. Here is a snippet of code to show how I did it.

        $data = array("a" => $a);
        $ch = curl_init($this->_serviceUrl . $id);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));

        $response = curl_exec($ch);
        if(!$response) {
            return false;
        }

I’m putting this here so I remember for next time – if it helps you as well then even better :)

PHPNW: Site, Tickets and CfP

The date for PHPNW was announced a few weeks ago as Saturday 10th October 2009, and now we’ve got all the official bits and bobs to go with it! In outline:

The website: http://conference.phpnw.org.uk

Tickets: http://conference.phpnw.org.uk/register. Early bird pricing until September 11th, student tickets available – look on the website for instructions on getting student tickets.

Call for Papers: http://conference.phpnw.org.uk/callforpapers. Speakers wanted! If you have something to share and you think you can do that coherently – then submit to us please, we’re always looking for new people, new talks, as well as the talks and speakers you’d expect to see at the bigger PHP conferences. If you’re not sure if something fits, feel free to contact us.

This is officially a one-day Saturday event, with a full day with two tracks of talks and an attendance of 200+ people. In reality its a whole weekend of geeking out in Manchester – with a pre-conference social on Friday night, the main event on Saturday, a conference social running on Saturday night and an informal set of sessions on Sunday morning for anyone with the energy to keep on going before everyone makes tracks to their homes.

If you’re going, thinking of going, went last year, or wishing you could be there – add a comment! I’m looking forward to meeting many of you at the event :)

Status Codes for Web Services

This the last entry in a mini series on points to consider when designing and building web services. So far there have been posts on error feedback for web services, auth mechanisms for web services, saving state in web services and using version parameters with web services.

Unlike the other posts in this series, this one is quite specific to one type of service – REST – since it deals with status codes, specifically HTTP ones. The ideas are transferrable however and other types of service can return statuses in a similar way.

There’s a few key things to think about when returning status codes. In earlier posts in this series these was discussion of using existing application framework to serve pages and changing the output mechanism accordingly. Usually a web page will return a status 200 for OK or also 302 for found, so this is fine when things are working normally. But when things aren’t going quite so well, its useful to give alternative feedback that can be easily picked up by a client application.

When things go wrong there are a couple of different schools of thought of how the service should respond. One is that if, for example, the user supplies data which fails validation, the service could provide the OK response and a message to the user to let them know what needs validating – exactly as we’d return information messages to a user filling in a form. To be considered restful however, the service should more correctly return one of the “400” status codes, which means that the client made an error. Interesting and useful codes* in this series are:

  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 405 Method Not Allowed
  • 406 Not Acceptable
  • 408 Request Timeout
  • 417 Expectation Failed
  • 418 I’m a teapot

* I didn’t say they were both useful and interesting

Using descriptive status codes allows the client to get the headline of the problem without having to parse a whole request to find out whether it is good or not. HTTP already has this feature built-in, and so we make use of it (HTTP is pretty cool really, makes a great protocol for services!).

Where an error occurs on the server side – it is usual to return a 500 error or another in the 500 series. This lets the client know there is a problem outside of their control; it is useful to include information about whether the client should retry and when. Having a defined protocol for retries helps avoid the situation where a system comes back up only to fall over again with all the traffic from people retrying every minute (or other interval) – this is a real concern for systems that are under heavy load.

Status codes are like a headline to the calling entity about what happened, and are a valuable tool in the web service toolkit. For bonus points, leave me a comment and tell me which is your favourite status code :)

Version Parameters for Web Services

This is a mini series on points to consider when designing and building web services. So far there have been posts on error feedback for web services, auth mechanisms for web services and saving state in web services.

When designing a service API, there are lots of things you can do right, and plenty of pitfalls. Most of both of these are completely specific to the situation you are designing for but I have one tip that has helped me out in a number of scenarios: Include a version parameter with every method call.

This is invaluable, not just in development where you can increment when you change the API (which could be quite often!) but also in production. For example if you want to extend or alter an existing service, you can identify which version of the API the client thinks it is accessing and behave accordingly – either letting them know there’s a new version, or preserving previous behaviours. Its never ideal to change the API of an existing service but sometimes it makes more sense to do so, especially if its just to include an additional parameter or something else quite minor, but which does cause an API change.

When you publish your shiny new service which does everything you need (including the hoovering), it might seem a bit redundant to require a field which is always set to the string “1.0” … but in 18 months time, you’ll be patting yourself on the back.