Skip to content

Instantly share code, notes, and snippets.

@louischan
Created December 20, 2020 14:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louischan/0f7d6caad1cd6103314d9facc77bb11e to your computer and use it in GitHub Desktop.
Save louischan/0f7d6caad1cd6103314d9facc77bb11e to your computer and use it in GitHub Desktop.
AWS Lambda PHP 8 Custom Runtime (Amazon Linux 2)
  1. Compile PHP in a Amazon Linux 2 machine
sudo yum update -y
mkdir php
curl -sL https://github.com/php/php-src/archive/php-8.0.0.tar.gz | tar -xvz
cd php-src-php-8.0.0/
sudo yum install -y gcc autoconf bison re2c libcurl-devel libxml2-devel openssl-devel sqlite-devel oniguruma-devel libzip-devel bzip2-devel
./buildconf --force
# Run ./configure --help for full list of options
./configure --prefix=/home/ec2-user/php/ --with-openssl --with-curl --with-zlib --with-zip --enable-mbstring --enable-cli
sudo make install
  1. Create a zip file that contains the PHP binary, library files and bootstrap file (an example is attached)
mkdir -p ~/runtime/bin/lib/
cd ~/runtime
cp ~/php/bin/php bin/
cp /usr/lib64/libonig.so.2 bin/lib/
cp /usr/lib64/libzip.so.5 bin/lib/
touch ./bootstrap && chmod +x ./bootstrap
# Edit bootstrap file
zip -r runtime.zip bin/php bootstrap
  1. Upload the zip file as a layer using the web console or CLI.

  2. In the web console, add the layer to your function using the ARN of the layer.

  3. Add an environment variable with key LD_LIBRARY_PATH and value /opt/bin/lib/

bootstrap

#!/opt/bin/php
<?php

while (true) {
    // Get an event. The HTTP request will block until one is received
    $request = getNextRequest();

    // Obtain the function name from the _HANDLER environment variable and ensure the function's code is available.
    $handlerFunction = array_slice(explode('.', $_ENV['_HANDLER']), -1)[0];
    require_once $_ENV['LAMBDA_TASK_ROOT'].'/'.$handlerFunction.'.php';

    // Execute the desired function and obtain the response.
    $response = $handlerFunction($request['eventData']);

    // Submit the response back to the runtime API.
    sendResponse($request['requestId'], $response);
}

function getNextRequest() {
    $url = 'http://'.$_ENV['AWS_LAMBDA_RUNTIME_API'].'/2018-06-01/runtime/invocation/next';
    $tmpHeaderFile = tempnam(sys_get_temp_dir(), 'php');
    $eventData = shell_exec('curl -sS -LD '.escapeshellarg($tmpHeaderFile).' -X GET '.escapeshellarg($url));
    $requestId = shell_exec('grep -Fi Lambda-Runtime-Aws-Request-Id '.escapeshellarg($tmpHeaderFile).' | tr -d \'[:space:]\' | cut -d: -f2');
    unlink($tmpHeaderFile);
    return [
        'requestId' => trim($requestId),
        'eventData' => json_decode($eventData, true),
    ];
}

function sendResponse($requestId, $response) {
    $url = 'http://'.$_ENV['AWS_LAMBDA_RUNTIME_API'].'/2018-06-01/runtime/invocation/'.$requestId.'/response';
    shell_exec('curl -X POST '.escapeshellarg($url).' -d '.escapeshellarg($response));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment