Here’s a quick question for the wider PHP programming community … if you’re writing code that tests for the presence of an array, should is_array() also accept objects that behave like arrays?
$testObject = new ArrayObject(array('Tom'));
$testResult = is_array($testObject);
On PHP 5.3.2, $testResult gets set to false. If you wanted to get an object that behaves like an array past this sort of test, you’d have to write:
$testObject = new ArrayObject(array('Tom'));
$testResult = (is_array($testObject) || $testObject instanceof ArrayAccess);
I’m just curious as to what other PHP programmers think of this. Having to write the second test is longer, and there seems to be little or no benefit gained by having to do so.
What do you think?
27 comments »
This is one of a series of blog posts about my experience competing in the European WinPHP Challenge 2009. Sponsored by iBuildings, Microsoft and Leaseweb, competitors are asked to build a PHP app for Windows Server 2008 and IIS 7 to showcase the FAST in FastCGI. The winner gets travel and tickets to Microsoft MIX 2010 in Las Vagas in March. My entry is “Give It A REST”, a SOAP <-> REST gateway.
In my last post, I solved my problems with PHP not working out of the box, and finished choosing and installing apps to complete my development environment. With that done, it’s time to think about the design of Give It A REST.
I find it always helps to start with a short description of what I’m trying to achieve. In a larger enterprise environment, this would normally be found in the product brief written by the product manager.
Given a (possibly remote) WSDL file, Give It A REST will automatically generate a RESTful webservice bridge between remote PHP clients and the remote SOAP service described by the WSDL file. Give It A REST will run on Windows Server 2008, it will use .NET to connect to the remote SOAP service, and the RESTful webservice bridge will be written in PHP.
Throughout the project, I’ll keep coming back to this description to make sure that this is still what I am delivering.
The product brief is just an idea; it needs further iterative development before it’s mature enough to turn into code. Sketching out some basic use cases to identify who will use Give It A REST, and how they will use it, is a good next step. Use cases can be very lightweight (especially the ones I typically create), but they’re easy to share with non-technical folks, and they make it fairly easy to play “what-if” and “walkthrough” type games with your customers. And because they are quick to create, they save you time overall.
When I’m creating use cases, they inevitably go through several iterations. I generally start with some rough ideas for actors, explore the high-level systems that the actors interact with, and then revamp my list of actors to suit the systems and use cases that I’ve discovered. Then, with my new list of actors, I do the whole exercise again, and I keep repeating it until I feel happy with the results. It’s that emotional connection that I’m always searching for whenever I’m designing something; I’m a great believer that this is where the creativity ultimately lies.
In this case, I have decided on four high-level systems that together will make up Give It A REST:
- I need some sort of user manager to handle user registration, login / logout, and administration of registered users.
- A bridge manager will handle the tricky work of creating, managing and destroying individual SOAP <-> REST bridges. It will also handle administration of who is allowed to use which bridge.
- The bridge itself will handle SOAP <-> REST requests and responses, and also provide tools for investigating problems, usage stats, and also (if possible) documentation auto-generated from the WSDL file.
- Finally, users need a way to find the available bridges, so I need a bridge browser for that. It will also provide the mechanism for users to request permission to use a bridge.
The generic ‘users’ need to be clarified into specific actors who participate in specific use cases. Working out the specific roles that a user can have makes it a lot easier to get the permissions system right first time. The downside is that mistakes made at this stage are the most expensive of all to fix.
- Admin users are the administrators of Give It A REST. They can do everything the app allows, without restriction.
- Bridge owners are users who own one or more bridges. They have control over who can and can’t use their bridges. Any user can create a bridge, and so become a bridge owner, but bridges have to be approved by an admin user.
- Bridge users are registered users who are not admin users or bridge owners. They have successfully applied for permission to use one or more bridges.
- Registered users are users who have registered to use the app, but who do not yet have permission to use any of the bridges.
- Finally(!) we have guest users, who need to register to use the site. Their registration must be approved by an admin user before they become registered users.
The actors describe roles, not people. People’s roles can and do change as they successfully complete some of the use cases.
Here are the use case diagrams. You should be able to click on each thumbnail to open the full diagram.
Use Cases: Admin Users
Use Cases: Bridge Owners
Use Cases: Bridge Users
Use Cases: Registered Users
Use Cases: Guest Users
Strictly speaking, the remote PHP RESTful client is also an actor with use cases that could be identified and captured, but I’ve chosen to treat the PHP client as just another way that my existing actors can interact with Give It A REST.
Problems To Solve In R&D
Thankfully, the majority of the use cases are run-of-the-mill web-app functionality that are straightforward to code up. But together, the product brief and use cases have generated a number of problems that I need to solve by a little bit of R&D.
- Given a WSDL file, how can I create a SOAP client in .NET?
- How do I call that SOAP client from PHP code?
- How do I capture the raw XML sent from the .NET client to the SOAP service, and how do I capture the raw XML sent back in response?
- From PHP, can I make multiple simultaneous calls through the SOAP client to the SOAP service?
- Because we’re using FastCGI, can I call multiple .NET SOAP clients from a single PHP process w/out memory leaks?
- How do I automatically define a RESTful client for a SOAP service?
- How will the security for calling a bridge from a RESTful client work?
- How do I automatically generate documentation from the WSDL file?
- What do I use for queueing up offline tasks on Windows?
- How do you do test-driven coding with .NET?
It may feel like I’ve taken the long way round to reach this list, but thanks to having use cases, I’m confident that I have the right list of questions to solve during R&D. If (and right now it is an if) I can solve them all, Give It A REST should be doable.
Whether I have enough time to do it, now that is another question :)
In this post, I’ve clearly stated my initial idea by writing a very basic product brief, and then I’ve started on the long road to clarifying my thinking by creating the main use cases for Give It A REST. I don’t know whether it’s possible to achieve all of these use cases, as I’m not a .NET developer, so I’ve identified the main questions that need to be answered by a little bit of R&D.
The next step is to try and answer all of these questions :)
Last Thursday, twitter was forced to withdraw its free SMS alerts service to UK users. This was a big blow to us at Gradwell dot com, because we’d just started using twitter to push out service alerts to our customers.
Six days later, thanks to the power of symfony, PHP, mysql and q4m, we’ve built and launched a replacement service called twittex.com. This is a very simple-to-use prepay service that allows you to follow the friends of your choice on the mobile phone of your choice via SMS, and it’s now live :)
5 comments »