Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Getting Started With Serverless PHP

DZone's Guide to

Getting Started With Serverless PHP

In this post we take a look at how to build a simple serverless PHP function. Come take a look at what this is and how to do it.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

I've been interested in Apache OpenWhisk for a little while now and recently submitted a new feature to add PHP support to the project. As OpenWhisk is a serverless environment, most users do not run their own copy and instead use a commercial provider with IBM's Bluemix available now along with Adobe's I/O Runtime and RedHat coming soon. As a result, my contribution isn't practically useful until it's in production with a provider.

Fortunately, and remarkably quickly, IBM has added support for PHP to the Bluemix "IBM Cloud Functions" platform, so now we can use PHP to develop serverless applications and deploy them into the wild! This is a rebranding, so you'll see this referred to as "Bluemix OpenWhisk" around the web too.

Let's look at how to write a simple PHP serverless function.

Getting Started

You need a Bluemix account, so go to bluemix.net and create one.

You then need to set up an organization – it has to be unique, so pick something that works for you; mine is called "19FT." You also need to select a region: OpenWhisk is available in the US South and United Kingdom regions. Finally, you need to create a space; mine's called "dev" and I also have a "live."

To interact with an OpenWhisk installation, we need the wsk CLI tool. IBM would prefer you to use their special "Bluemix CLI" tool, but I prefer the stock wsk one as it works with my local installations and all the tutorials you'll find on the web.

To install wsk:

  • Go to https://console.ng.bluemix.net/openwhisk/
  • Click "Download Cloud Functions CLI" and then click "Looking for the wsk CLI?" at the bottom of the page
  • Follow the steps on this page:
    • Download the CLI and then unzip it and place it on your path (e.g. copy it to /usr/local/bin).
    • Check that it works by running wsk help in your terminal. You should see usage information.
    • Copy the wsk property set command that's shown in step 2 and run it in your terminal to set up the authorization.
    • Test it by running the wsk action invoke: /whisk.system/utils/echo -p message hello --result 

You should now have a working wsk command line tool. wsk is remarkably helpful. Add -h to any command and it'll give you help.

If you're only ever going to use the IBM Cloud Functions offering, you can use the IBM Cloud Functions CLI by installing the Bluemix CLI and then installing the Cloud Functions plugin for it. Then, whenever you see wsk in this article or any other tutorial, use bx wsk instead. As I say, I think IBM would prefer you to do this, but I'm not clear what the benefits are for someone who just uses their OpenWhisk product.

Hello World in PHP

In OpenWhisk, we call each function an "action." A PHP action is a function called main that takes an associative array of parameters ($args) and returns an associative array. This is Functions As A Service, so we don't need to worry about anything else other than the code that does the work.

Here's Hello World:

<?php

function main(array $args) : array
{
    $name = $args["name"] ?? "stranger";
    return [
        "greeting" => "Hello $name!"
    ];
}

The PHP runtime on OpenWhisk is PHP 7.1, so we get all the new PHP features. This function doesn't do very much, so I expect you can work out what it does!

Save this file as hello.php.

Upload to OpenWhisk

To upload our action to OpenWhisk, we use the wsk tool from the command line:

$ wsk action update hello hello.php

This creates an action called hello in the default package. Packages are a useful way to group related actions and other OpenWhisk artifacts.

List Our Actions

To list our actions:

$ wsk action list
actions
/19FT_dev/hello                                                   private php:7.1

In this case, I have one action, hello, which is in the default package which is private (i.e. not shared) and uses the kind php:7.1. The kind is the runtime that will be used to execute the action. As the PHP version number is encoded in the kind, we'll be able to add new runtimes that support PHP 7.2, 7.3, etc. OpenWhisk also supports Swift, Node.js, Python, Java, and arbitrary Docker containers in addition to PHP.

Running the Action

There are many ways to run the action. The first way is to use the wsk tool's action invoke command:

$ wsk action invoke --result hello
{
    "greeting": "Hello stranger!"
}

The result parameter tells the command to wait until the action completes before returning and only show the result of the action, ignoring all the metadata. If you want to see the metadata too, then use --blocking instead.

Behind the scenes, this is an API call, so you can also use curl:

$ AUTH=$(wsk property get --auth | awk '{printf("%s", $3)}' | openssl base64 | tr -d "\n")
$ curl -X POST -H "Authorization: Basic $AUTH" \
https://openwhisk.eu-gb.bluemix.net/api/v1/namespaces/_/actions/hello?blocking=true

This uses your private authentication key in the Authorization header, so don't share this, as anyone who knows the key can change your actions and create new ones!

Web Actions

One of the more common uses of serverless actions is as web hook receivers to handle things as diverse as GitHub notifications, Slack commands, and Alexa skills. In all these cases, you register a URL that the service will call when it needs to. Any OpenWhisk action can be configured as a "Web Action" which provides a public URL without having to worry about configuring API Gateways and what not. To do this, you pass --web true to the update command:

$ wsk action update hello --web true

You can also combine, so if you're changing the source file, you can do:

$ wsk action update hello hello.php --web true

To find out the public URL of your action, run:

$ wsk action get hello --url
ok: got action hello
https://openwhisk.eu-gb.bluemix.net/api/v1/web/19FT_dev/default/hello

This endpoint expects you to send back status code, headers, and a body. If you just want to send back the result of your action as JSON, add .json to the end and OpenWhisk will set the status code to 200 and set the content-type header for you.

We can use curl to access our hello action like this:

$ curl https://openwhisk.eu-gb.bluemix.net/api/v1/web/19FT_dev/default/hello.json
{
  "greeting": "Hello stranger!"
}

This is a very convenient way to run an action and is the most common way to register one as a web hook callback on systems such as Slack or Amazon's Alexa.

Parameters

On the command line, we can use the --param argument to pass parameters to our action:

$ wsk action invoke --result hello --param name Rob
{
    "greeting": "Hello Rob!"
}

For web actions, any parameters passed on the query string or POSTed (form encoded or JSON) are available to you in the $args array. Hence we can do:

$ curl https://openwhisk.eu-gb.bluemix.net/api/v1/web/19FT_dev/default/hello.json?name=World

{

  "greeting": "Hello World!"

}

or as a form POST:

$ curl -X POST -d name=Rob https://openwhisk.eu-gb.bluemix.net/api/v1/web/19FT_dev/default/hello.json
{
  "greeting": "Hello Rob!"
}

or even as a JSON-encoded POST:

$ curl -X POST -H "Content-Type: application/json" -d '{"name": "OpenWhisk"}' \
https://openwhisk.eu-gb.bluemix.net/api/v1/web/19FT_dev/default/hello.json
{
  "greeting": "Hello OpenWhisk!"
}

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
openwhisk ,php ,bluemix ,web dev ,http calls

Published at DZone with permission of Rob Allen, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}