These are some notes for working on the OpenWhisk PHP Runtime, but are probably applicable to the other runtimes too. Setting up I have a clone of the runtimes I'm interested in and core side-by-side in a directory. You then need various tools for development, which are documented here for macOS & Ubuntu in the Prerequites section. Build the container The PHP runtime creates two containers, one for PHP 7.1 and one for PHP 7.2.… continue reading.
When writing an API, it's common to produce an output that conforms to a known media type such as JSON API or HAL, etc. I'm a strong believer that even though I'm writing an API, my application has a view layer. It's not the same as building an HTML page, but you still need to separate out the code that creates the structured output from your model layer. For a couple of APIs that I've… continue reading.
Any non-trivial PHP applications use various components to do its work, from PDO though to classes from Packagist. It's fairly common in a standard PHP application to use Dependency Injection to configure and load these classes when necessary. How do we do this in a serverless environment such as OpenWhisk? This question comes up because we do not have a single entry point into our application, instead we have one entry point per action. If… continue reading.
As with all serverless offerings OpenWhisk offers an API Gateway to provide HTTP routing to your serverless actions. This provides a number of advantages over web actions, the most significant of which are routing based on HTTP method, authentication and custom domains (in IBM Cloud). Creating routes with the wsk CLI To route to an action using API Gateway, you first need to make your action a web action first:
$ wsk action update todo-backend/listTodos listTodos.php --web raw
(You can also use… continue reading.
Every PHP project I write has dependencies on components from Packagist and my Serverless OpenWhisk PHP projects are no different. It turns out that adding Composer dependencies is trivial. Let's create a simple action that converts a number to it's string form. e.g. 123 becomes one hundred and twenty three. We'll start with our simple ow-php-hello project from my earlier article and add a new function to serverless.yml:
Our handler is n2w.main, so we… continue reading.
Serverless Framework is a toolkit to help you mange and deploy a serverless application. (Personally, I'm not a fan of the name as the word "Serverless" already has a meaning in the same space!) It's a useful tool and supports all the major providers, though AWS Lambda seems to be first-among-equals. The OpenWhisk plugin for Serverless is maintained by the rather excellent James Thomas, so if you have any questions, ping him! As I build… continue reading.
I'm delighted to announce my new venture, PHP Training, with my friend Gary Hockin. As you can probably guess from the name, PHP Training is a training organisation where we provide public training courses on topics related to PHP. These courses will be held in person, initially at various venues in the UK, and are taught by Gary and myself. Both of us are experienced trainers and this is the first time we've offered training… continue reading.
When creating new OpenWhisk actions in PHP, It's likely that you'll want to take advantage of the rich ecosystem of Composer packages on Packagist.org. The OpenWhisk PHP runtime has you covered with some pre-installed Composer packages and also the ability to upload your own using a zip file. Pre-installed Composer packages The PHP runtime ships with two Composer packages by default: Guzzle and ramsey/uuid. This is handy as if you need to make an API… continue reading.
On a recent project, I needed to implement CORS support for my Expressive API. The easiest way to do this is to use Mike Tuupola's PSR-7 CORS Middleware. As this is a standard Slim-Style PSR-7 middleware implementation, we need to wrap it for Expressive, so we make a factory: App/Factory/CorsMiddlewareFactory.php:
public function __invoke($container)
return new CallableMiddlewareWrapper(
"origin" => ["*"],
"methods" => ["GET", "POST", "PUT", "PATCH", "DELETE"],
"headers.allow" => ["Content-Type", "Accept"],
"headers.expose" => ,
"credentials" => false,
"cache" => 0,
We then register this in our App\ConfigProvider::getDependencies() by adding to the factories key so that it looks something like this:
'factories' => [
Action\HomePageAction::class => Action\HomePageFactory::class,
\Tuupola\Middleware\Cors::class => Factory\CorsMiddlewareFactory::class,
If you don't… continue reading.
I find the Whoops error handler page in Expressive quite hard to read and particularly dislike that the error message displayed in the top left is hidden if it's more than a few words long. To fix this, I discovered that you can provide a custom CSS file to the PrettyPrintHandler and then override to your heart's content! One way to do this is to add a delegator factory to add the additional functionality, so… continue reading.