PHP Functions on AWS Lambda (without NodeJS)

php lambda without node

I’ve used AWS Lambda for a while in a few different programming languages - including NodeJS, with Go binaries and with PHP. But the PHP functions were always a bit complicated as Lambda doesn’t support PHP as a language natively. You could however emulate it by passing events to Node, which in turn passes the event to a PHP binary, specifically built for AWS architecture, to get around this though.

There’s a slightly neater way to achieve this now, using layers.

Here’s a brief guide on how you can stop using docker to build php binaries, have faster cold-boot times and work with much simpler code.

The Project#

We’re going to use a combination of the Serverless framework and a composer package called Bref to create a simple calculator function. (So we’ll assume you have these things installed, if you don’t check out their respective sites to setup.)

Create a new folder and install bref:

mkdir quickcalc && cd quickcalc
composer require bref/bref

Setup the files needed:

vendor/bin/bref init

php lambda setup

serverless.yml#

At this stage, we’ll now have everything we need to get started. The commands above would have setup the project for serverless and given you a php file to work with.

We’re going to make a few changes to the code - mainly to turn it into a calculator. First, we change the serverless config file to give our function a name, quickcalc, and set our aws region.

service: quickcalc

provider:
    name: aws
    region: eu-west-1
    runtime: provided

plugins:
    - ./vendor/bref/bref

functions:
    function:
        handler: index.php
        description: ''
        layers:
            - ${bref:layer.php-74}

# Exclude files from deployment
package:
    exclude:
        - 'tests/**'

index.php#

We’ll now edit the PHP in our entry point file, index.php. This file returns the result of the function as it’s response, which it will encode into json automatically from an array.

The event that’s passed in is also automatically decoded from json. We’ll use two parameters, num1 and num2, and add them together and return the response (like all good calculators!).

<?php declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

return function ($event) {

    if (empty($event['num1']) || !is_numeric($event['num1'])) {
        throw new InvalidArgumentException("Invalid number 1");
    }
    if (empty($event['num2']) || !is_numeric($event['num2'])) {
        throw new InvalidArgumentException("Invalid number 1");
    }

    return [
        'result' => ($event['num1'] + $event['num2']),
    ];
};

Deploy!#

We should be good to go. Run our deploy command to let serverless handle using CloudFormation to build a lambda function. Without any parameters, this will have created a dev function - use --stage production if need to push a second production function.

serverless deploy

Test#

In AWS we can test our Lambda function by passing it an example of our request event.

{
    "num1": "123",
    "num2": "456"
}

Which all being well should return you the magic number: 579

php lambda test