From 67610bfb06970d2123b30871630fc52af42cfc07 Mon Sep 17 00:00:00 2001
From: David Michael <1.david.michael@gmail.com>
Date: Fri, 30 Nov 2018 14:39:00 -0600
Subject: [PATCH 01/42] Update README.md template to be consistent with paths
 described

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 61b979c..c191980 100644
--- a/README.md
+++ b/README.md
@@ -84,7 +84,7 @@ Resources:
     Properties:
       FunctionName: !Sub ${AWS::StackName}-phpserver
       Description: PHP Webserver
-      CodeUri: src/server
+      CodeUri: src/php
       Runtime: provided
       Handler: index.php
       MemorySize: 3008

From e7ad8860ab40fc6a522c0c56c093f165870585ee Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Sat, 1 Dec 2018 11:04:45 -0800
Subject: [PATCH 02/42] Load php.ini from function code root directory

---
 bootstrap | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bootstrap b/bootstrap
index 5794495..e03422f 100755
--- a/bootstrap
+++ b/bootstrap
@@ -15,7 +15,7 @@ function start_webserver() {
       // exec the command
       $HANDLER = getenv('_HANDLER');
       chdir('/var/task');
-      exec("php -S localhost:8000 '$HANDLER'");
+      exec("php -S localhost:8000 -c /var/task/php.ini '$HANDLER'");
       exit;
 
     // return the child pid to parent

From 8dedbe73d734b1980d31ffd65d14945dedc41076 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Sat, 1 Dec 2018 11:05:31 -0800
Subject: [PATCH 03/42] Don't encode non-ascii responses

---
 bootstrap | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/bootstrap b/bootstrap
index e03422f..e6d7d42 100755
--- a/bootstrap
+++ b/bootstrap
@@ -200,11 +200,6 @@ while (true) {
   curl_exec($ch);
   curl_close($ch);
 
-  if (preg_match('/[^\x00-\x7f]/', $response['body'])) {
-    $response['body'] = base64_encode($response_body);
-    $response['isBase64Encoded'] = TRUE;
-  }
-
   $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
 
   $response_json = json_encode($response);

From ff5e771d5365a9f9bf3033306d3cc772b383ad1e Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Sat, 1 Dec 2018 11:10:55 -0800
Subject: [PATCH 04/42] Specify extension_dir on command line

So it doesn't need to be specified in php.ini.
---
 bootstrap | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bootstrap b/bootstrap
index e6d7d42..6b71548 100755
--- a/bootstrap
+++ b/bootstrap
@@ -15,7 +15,7 @@ function start_webserver() {
       // exec the command
       $HANDLER = getenv('_HANDLER');
       chdir('/var/task');
-      exec("php -S localhost:8000 -c /var/task/php.ini '$HANDLER'");
+      exec("php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.1/modules '$HANDLER'");
       exit;
 
     // return the child pid to parent

From 42a7d106ab5787f1b26e738e3794c4b95cc74f34 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Sat, 1 Dec 2018 11:14:10 -0800
Subject: [PATCH 05/42] Update and improve extension documentation

---
 README.md | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index c191980..7630eb7 100644
--- a/README.md
+++ b/README.md
@@ -22,13 +22,6 @@ $ php -S localhost:8000 '<handler>'
 The Lambda Function Handler property specifies the location of the the script executed in response to an incoming API Gateway request.
 
 ##### Extensions
-Extensions can be built using the lambci/lambda:build-nodejs8.10 Docker image. It is recommended that extensions be built into a Lambda Layer in /lib/php/7.1/modules. Then, in a php.ini file in the Lambda Function root directory put:
-
-```ini
-extension_dir=/opt/lib/php/7.1/modules
-extension=...
-```
-
 The following extensions are built into the layer and available in /opt/lib/php/7.1/modules:
 
 ```
@@ -60,6 +53,14 @@ xsl.so
 zip.so
 ```
 
+These extensions are not loaded by default. You must add the extension to your php.ini file to use it:
+
+```ini
+extension=json.so
+```
+
+Extensions can be built using the lambci/lambda:build-nodejs8.10 Docker image. It is recommended that custom extensions be provided by a separate Lambda Layer with the extension .so files placed in /lib/php/7.1/modules/ so they can be loaded alongside the built-in extensions listed above.
+
 #### Example
 Let's create an AWS SAM PHP application. We suggest using [Stackery](https://stackery.io) to make this super simple. It automates all the scaffolding shown below. But you may also choose to roll your own application from scratch.
 

From 76a2d0258e1366d438450ea5383b331c0a3e86dc Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Sat, 1 Dec 2018 11:29:10 -0800
Subject: [PATCH 06/42] Release PHP 7.1 layer version 4

---
 README.md | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 7630eb7..ee0541b 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,9 @@ This is an early iteration of the PHP runtime Layer which is not yet ready for p
 ## Current Layer Version ARN
 When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARN is:
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:3**
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:4**
+
+See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
 ### Usage
 #### General Usage
@@ -92,7 +94,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:3
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:4
       Events:
         api:
           Type: Api

From d8356936702512ab89df19df9a5532bab5d88cb2 Mon Sep 17 00:00:00 2001
From: Alan Trope <atrope@gmail.com>
Date: Sun, 2 Dec 2018 19:39:46 +0200
Subject: [PATCH 07/42] Adding ALB Support Out of the Box.

---
 bootstrap | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/bootstrap b/bootstrap
index 6b71548..cde3a43 100755
--- a/bootstrap
+++ b/bootstrap
@@ -5,6 +5,9 @@ error_reporting(E_ALL | E_STRICT);
 
 $AWS_LAMBDA_RUNTIME_API = getenv('AWS_LAMBDA_RUNTIME_API');
 
+/* https://gist.github.com/henriquemoody/6580488 */
+$http_codes = [100=>'Continue',101=>'Switching Protocols',102=>'Processing',200=>'OK',201=>'Created',202=>'Accepted',203=>'Non-Authoritative Information',204=>'No Content',205=>'Reset Content',206=>'Partial Content',207=>'Multi-Status',208=>'Already Reported',226=>'IM Used',300=>'Multiple Choices',301=>'Moved Permanently',302=>'Found',303=>'See Other',304=>'Not Modified',305=>'Use Proxy',306=>'Switch Proxy',307=>'Temporary Redirect',308=>'Permanent Redirect',400=>'Bad Request',401=>'Unauthorized',402=>'Payment Required',403=>'Forbidden',404=>'Not Found',405=>'Method Not Allowed',406=>'Not Acceptable',407=>'Proxy Authentication Required',408=>'Request Timeout',409=>'Conflict',410=>'Gone',411=>'Length Required',412=>'Precondition Failed',413=>'Request Entity Too Large',414=>'Request-URI Too Long',415=>'Unsupported Media Type',416=>'Requested Range Not Satisfiable',417=>'Expectation Failed',418=>'I\'m a teapot',419=>'Authentication Timeout',420=>'Enhance Your Calm',420=>'Method Failure',422=>'Unprocessable Entity',423=>'Locked',424=>'Failed Dependency',424=>'Method Failure',425=>'Unordered Collection',426=>'Upgrade Required',428=>'Precondition Required',429=>'Too Many Requests',431=>'Request Header Fields Too Large',444=>'No Response',449=>'Retry With',450=>'Blocked by Windows Parental Controls',451=>'Redirect',451=>'Unavailable For Legal Reasons',494=>'Request Header Too Large',495=>'Cert Error',496=>'No Cert',497=>'HTTP to HTTPS',499=>'Client Closed Request',500=>'Internal Server Error',501=>'Not Implemented',502=>'Bad Gateway',503=>'Service Unavailable',504=>'Gateway Timeout',505=>'HTTP Version Not Supported',506=>'Variant Also Negotiates',507=>'Insufficient Storage',508=>'Loop Detected',509=>'Bandwidth Limit Exceeded',510=>'Not Extended',511=>'Network Authentication Required',598=>'Network read timeout error',599=>'Network connect timeout error'];
+
 function start_webserver() {
   $pid = pcntl_fork();
   switch($pid) {
@@ -137,7 +140,7 @@ while (true) {
         array_push($headers, "${name}: ${value}");
       }
     }
-    
+
     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
   }
 
@@ -202,18 +205,24 @@ while (true) {
 
   $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
 
+  $isALB = array_key_exists("elb", $event['requestContext']);
+  if ($isALB) { // Add Headers For ALB
+    $status = $response["statusCode"];
+    $response["statusDescription"] = "$status ". $http_codes[$status];
+    $response["isBase64Encoded"] = false;
+  }
   $response_json = json_encode($response);
-
   curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
   curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
-  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
-    'Content-Type: application/json',
-    'Content-Length: ' . strlen($response_json)
-  ));
-
+  if (!$isALB){
+    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+      'Content-Type: application/json',
+      'Content-Length: ' . strlen($response_json)
+    ));
+  }
   curl_exec($ch);
   curl_close($ch);
 }
 
-?>
\ No newline at end of file
+?>

From 9c4871b733826c4a2e701590d810bfa2560d45f3 Mon Sep 17 00:00:00 2001
From: Jerry Verhoef <jerry@lucard.nl>
Date: Sun, 2 Dec 2018 15:21:07 -0800
Subject: [PATCH 08/42] Allow layers to load extra ini files and allow the task
  to load additional ini files

---
 README.md | 4 +++-
 bootstrap | 6 +++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index ee0541b..67f6674 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,9 @@ extension=json.so
 
 Extensions can be built using the lambci/lambda:build-nodejs8.10 Docker image. It is recommended that custom extensions be provided by a separate Lambda Layer with the extension .so files placed in /lib/php/7.1/modules/ so they can be loaded alongside the built-in extensions listed above.
 
-#### Example
+The extensions can be loaded by adding an ini file in the etc/php-7.1.d this will be picked up automatically
+
+#### SAM Example
 Let's create an AWS SAM PHP application. We suggest using [Stackery](https://stackery.io) to make this super simple. It automates all the scaffolding shown below. But you may also choose to roll your own application from scratch.
 
 First, install [AWS SAM CLI](https://github.com/awslabs/aws-sam-cli). Make sure to create a SAM deployment bucket as shown in [Packaging your application](https://github.com/awslabs/aws-sam-cli/blob/develop/docs/deploying_serverless_applications.rst#packaging-your-application)
diff --git a/bootstrap b/bootstrap
index 6b71548..f15acaa 100755
--- a/bootstrap
+++ b/bootstrap
@@ -15,7 +15,7 @@ function start_webserver() {
       // exec the command
       $HANDLER = getenv('_HANDLER');
       chdir('/var/task');
-      exec("php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.1/modules '$HANDLER'");
+      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.1.d/:/var/task/php-7.1.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.1/modules '$HANDLER'");
       exit;
 
     // return the child pid to parent
@@ -137,7 +137,7 @@ while (true) {
         array_push($headers, "${name}: ${value}");
       }
     }
-    
+
     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
   }
 
@@ -216,4 +216,4 @@ while (true) {
   curl_close($ch);
 }
 
-?>
\ No newline at end of file
+?>

From ea769d9b698cd7a503287b7e593f57db696283aa Mon Sep 17 00:00:00 2001
From: Alan Trope <atrope@gmail.com>
Date: Mon, 3 Dec 2018 18:55:57 +0200
Subject: [PATCH 09/42] Checking existing StatusCodes

---
 bootstrap | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/bootstrap b/bootstrap
index cde3a43..0399cf8 100755
--- a/bootstrap
+++ b/bootstrap
@@ -208,7 +208,11 @@ while (true) {
   $isALB = array_key_exists("elb", $event['requestContext']);
   if ($isALB) { // Add Headers For ALB
     $status = $response["statusCode"];
-    $response["statusDescription"] = "$status ". $http_codes[$status];
+    if (array_key_exists($status, $http_codes)) {
+        $response["statusDescription"] = "$status ". $http_codes[$status];
+    } else {
+        $response["statusDescription"] = "$status Unknown";
+    }
     $response["isBase64Encoded"] = false;
   }
   $response_json = json_encode($response);

From c081de0f73d013cf2d8db50c737f6da4baaa2602 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 4 Dec 2018 08:27:49 -0800
Subject: [PATCH 10/42] Updated documentation for ini file locations and ALB
 requests

---
 README.md | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 67f6674..7bcb131 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # PHP Layer For AWS Lambda
 
-Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.1 webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) requests.
+Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.1 webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) or [AWS Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/features/#Details_for_Elastic_Load_Balancing_Products) requests.
 
 And, if you're looking for a great way to build serverless apps of all kinds, be sure to check out [Stackery](https://stackery.io)!
 
@@ -21,7 +21,14 @@ The layer runs the PHP 7.1 [PHP webserver](http://php.net/manual/en/features.com
 $ php -S localhost:8000 '<handler>'
 ```
 
-The Lambda Function Handler property specifies the location of the the script executed in response to an incoming API Gateway request.
+The Lambda Function Handler property specifies the location of the the script executed in response to an incoming API Gateway or Application Load Balancer request.
+
+#### Configuration Files
+There are three locations where PHP configuration may be located:
+
+* Files in layer code packages located under /etc/php-7.1.d/
+* Files in function code package located under /php-7.1.d/
+* php.ini located at the root of the function code package
 
 ##### Extensions
 The following extensions are built into the layer and available in /opt/lib/php/7.1/modules:
@@ -55,7 +62,7 @@ xsl.so
 zip.so
 ```
 
-These extensions are not loaded by default. You must add the extension to your php.ini file to use it:
+These extensions are not loaded by default. You must add the extension to a php.ini file to use it:
 
 ```ini
 extension=json.so
@@ -63,8 +70,6 @@ extension=json.so
 
 Extensions can be built using the lambci/lambda:build-nodejs8.10 Docker image. It is recommended that custom extensions be provided by a separate Lambda Layer with the extension .so files placed in /lib/php/7.1/modules/ so they can be loaded alongside the built-in extensions listed above.
 
-The extensions can be loaded by adding an ini file in the etc/php-7.1.d this will be picked up automatically
-
 #### SAM Example
 Let's create an AWS SAM PHP application. We suggest using [Stackery](https://stackery.io) to make this super simple. It automates all the scaffolding shown below. But you may also choose to roll your own application from scratch.
 

From 128ed23850252f9d7fc851d194d2b6d02b5a98e2 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Wed, 5 Dec 2018 08:00:40 -0800
Subject: [PATCH 11/42] Release layer version 5

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 7bcb131..9b536c8 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ This is an early iteration of the PHP runtime Layer which is not yet ready for p
 ## Current Layer Version ARN
 When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARN is:
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:4**
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:5**
 
 See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
@@ -101,7 +101,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:4
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:5
       Events:
         api:
           Type: Api

From 5958ce0bb1355286c201a94aa413fb43a5a8eb96 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Wed, 5 Dec 2018 08:21:24 -0800
Subject: [PATCH 12/42] Create pull request template

---
 .github/pull_request_template.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 .github/pull_request_template.md

diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..f496cf9
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1 @@
+**:warning: Please make sure pull requests are opened against the development branch. Pull requests opened against master will be closed automatically.** You may delete this line once you have confirmed the correct branch. :pray:

From 2a7eb8416db33a3cca2d9195dec34f0276b3e8f9 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Wed, 5 Dec 2018 08:23:03 -0800
Subject: [PATCH 13/42] Update pull_request_template.md

---
 .github/pull_request_template.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index f496cf9..e6a05a7 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1 +1 @@
-**:warning: Please make sure pull requests are opened against the development branch. Pull requests opened against master will be closed automatically.** You may delete this line once you have confirmed the correct branch. :pray:
+Please make sure pull requests are opened against the development branch. Pull requests opened against master will be closed automatically. Please delete this line once you have confirmed the correct branch.

From 5aeccb54656e67656cf9cdb268d4ec41f400837a Mon Sep 17 00:00:00 2001
From: Andy Buckingham <andy@aiir.com>
Date: Thu, 6 Dec 2018 16:27:41 +0000
Subject: [PATCH 14/42] Fix value of `PHP_SELF` when router script is in a
 subdirectory

PHP's built-in web server sets the value of `$_SERVER['PHP_SELF']` differently
when the router script is in working directory versus a subdirectory of the
working directory. This breaks routing functionality in routing libraries such
as [Slim](https://www.slimframework.com).

When the script is in the working directory, the value of `PHP_SELF` is the
filename of the script, but when run from a parent directory of the script it
changes to being the path requested of the web server.

This commit changes `bootstrap` behaviour when referring to the Lambda handler.
If it refers to a script in a subdirectory of the task root, it changes the
`chdir` call to enter that directory before running the PHP internal web-server,
so that it can refer to the script filename as being in the working directory.

This poses no change to how the layer is configured or run, but `PHP_SELF` now
correctly refers to the filename and this solves the issue with Slim.

Resolves: stackery/php-lambda-layer#11
---
 bootstrap | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/bootstrap b/bootstrap
index 37e3264..8391e0a 100755
--- a/bootstrap
+++ b/bootstrap
@@ -17,8 +17,11 @@ function start_webserver() {
     case 0:
       // exec the command
       $HANDLER = getenv('_HANDLER');
-      chdir('/var/task');
-      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.1.d/:/var/task/php-7.1.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.1/modules '$HANDLER'");
+      $handler_components = explode('/', $HANDLER);
+      $handler_filename = array_pop($handler_components);
+      $handler_path = implode('/', array_merge(['/var/task'], $handler_components));
+      chdir($handler_path);
+      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.1.d/:/var/task/php-7.1.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.1/modules '$handler_filename'");
       exit;
 
     // return the child pid to parent

From ab30c064384836992b208b4db251604b10663d96 Mon Sep 17 00:00:00 2001
From: Tomoya Iwata <iwata.tomoya@classmethod.jp>
Date: Mon, 24 Dec 2018 14:55:52 +0900
Subject: [PATCH 15/42] send post data to backend when request method is post

---
 bootstrap | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/bootstrap b/bootstrap
index 37e3264..73cce3f 100755
--- a/bootstrap
+++ b/bootstrap
@@ -156,6 +156,9 @@ while (true) {
   }
 
   if (strlen($body) > 0) {
+    if($event['httpMethod'] === 'POST'){
+      curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+    }    
     curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
     curl_setopt($ch, CURLOPT_READFUNCTION, function ($ch, $fd, $length) use ($body) {
       return $body;

From 1fa196cb844e226d598e0590473bd4cffb479caf Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Thu, 3 Jan 2019 16:32:42 -0800
Subject: [PATCH 16/42] Release layer version 6

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 9b536c8..916a432 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ This is an early iteration of the PHP runtime Layer which is not yet ready for p
 ## Current Layer Version ARN
 When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARN is:
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:5**
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:6**
 
 See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
@@ -101,7 +101,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:5
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:6
       Events:
         api:
           Type: Api

From 96c9169ee63bb634f55e0ba7b2bc9fe4eb7ca17e Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Sun, 6 Jan 2019 08:23:42 +0100
Subject: [PATCH 17/42] Added support for mbstring, postgresql, mysql

---
 build.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.sh b/build.sh
index c646c79..a0da5b9 100755
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-yum install -y php71-cli zip
+yum install -y php71-mbstring.x86_64 zip php71-pgsql php71-mysqli
 
 mkdir /tmp/layer
 cd /tmp/layer

From bdd2286d49859253cf6338a0ce2b18af31eeef85 Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Sun, 6 Jan 2019 08:33:58 +0100
Subject: [PATCH 18/42] Added support for mbstring, postgresql, mysql

---
 README.md | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/README.md b/README.md
index 916a432..1387558 100644
--- a/README.md
+++ b/README.md
@@ -45,11 +45,20 @@ ftp.so
 gettext.so
 iconv.so
 json.so
+mbstring.so
+mysqli.so
+mysqlnd.so
+pdo.so
+pdo_mysql.so
+pdo_pgsql.so
+pdo_sqlite.so
+pgsql.so
 phar.so
 posix.so
 shmop.so
 simplexml.so
 sockets.so
+sqlite3.so
 sysvmsg.so
 sysvsem.so
 sysvshm.so

From 41eb94b48d0f99d689cba693abf19febe319b932 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 15 Jan 2019 15:09:01 -0800
Subject: [PATCH 19/42] Release layer version 7

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 916a432..e616b8e 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ This is an early iteration of the PHP runtime Layer which is not yet ready for p
 ## Current Layer Version ARN
 When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARN is:
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:6**
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:7**
 
 See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
@@ -101,7 +101,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:6
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:7
       Events:
         api:
           Type: Api

From 35f7a86714425d6e8c467a1fe1d40c7403d43c4b Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Wed, 16 Jan 2019 07:00:59 +0100
Subject: [PATCH 20/42] Added support for PHP 7.2 and 7.3

---
 .gitignore      |   2 +
 Makefile        |   9 +-
 README.md       |  42 ++++++---
 bootstrap-php72 | 235 ++++++++++++++++++++++++++++++++++++++++++++++++
 bootstrap-php73 | 235 ++++++++++++++++++++++++++++++++++++++++++++++++
 build-php72.sh  |  40 +++++++++
 build-php73.sh  |  40 +++++++++
 build.sh        |   1 +
 php72.ini       |   4 +
 php73.ini       |   4 +
 10 files changed, 597 insertions(+), 15 deletions(-)
 create mode 100644 bootstrap-php72
 create mode 100644 bootstrap-php73
 create mode 100644 build-php72.sh
 create mode 100644 build-php73.sh
 create mode 100644 php72.ini
 create mode 100644 php73.ini

diff --git a/.gitignore b/.gitignore
index 15cc1ca..59f7c11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
 php71.zip
+php72.zip
+php73.zip
diff --git a/Makefile b/Makefile
index e6453b0..269a84f 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,12 @@ ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
 php71.zip:
 	docker run --rm -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build.sh
 
+php72.zip:
+	docker run --rm -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php72.sh
+
+php73.zip:
+	docker run --rm -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php73.sh
+
 upload: php71.zip
 	./upload.sh
 
@@ -10,4 +16,5 @@ publish: php71.zip
 	./publish.sh
 
 clean:
-	rm php71.zip
+	rm -f php71.zip php72.zip php73.zip
+
diff --git a/README.md b/README.md
index 1387558..b60f70b 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,19 @@
 # PHP Layer For AWS Lambda
 
-Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.1 webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) or [AWS Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/features/#Details_for_Elastic_Load_Balancing_Products) requests.
+Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.1/7.2/7.3 webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) or [AWS Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/features/#Details_for_Elastic_Load_Balancing_Products) requests.
 
-And, if you're looking for a great way to build serverless apps of all kinds, be sure to check out [Stackery](https://stackery.io)!
+This project is fork of the [Stackery](https://stackery.io) [php-lambda-layer](https://github.com/stackery/php-lambda-layer) that has been modified to:
 
-This is an early iteration of the PHP runtime Layer which is not yet ready for production. Please feel free to use this Layer to learn about the Lambda Layers feature and begin experimenting with PHP functions. We welcome feedback and stay tuned for the production-ready version coming soon.
-
-## Current Layer Version ARN
-When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARN is:
+- support PHP 7.1, 7.2, and 7.3 (the original supports 7.1 only) - using the [Remi RPM Repository](https://rpms.remirepo.net/)
+- add support for mbstring, MySQL (pdo-mysql) and Postgres (pdo-pgsql)
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:6**
+that are requirements for running frameworks such as [Lumen](https://lumen.laravel.com/) and [Laravel](https://laravel.com/) frameworks in serverless mode.
 
-See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
+This is an early iteration of the PHP runtime Layer which is not yet ready for production. Please feel free to use this Layer to learn about the Lambda Layers feature and begin experimenting with PHP functions. We welcome feedback and stay tuned for the production-ready version coming soon.
 
 ### Usage
 #### General Usage
-The layer runs the PHP 7.1 [PHP webserver](http://php.net/manual/en/features.commandline.webserver.php) in /var/task, the root directory of function code packages:
+The layer runs the PHP 7.* [PHP webserver](http://php.net/manual/en/features.commandline.webserver.php) in /var/task, the root directory of function code packages:
 
 ```sh
 $ php -S localhost:8000 '<handler>'
@@ -26,12 +24,14 @@ The Lambda Function Handler property specifies the location of the the script ex
 #### Configuration Files
 There are three locations where PHP configuration may be located:
 
-* Files in layer code packages located under /etc/php-7.1.d/
-* Files in function code package located under /php-7.1.d/
+* Files in layer code packages located under /etc/php-<PHP_VERSION>.d/
+* Files in function code package located under /php-<PHP_VERSION>.d/
 * php.ini located at the root of the function code package
 
+Replace <PHP_VERSION> with 7.1, 7.2, or 7.3 according to your preferred runtime.
+
 ##### Extensions
-The following extensions are built into the layer and available in /opt/lib/php/7.1/modules:
+The following extensions are built into the layer and available in /opt/lib/php/7.1/modules (PHP 7.1) or /opt/lib/php/modules (PHP 7.2/7.3):
 
 ```
 bz2.so
@@ -154,9 +154,23 @@ $ sam deploy \
 Build the layer by:
 
 1. Installing a Docker environment
-1. Running `make`
+2. Running `make`
+
+This will launch a Docker container that will build php71.zip, based on PHP 7.1 (default).
+
+You can run `make php72.zip` and `make php73.zip` to create a layer that is based on PHP 7.2/7.3.
+
+### Debugging
+
+Run:
+
+	$ docker run --rm -it -v `pwd`:/opt/layer lambci/lambda:build-nodejs8.10 /bin/bash
+	
+If you are on Windows, run this instead:
 
-This will launch a Docker container that will build php71.zip.
+	> docker run --rm -it -v %cd%:/opt/layer lambci/lambda:build-nodejs8.10 /bin/bash
+	
+and execute manually the commands in the build.sh file.
 
 ### Disclaimer
 
diff --git a/bootstrap-php72 b/bootstrap-php72
new file mode 100644
index 0000000..3abb20a
--- /dev/null
+++ b/bootstrap-php72
@@ -0,0 +1,235 @@
+#!/opt/bin/php -c/opt/php.ini
+<?php
+
+error_reporting(E_ALL | E_STRICT);
+
+$AWS_LAMBDA_RUNTIME_API = getenv('AWS_LAMBDA_RUNTIME_API');
+
+/* https://gist.github.com/henriquemoody/6580488 */
+$http_codes = [100=>'Continue',101=>'Switching Protocols',102=>'Processing',200=>'OK',201=>'Created',202=>'Accepted',203=>'Non-Authoritative Information',204=>'No Content',205=>'Reset Content',206=>'Partial Content',207=>'Multi-Status',208=>'Already Reported',226=>'IM Used',300=>'Multiple Choices',301=>'Moved Permanently',302=>'Found',303=>'See Other',304=>'Not Modified',305=>'Use Proxy',306=>'Switch Proxy',307=>'Temporary Redirect',308=>'Permanent Redirect',400=>'Bad Request',401=>'Unauthorized',402=>'Payment Required',403=>'Forbidden',404=>'Not Found',405=>'Method Not Allowed',406=>'Not Acceptable',407=>'Proxy Authentication Required',408=>'Request Timeout',409=>'Conflict',410=>'Gone',411=>'Length Required',412=>'Precondition Failed',413=>'Request Entity Too Large',414=>'Request-URI Too Long',415=>'Unsupported Media Type',416=>'Requested Range Not Satisfiable',417=>'Expectation Failed',418=>'I\'m a teapot',419=>'Authentication Timeout',420=>'Enhance Your Calm',420=>'Method Failure',422=>'Unprocessable Entity',423=>'Locked',424=>'Failed Dependency',424=>'Method Failure',425=>'Unordered Collection',426=>'Upgrade Required',428=>'Precondition Required',429=>'Too Many Requests',431=>'Request Header Fields Too Large',444=>'No Response',449=>'Retry With',450=>'Blocked by Windows Parental Controls',451=>'Redirect',451=>'Unavailable For Legal Reasons',494=>'Request Header Too Large',495=>'Cert Error',496=>'No Cert',497=>'HTTP to HTTPS',499=>'Client Closed Request',500=>'Internal Server Error',501=>'Not Implemented',502=>'Bad Gateway',503=>'Service Unavailable',504=>'Gateway Timeout',505=>'HTTP Version Not Supported',506=>'Variant Also Negotiates',507=>'Insufficient Storage',508=>'Loop Detected',509=>'Bandwidth Limit Exceeded',510=>'Not Extended',511=>'Network Authentication Required',598=>'Network read timeout error',599=>'Network connect timeout error'];
+
+function start_webserver() {
+  $pid = pcntl_fork();
+  switch($pid) {
+    case -1:
+      die('Failed to fork webserver process');
+
+    case 0:
+      // exec the command
+      $HANDLER = getenv('_HANDLER');
+      chdir('/var/task');
+      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.2.d/:/var/task/php-7.2.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/modules '$HANDLER'");
+      exit;
+
+    // return the child pid to parent
+    default:
+      // Wait for child server to start
+      sleep(1);
+      return $pid;
+  }
+}
+
+function fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, $message) {
+  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
+
+  $response = array();
+
+  $response['statusCode'] = 500;
+  $response['body'] = $message;
+
+  $response_json = json_encode($response);
+
+  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
+  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
+  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+    'Content-Type: application/json',
+    'Content-Length: ' . strlen($response_json)
+  ));
+
+  curl_exec($ch);
+  curl_close($ch);
+}
+
+start_webserver();
+
+while (true) {
+  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/next");
+
+  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
+  curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
+
+  $invocation_id = '';
+
+  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$invocation_id) {
+    if (!preg_match('/:\s*/', $header)) {
+      return strlen($header);
+    }
+
+    [$name, $value] = preg_split('/:\s*/', $header, 2);
+
+    if (strtolower($name) == 'lambda-runtime-aws-request-id') {
+      $invocation_id = trim($value);
+    }
+
+    return strlen($header);
+  });
+
+  $body = '';
+
+  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$body) {
+    $body .= $chunk;
+
+    return strlen($chunk);
+  });
+
+  curl_exec($ch);
+
+  if (curl_error($ch)) {
+    die('Failed to fetch next Lambda invocation: ' . curl_error($ch) . "\n");
+  }
+
+  if ($invocation_id == '') {
+    die('Failed to determine Lambda invocation ID');
+  }
+
+  curl_close($ch);
+
+  if (!$body) {
+    die("Empty Lambda invocation response\n");
+  }
+
+  $event = json_decode($body, TRUE);
+
+  if (!array_key_exists('requestContext', $event)) {
+    fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, 'Event is not an API Gateway request');
+    continue;
+  }
+
+  $uri = $event['path'];
+
+  if (array_key_exists('multiValueQueryStringParameters', $event) && $event['multiValueQueryStringParameters']) {
+    $first = TRUE;
+    foreach ($event['multiValueQueryStringParameters'] as $name => $values) {
+      foreach ($values as $value) {
+        if ($first) {
+          $uri .= "?";
+          $first = FALSE;
+        } else {
+          $uri .= "&";
+        }
+
+        $uri .= $name;
+
+        if ($value != '') {
+          $uri .= '=' . $value;
+        }
+      }
+    }
+  }
+
+  $ch = curl_init("http://localhost:8000$uri");
+
+  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
+
+  if (array_key_exists('multiValueHeaders', $event)) {
+    $headers = array();
+
+    foreach ($event['multiValueHeaders'] as $name => $values) {
+      foreach ($values as $value) {
+        array_push($headers, "${name}: ${value}");
+      }
+    }
+
+    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+  }
+
+  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $event['httpMethod']);
+
+  if (array_key_exists('body', $event)) {
+    $body = $event['body'];
+    if (array_key_exists('isBase64Encoded', $event) && $event['isBase64Encoded']) {
+      $body = base64_decode($body);
+    }
+  } else {
+    $body = '';
+  }
+
+  if (strlen($body) > 0) {
+    if($event['httpMethod'] === 'POST'){
+      curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+    }    
+    curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
+    curl_setopt($ch, CURLOPT_READFUNCTION, function ($ch, $fd, $length) use ($body) {
+      return $body;
+    });
+  }
+
+  $response = array();
+  $response['multiValueHeaders'] = array();
+  $response['body'] = '';
+
+  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$response) {
+    if (preg_match('/HTTP\/1.1 (\d+) .*/', $header, $matches)) {
+      $response['statusCode'] = intval($matches[1]);
+      return strlen($header);
+    }
+
+    if (!preg_match('/:\s*/', $header)) {
+      return strlen($header);
+    }
+
+    [$name, $value] = preg_split('/:\s*/', $header, 2);
+
+    $name = trim($name);
+    $value = trim($value);
+
+    if ($name == '') {
+      return strlen($header);
+    }
+
+    if (!array_key_exists($name, $response['multiValueHeaders'])) {
+      $response['multiValueHeaders'][$name] = array();
+    }
+
+    array_push($response['multiValueHeaders'][$name], $value);
+
+    return strlen($header);
+  });
+
+  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$response) {
+    $response['body'] .= $chunk;
+
+    return strlen($chunk);
+  });
+
+  curl_exec($ch);
+  curl_close($ch);
+
+  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
+
+  $isALB = array_key_exists("elb", $event['requestContext']);
+  if ($isALB) { // Add Headers For ALB
+    $status = $response["statusCode"];
+    if (array_key_exists($status, $http_codes)) {
+        $response["statusDescription"] = "$status ". $http_codes[$status];
+    } else {
+        $response["statusDescription"] = "$status Unknown";
+    }
+    $response["isBase64Encoded"] = false;
+  }
+  $response_json = json_encode($response);
+  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
+  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
+  if (!$isALB){
+    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+      'Content-Type: application/json',
+      'Content-Length: ' . strlen($response_json)
+    ));
+  }
+  curl_exec($ch);
+  curl_close($ch);
+}
+
+?>
diff --git a/bootstrap-php73 b/bootstrap-php73
new file mode 100644
index 0000000..2d7ae93
--- /dev/null
+++ b/bootstrap-php73
@@ -0,0 +1,235 @@
+#!/opt/bin/php -c/opt/php.ini
+<?php
+
+error_reporting(E_ALL | E_STRICT);
+
+$AWS_LAMBDA_RUNTIME_API = getenv('AWS_LAMBDA_RUNTIME_API');
+
+/* https://gist.github.com/henriquemoody/6580488 */
+$http_codes = [100=>'Continue',101=>'Switching Protocols',102=>'Processing',200=>'OK',201=>'Created',202=>'Accepted',203=>'Non-Authoritative Information',204=>'No Content',205=>'Reset Content',206=>'Partial Content',207=>'Multi-Status',208=>'Already Reported',226=>'IM Used',300=>'Multiple Choices',301=>'Moved Permanently',302=>'Found',303=>'See Other',304=>'Not Modified',305=>'Use Proxy',306=>'Switch Proxy',307=>'Temporary Redirect',308=>'Permanent Redirect',400=>'Bad Request',401=>'Unauthorized',402=>'Payment Required',403=>'Forbidden',404=>'Not Found',405=>'Method Not Allowed',406=>'Not Acceptable',407=>'Proxy Authentication Required',408=>'Request Timeout',409=>'Conflict',410=>'Gone',411=>'Length Required',412=>'Precondition Failed',413=>'Request Entity Too Large',414=>'Request-URI Too Long',415=>'Unsupported Media Type',416=>'Requested Range Not Satisfiable',417=>'Expectation Failed',418=>'I\'m a teapot',419=>'Authentication Timeout',420=>'Enhance Your Calm',420=>'Method Failure',422=>'Unprocessable Entity',423=>'Locked',424=>'Failed Dependency',424=>'Method Failure',425=>'Unordered Collection',426=>'Upgrade Required',428=>'Precondition Required',429=>'Too Many Requests',431=>'Request Header Fields Too Large',444=>'No Response',449=>'Retry With',450=>'Blocked by Windows Parental Controls',451=>'Redirect',451=>'Unavailable For Legal Reasons',494=>'Request Header Too Large',495=>'Cert Error',496=>'No Cert',497=>'HTTP to HTTPS',499=>'Client Closed Request',500=>'Internal Server Error',501=>'Not Implemented',502=>'Bad Gateway',503=>'Service Unavailable',504=>'Gateway Timeout',505=>'HTTP Version Not Supported',506=>'Variant Also Negotiates',507=>'Insufficient Storage',508=>'Loop Detected',509=>'Bandwidth Limit Exceeded',510=>'Not Extended',511=>'Network Authentication Required',598=>'Network read timeout error',599=>'Network connect timeout error'];
+
+function start_webserver() {
+  $pid = pcntl_fork();
+  switch($pid) {
+    case -1:
+      die('Failed to fork webserver process');
+
+    case 0:
+      // exec the command
+      $HANDLER = getenv('_HANDLER');
+      chdir('/var/task');
+      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.3.d/:/var/task/php-7.3.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/modules '$HANDLER'");
+      exit;
+
+    // return the child pid to parent
+    default:
+      // Wait for child server to start
+      sleep(1);
+      return $pid;
+  }
+}
+
+function fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, $message) {
+  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
+
+  $response = array();
+
+  $response['statusCode'] = 500;
+  $response['body'] = $message;
+
+  $response_json = json_encode($response);
+
+  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
+  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
+  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+    'Content-Type: application/json',
+    'Content-Length: ' . strlen($response_json)
+  ));
+
+  curl_exec($ch);
+  curl_close($ch);
+}
+
+start_webserver();
+
+while (true) {
+  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/next");
+
+  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
+  curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
+
+  $invocation_id = '';
+
+  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$invocation_id) {
+    if (!preg_match('/:\s*/', $header)) {
+      return strlen($header);
+    }
+
+    [$name, $value] = preg_split('/:\s*/', $header, 2);
+
+    if (strtolower($name) == 'lambda-runtime-aws-request-id') {
+      $invocation_id = trim($value);
+    }
+
+    return strlen($header);
+  });
+
+  $body = '';
+
+  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$body) {
+    $body .= $chunk;
+
+    return strlen($chunk);
+  });
+
+  curl_exec($ch);
+
+  if (curl_error($ch)) {
+    die('Failed to fetch next Lambda invocation: ' . curl_error($ch) . "\n");
+  }
+
+  if ($invocation_id == '') {
+    die('Failed to determine Lambda invocation ID');
+  }
+
+  curl_close($ch);
+
+  if (!$body) {
+    die("Empty Lambda invocation response\n");
+  }
+
+  $event = json_decode($body, TRUE);
+
+  if (!array_key_exists('requestContext', $event)) {
+    fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, 'Event is not an API Gateway request');
+    continue;
+  }
+
+  $uri = $event['path'];
+
+  if (array_key_exists('multiValueQueryStringParameters', $event) && $event['multiValueQueryStringParameters']) {
+    $first = TRUE;
+    foreach ($event['multiValueQueryStringParameters'] as $name => $values) {
+      foreach ($values as $value) {
+        if ($first) {
+          $uri .= "?";
+          $first = FALSE;
+        } else {
+          $uri .= "&";
+        }
+
+        $uri .= $name;
+
+        if ($value != '') {
+          $uri .= '=' . $value;
+        }
+      }
+    }
+  }
+
+  $ch = curl_init("http://localhost:8000$uri");
+
+  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
+
+  if (array_key_exists('multiValueHeaders', $event)) {
+    $headers = array();
+
+    foreach ($event['multiValueHeaders'] as $name => $values) {
+      foreach ($values as $value) {
+        array_push($headers, "${name}: ${value}");
+      }
+    }
+
+    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+  }
+
+  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $event['httpMethod']);
+
+  if (array_key_exists('body', $event)) {
+    $body = $event['body'];
+    if (array_key_exists('isBase64Encoded', $event) && $event['isBase64Encoded']) {
+      $body = base64_decode($body);
+    }
+  } else {
+    $body = '';
+  }
+
+  if (strlen($body) > 0) {
+    if($event['httpMethod'] === 'POST'){
+      curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
+    }    
+    curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
+    curl_setopt($ch, CURLOPT_READFUNCTION, function ($ch, $fd, $length) use ($body) {
+      return $body;
+    });
+  }
+
+  $response = array();
+  $response['multiValueHeaders'] = array();
+  $response['body'] = '';
+
+  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$response) {
+    if (preg_match('/HTTP\/1.1 (\d+) .*/', $header, $matches)) {
+      $response['statusCode'] = intval($matches[1]);
+      return strlen($header);
+    }
+
+    if (!preg_match('/:\s*/', $header)) {
+      return strlen($header);
+    }
+
+    [$name, $value] = preg_split('/:\s*/', $header, 2);
+
+    $name = trim($name);
+    $value = trim($value);
+
+    if ($name == '') {
+      return strlen($header);
+    }
+
+    if (!array_key_exists($name, $response['multiValueHeaders'])) {
+      $response['multiValueHeaders'][$name] = array();
+    }
+
+    array_push($response['multiValueHeaders'][$name], $value);
+
+    return strlen($header);
+  });
+
+  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$response) {
+    $response['body'] .= $chunk;
+
+    return strlen($chunk);
+  });
+
+  curl_exec($ch);
+  curl_close($ch);
+
+  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
+
+  $isALB = array_key_exists("elb", $event['requestContext']);
+  if ($isALB) { // Add Headers For ALB
+    $status = $response["statusCode"];
+    if (array_key_exists($status, $http_codes)) {
+        $response["statusDescription"] = "$status ". $http_codes[$status];
+    } else {
+        $response["statusDescription"] = "$status Unknown";
+    }
+    $response["isBase64Encoded"] = false;
+  }
+  $response_json = json_encode($response);
+  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
+  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
+  if (!$isALB){
+    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+      'Content-Type: application/json',
+      'Content-Length: ' . strlen($response_json)
+    ));
+  }
+  curl_exec($ch);
+  curl_close($ch);
+}
+
+?>
diff --git a/build-php72.sh b/build-php72.sh
new file mode 100644
index 0000000..387ef8e
--- /dev/null
+++ b/build-php72.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+yum install -y wget
+yum install -y yum-utils
+wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
+wget https://rpms.remirepo.net/enterprise/remi-release-6.rpm
+rpm -Uvh remi-release-6.rpm
+rpm -Uvh epel-release-latest-6.noarch.rpm
+
+
+yum-config-manager --enable remi-php72
+
+yum install -y httpd
+yum install -y postgresql-devel
+yum install -y libargon2-devel
+
+yum install -y --disablerepo="*" --enablerepo="remi,remi-php72" php php-mbstring php-pdo php-mysql php-pgsql
+
+
+mkdir /tmp/layer
+cd /tmp/layer
+cp /opt/layer/bootstrap-php72 bootstrap
+cp /opt/layer/php72.ini php.ini
+
+mkdir bin
+cp /usr/bin/php bin/
+
+mkdir lib
+for lib in libncurses.so.5 libtinfo.so.5 libpcre.so.0; do
+  cp "/lib64/${lib}" lib/
+done
+
+cp /usr/lib64/libedit.so.0 lib/
+cp /usr/lib64/libargon2.so.0 lib/
+cp /usr/lib64/libpq.so.5 lib/
+
+cp -a /usr/lib64/php lib/
+
+zip -r /opt/layer/php72.zip .
+
diff --git a/build-php73.sh b/build-php73.sh
new file mode 100644
index 0000000..079816d
--- /dev/null
+++ b/build-php73.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+yum install -y wget
+yum install -y yum-utils
+wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
+wget https://rpms.remirepo.net/enterprise/remi-release-6.rpm
+rpm -Uvh remi-release-6.rpm
+rpm -Uvh epel-release-latest-6.noarch.rpm
+
+
+yum-config-manager --enable remi-php73
+
+yum install -y httpd
+yum install -y postgresql-devel
+yum install -y libargon2-devel
+
+yum install -y --disablerepo="*" --enablerepo="remi,remi-php73" php php-mbstring php-pdo php-mysql php-pgsql
+
+
+mkdir /tmp/layer
+cd /tmp/layer
+cp /opt/layer/bootstrap-php73 bootstrap
+cp /opt/layer/php73.ini php.ini
+
+mkdir bin
+cp /usr/bin/php bin/
+
+mkdir lib
+for lib in libncurses.so.5 libtinfo.so.5 libpcre.so.0; do
+  cp "/lib64/${lib}" lib/
+done
+
+cp /usr/lib64/libedit.so.0 lib/
+cp /usr/lib64/libargon2.so.0 lib/
+cp /usr/lib64/libpq.so.5 lib/
+
+cp -a /usr/lib64/php lib/
+
+zip -r /opt/layer/php73.zip .
+
diff --git a/build.sh b/build.sh
index a0da5b9..f1ef9f5 100755
--- a/build.sh
+++ b/build.sh
@@ -16,6 +16,7 @@ for lib in libncurses.so.5 libtinfo.so.5 libpcre.so.0; do
 done
 
 cp /usr/lib64/libedit.so.0 lib/
+cp /usr/lib64/libpq.so.5 lib/
 
 cp -a /usr/lib64/php lib/
 
diff --git a/php72.ini b/php72.ini
new file mode 100644
index 0000000..3b51503
--- /dev/null
+++ b/php72.ini
@@ -0,0 +1,4 @@
+extension_dir=/opt/lib/php/modules
+extension=curl.so
+extension=json.so
+display_errors=On
\ No newline at end of file
diff --git a/php73.ini b/php73.ini
new file mode 100644
index 0000000..3b51503
--- /dev/null
+++ b/php73.ini
@@ -0,0 +1,4 @@
+extension_dir=/opt/lib/php/modules
+extension=curl.so
+extension=json.so
+display_errors=On
\ No newline at end of file

From 7b6ea9a634d8cd207bd40fda7600964344d1b809 Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Wed, 16 Jan 2019 07:05:08 +0100
Subject: [PATCH 21/42] Added support for PHP 7.2 and 7.3

---
 php.ini   | 36 +++++++++++++++++++++++++++++++++++-
 php72.ini | 36 +++++++++++++++++++++++++++++++++++-
 php73.ini | 36 +++++++++++++++++++++++++++++++++++-
 3 files changed, 105 insertions(+), 3 deletions(-)

diff --git a/php.ini b/php.ini
index ce1c3ec..b81ef93 100644
--- a/php.ini
+++ b/php.ini
@@ -1,4 +1,38 @@
 extension_dir=/opt/lib/php/7.1/modules
+display_errors=On
+
+;extension=bz2.so
+;extension=calendar.so
+;extension=ctype.so
 extension=curl.so
+;extension=dom.so
+;extension=exif.so
+;extension=fileinfo.so
+;extension=ftp.so
+;extension=gettext.so
+;extension=iconv.so
 extension=json.so
-display_errors=On
\ No newline at end of file
+;extension=mbstring.so
+;extension=mysqli.so
+;extension=mysqlnd.so
+;extension=pdo.so
+;extension=pdo_mysql.so
+;extension=pdo_pgsql.so
+;extension=pdo_sqlite.so
+;extension=pgsql.so
+;extension=phar.so
+;extension=posix.so
+;extension=shmop.so
+;extension=simplexml.so
+;extension=sockets.so
+;extension=sqlite3.so
+;extension=sysvmsg.so
+;extension=sysvsem.so
+;extension=sysvshm.so
+;extension=tokenizer.so
+;extension=wddx.so
+;extension=xml.so
+;extension=xmlreader.so
+;extension=xmlwriter.so
+;extension=xsl.so
+;extension=zip.so
diff --git a/php72.ini b/php72.ini
index 3b51503..a2f7c65 100644
--- a/php72.ini
+++ b/php72.ini
@@ -1,4 +1,38 @@
 extension_dir=/opt/lib/php/modules
+display_errors=On
+
+;extension=bz2.so
+;extension=calendar.so
+;extension=ctype.so
 extension=curl.so
+;extension=dom.so
+;extension=exif.so
+;extension=fileinfo.so
+;extension=ftp.so
+;extension=gettext.so
+;extension=iconv.so
 extension=json.so
-display_errors=On
\ No newline at end of file
+;extension=mbstring.so
+;extension=mysqli.so
+;extension=mysqlnd.so
+;extension=pdo.so
+;extension=pdo_mysql.so
+;extension=pdo_pgsql.so
+;extension=pdo_sqlite.so
+;extension=pgsql.so
+;extension=phar.so
+;extension=posix.so
+;extension=shmop.so
+;extension=simplexml.so
+;extension=sockets.so
+;extension=sqlite3.so
+;extension=sysvmsg.so
+;extension=sysvsem.so
+;extension=sysvshm.so
+;extension=tokenizer.so
+;extension=wddx.so
+;extension=xml.so
+;extension=xmlreader.so
+;extension=xmlwriter.so
+;extension=xsl.so
+;extension=zip.so
diff --git a/php73.ini b/php73.ini
index 3b51503..a2f7c65 100644
--- a/php73.ini
+++ b/php73.ini
@@ -1,4 +1,38 @@
 extension_dir=/opt/lib/php/modules
+display_errors=On
+
+;extension=bz2.so
+;extension=calendar.so
+;extension=ctype.so
 extension=curl.so
+;extension=dom.so
+;extension=exif.so
+;extension=fileinfo.so
+;extension=ftp.so
+;extension=gettext.so
+;extension=iconv.so
 extension=json.so
-display_errors=On
\ No newline at end of file
+;extension=mbstring.so
+;extension=mysqli.so
+;extension=mysqlnd.so
+;extension=pdo.so
+;extension=pdo_mysql.so
+;extension=pdo_pgsql.so
+;extension=pdo_sqlite.so
+;extension=pgsql.so
+;extension=phar.so
+;extension=posix.so
+;extension=shmop.so
+;extension=simplexml.so
+;extension=sockets.so
+;extension=sqlite3.so
+;extension=sysvmsg.so
+;extension=sysvsem.so
+;extension=sysvshm.so
+;extension=tokenizer.so
+;extension=wddx.so
+;extension=xml.so
+;extension=xmlreader.so
+;extension=xmlwriter.so
+;extension=xsl.so
+;extension=zip.so

From 557cbe42def3242745b5a61460ce6ceaccdea11c Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Fri, 1 Feb 2019 07:50:21 +0100
Subject: [PATCH 22/42] Files for PHP 7.2 and 7.3 have been merged together

---
 Makefile                            |   4 +-
 README.md                           |  60 ++++---
 bootstrap                           |   3 +-
 bootstrap-php72                     | 235 ----------------------------
 bootstrap-php73                     | 235 ----------------------------
 build-php72.sh => build-php-remi.sh |  17 +-
 build-php73.sh                      |  40 -----
 php.ini                             |  35 +----
 php72.ini                           |  38 -----
 php73.ini                           |  38 -----
 tmp/test/due                        |   0
 tmp/test/uno                        |   0
 12 files changed, 50 insertions(+), 655 deletions(-)
 delete mode 100644 bootstrap-php72
 delete mode 100644 bootstrap-php73
 rename build-php72.sh => build-php-remi.sh (53%)
 delete mode 100644 build-php73.sh
 delete mode 100644 php72.ini
 delete mode 100644 php73.ini
 create mode 100644 tmp/test/due
 create mode 100644 tmp/test/uno

diff --git a/Makefile b/Makefile
index 269a84f..fc8714e 100644
--- a/Makefile
+++ b/Makefile
@@ -4,10 +4,10 @@ php71.zip:
 	docker run --rm -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build.sh
 
 php72.zip:
-	docker run --rm -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php72.sh
+	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php-remi.sh 2
 
 php73.zip:
-	docker run --rm -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php73.sh
+	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php-remi.sh 3
 
 upload: php71.zip
 	./upload.sh
diff --git a/README.md b/README.md
index b60f70b..fe97169 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,20 @@
 # PHP Layer For AWS Lambda
 
-Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.1/7.2/7.3 webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) or [AWS Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/features/#Details_for_Elastic_Load_Balancing_Products) requests.
+Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.1/7.2/7.3  webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) or [AWS Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/features/#Details_for_Elastic_Load_Balancing_Products) requests.
 
-This project is fork of the [Stackery](https://stackery.io) [php-lambda-layer](https://github.com/stackery/php-lambda-layer) that has been modified to:
+And, if you're looking for a great way to build serverless apps of all kinds, be sure to check out [Stackery](https://stackery.io)!
 
-- support PHP 7.1, 7.2, and 7.3 (the original supports 7.1 only) - using the [Remi RPM Repository](https://rpms.remirepo.net/)
-- add support for mbstring, MySQL (pdo-mysql) and Postgres (pdo-pgsql)
+This is an early iteration of the PHP runtime Layer which is not yet ready for production. Please feel free to use this Layer to learn about the Lambda Layers feature and begin experimenting with PHP functions. We welcome feedback and stay tuned for the production-ready version coming soon.
 
-that are requirements for running frameworks such as [Lumen](https://lumen.laravel.com/) and [Laravel](https://laravel.com/) frameworks in serverless mode.
+## Current Layer Version ARN
+When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARN for PHP 7.1 is:
 
-This is an early iteration of the PHP runtime Layer which is not yet ready for production. Please feel free to use this Layer to learn about the Lambda Layers feature and begin experimenting with PHP functions. We welcome feedback and stay tuned for the production-ready version coming soon.
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:7**
+
+If you need a layer for PHP 7.2 or 7.3, you can build your own.
+You can find an example [here](http://tinyurl.com/ycsbfpbr).
+
+See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
 ### Usage
 #### General Usage
@@ -24,14 +29,14 @@ The Lambda Function Handler property specifies the location of the the script ex
 #### Configuration Files
 There are three locations where PHP configuration may be located:
 
-* Files in layer code packages located under /etc/php-<PHP_VERSION>.d/
-* Files in function code package located under /php-<PHP_VERSION>.d/
+* Files in layer code packages located under /etc/php-${PHP_VERSION}.d/
+* Files in function code package located under /php-${PHP_VERSION}.d/
 * php.ini located at the root of the function code package
 
-Replace <PHP_VERSION> with 7.1, 7.2, or 7.3 according to your preferred runtime.
+Replace ${PHP_VERSION} with '7.1', '7.2', or '7.3' according to your preferred runtime.
 
 ##### Extensions
-The following extensions are built into the layer and available in /opt/lib/php/7.1/modules (PHP 7.1) or /opt/lib/php/modules (PHP 7.2/7.3):
+The following extensions are built into the layer and available in /opt/lib/php/${PHP_VERSION}/modules:
 
 ```
 bz2.so
@@ -45,20 +50,11 @@ ftp.so
 gettext.so
 iconv.so
 json.so
-mbstring.so
-mysqli.so
-mysqlnd.so
-pdo.so
-pdo_mysql.so
-pdo_pgsql.so
-pdo_sqlite.so
-pgsql.so
 phar.so
 posix.so
 shmop.so
 simplexml.so
 sockets.so
-sqlite3.so
 sysvmsg.so
 sysvsem.so
 sysvshm.so
@@ -77,7 +73,7 @@ These extensions are not loaded by default. You must add the extension to a php.
 extension=json.so
 ```
 
-Extensions can be built using the lambci/lambda:build-nodejs8.10 Docker image. It is recommended that custom extensions be provided by a separate Lambda Layer with the extension .so files placed in /lib/php/7.1/modules/ so they can be loaded alongside the built-in extensions listed above.
+Extensions can be built using the lambci/lambda:build-nodejs8.10 Docker image. It is recommended that custom extensions be provided by a separate Lambda Layer with the extension .so files placed in /lib/php/${PHP_VERSION}/modules/ so they can be loaded alongside the built-in extensions listed above.
 
 #### SAM Example
 Let's create an AWS SAM PHP application. We suggest using [Stackery](https://stackery.io) to make this super simple. It automates all the scaffolding shown below. But you may also choose to roll your own application from scratch.
@@ -110,7 +106,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:6
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:7
       Events:
         api:
           Type: Api
@@ -154,22 +150,34 @@ $ sam deploy \
 Build the layer by:
 
 1. Installing a Docker environment
-2. Running `make`
+1. Running `make`
 
-This will launch a Docker container that will build php71.zip, based on PHP 7.1 (default).
+This will launch a Docker container that will build php71.zip.
 
 You can run `make php72.zip` and `make php73.zip` to create a layer that is based on PHP 7.2/7.3.
 
+If you are behind a proxy server, just set the environment variable `http_proxy` before
+invoking `make`, eg.:
+
+```sh
+	$ export http_proyx=http://myproxy.acme.com:8080
+	$ make php73.zip
+```
+
 ### Debugging
 
 Run:
 
+```sh
 	$ docker run --rm -it -v `pwd`:/opt/layer lambci/lambda:build-nodejs8.10 /bin/bash
-	
+```
+
 If you are on Windows, run this instead:
 
+```sh
 	> docker run --rm -it -v %cd%:/opt/layer lambci/lambda:build-nodejs8.10 /bin/bash
-	
+```
+
 and execute manually the commands in the build.sh file.
 
 ### Disclaimer
@@ -185,4 +193,4 @@ and execute manually the commands in the build.sh file.
 > HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 > STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 > ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-> OF THE POSSIBILITY OF SUCH DAMAGE.
+> OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/bootstrap b/bootstrap
index 73cce3f..c6f4d53 100755
--- a/bootstrap
+++ b/bootstrap
@@ -18,7 +18,8 @@ function start_webserver() {
       // exec the command
       $HANDLER = getenv('_HANDLER');
       chdir('/var/task');
-      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.1.d/:/var/task/php-7.1.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.1/modules '$HANDLER'");
+	  $phpMinorVersion = PHP_MINOR_VERSION;
+      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.${phpMinorVersion}.d/:/var/task/php-7.${phpMinorVersion}.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.${phpMinorVersion}/modules '$HANDLER'");
       exit;
 
     // return the child pid to parent
diff --git a/bootstrap-php72 b/bootstrap-php72
deleted file mode 100644
index 3abb20a..0000000
--- a/bootstrap-php72
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/opt/bin/php -c/opt/php.ini
-<?php
-
-error_reporting(E_ALL | E_STRICT);
-
-$AWS_LAMBDA_RUNTIME_API = getenv('AWS_LAMBDA_RUNTIME_API');
-
-/* https://gist.github.com/henriquemoody/6580488 */
-$http_codes = [100=>'Continue',101=>'Switching Protocols',102=>'Processing',200=>'OK',201=>'Created',202=>'Accepted',203=>'Non-Authoritative Information',204=>'No Content',205=>'Reset Content',206=>'Partial Content',207=>'Multi-Status',208=>'Already Reported',226=>'IM Used',300=>'Multiple Choices',301=>'Moved Permanently',302=>'Found',303=>'See Other',304=>'Not Modified',305=>'Use Proxy',306=>'Switch Proxy',307=>'Temporary Redirect',308=>'Permanent Redirect',400=>'Bad Request',401=>'Unauthorized',402=>'Payment Required',403=>'Forbidden',404=>'Not Found',405=>'Method Not Allowed',406=>'Not Acceptable',407=>'Proxy Authentication Required',408=>'Request Timeout',409=>'Conflict',410=>'Gone',411=>'Length Required',412=>'Precondition Failed',413=>'Request Entity Too Large',414=>'Request-URI Too Long',415=>'Unsupported Media Type',416=>'Requested Range Not Satisfiable',417=>'Expectation Failed',418=>'I\'m a teapot',419=>'Authentication Timeout',420=>'Enhance Your Calm',420=>'Method Failure',422=>'Unprocessable Entity',423=>'Locked',424=>'Failed Dependency',424=>'Method Failure',425=>'Unordered Collection',426=>'Upgrade Required',428=>'Precondition Required',429=>'Too Many Requests',431=>'Request Header Fields Too Large',444=>'No Response',449=>'Retry With',450=>'Blocked by Windows Parental Controls',451=>'Redirect',451=>'Unavailable For Legal Reasons',494=>'Request Header Too Large',495=>'Cert Error',496=>'No Cert',497=>'HTTP to HTTPS',499=>'Client Closed Request',500=>'Internal Server Error',501=>'Not Implemented',502=>'Bad Gateway',503=>'Service Unavailable',504=>'Gateway Timeout',505=>'HTTP Version Not Supported',506=>'Variant Also Negotiates',507=>'Insufficient Storage',508=>'Loop Detected',509=>'Bandwidth Limit Exceeded',510=>'Not Extended',511=>'Network Authentication Required',598=>'Network read timeout error',599=>'Network connect timeout error'];
-
-function start_webserver() {
-  $pid = pcntl_fork();
-  switch($pid) {
-    case -1:
-      die('Failed to fork webserver process');
-
-    case 0:
-      // exec the command
-      $HANDLER = getenv('_HANDLER');
-      chdir('/var/task');
-      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.2.d/:/var/task/php-7.2.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/modules '$HANDLER'");
-      exit;
-
-    // return the child pid to parent
-    default:
-      // Wait for child server to start
-      sleep(1);
-      return $pid;
-  }
-}
-
-function fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, $message) {
-  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
-
-  $response = array();
-
-  $response['statusCode'] = 500;
-  $response['body'] = $message;
-
-  $response_json = json_encode($response);
-
-  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
-  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
-  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
-  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
-    'Content-Type: application/json',
-    'Content-Length: ' . strlen($response_json)
-  ));
-
-  curl_exec($ch);
-  curl_close($ch);
-}
-
-start_webserver();
-
-while (true) {
-  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/next");
-
-  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
-  curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
-
-  $invocation_id = '';
-
-  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$invocation_id) {
-    if (!preg_match('/:\s*/', $header)) {
-      return strlen($header);
-    }
-
-    [$name, $value] = preg_split('/:\s*/', $header, 2);
-
-    if (strtolower($name) == 'lambda-runtime-aws-request-id') {
-      $invocation_id = trim($value);
-    }
-
-    return strlen($header);
-  });
-
-  $body = '';
-
-  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$body) {
-    $body .= $chunk;
-
-    return strlen($chunk);
-  });
-
-  curl_exec($ch);
-
-  if (curl_error($ch)) {
-    die('Failed to fetch next Lambda invocation: ' . curl_error($ch) . "\n");
-  }
-
-  if ($invocation_id == '') {
-    die('Failed to determine Lambda invocation ID');
-  }
-
-  curl_close($ch);
-
-  if (!$body) {
-    die("Empty Lambda invocation response\n");
-  }
-
-  $event = json_decode($body, TRUE);
-
-  if (!array_key_exists('requestContext', $event)) {
-    fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, 'Event is not an API Gateway request');
-    continue;
-  }
-
-  $uri = $event['path'];
-
-  if (array_key_exists('multiValueQueryStringParameters', $event) && $event['multiValueQueryStringParameters']) {
-    $first = TRUE;
-    foreach ($event['multiValueQueryStringParameters'] as $name => $values) {
-      foreach ($values as $value) {
-        if ($first) {
-          $uri .= "?";
-          $first = FALSE;
-        } else {
-          $uri .= "&";
-        }
-
-        $uri .= $name;
-
-        if ($value != '') {
-          $uri .= '=' . $value;
-        }
-      }
-    }
-  }
-
-  $ch = curl_init("http://localhost:8000$uri");
-
-  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
-
-  if (array_key_exists('multiValueHeaders', $event)) {
-    $headers = array();
-
-    foreach ($event['multiValueHeaders'] as $name => $values) {
-      foreach ($values as $value) {
-        array_push($headers, "${name}: ${value}");
-      }
-    }
-
-    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
-  }
-
-  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $event['httpMethod']);
-
-  if (array_key_exists('body', $event)) {
-    $body = $event['body'];
-    if (array_key_exists('isBase64Encoded', $event) && $event['isBase64Encoded']) {
-      $body = base64_decode($body);
-    }
-  } else {
-    $body = '';
-  }
-
-  if (strlen($body) > 0) {
-    if($event['httpMethod'] === 'POST'){
-      curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
-    }    
-    curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
-    curl_setopt($ch, CURLOPT_READFUNCTION, function ($ch, $fd, $length) use ($body) {
-      return $body;
-    });
-  }
-
-  $response = array();
-  $response['multiValueHeaders'] = array();
-  $response['body'] = '';
-
-  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$response) {
-    if (preg_match('/HTTP\/1.1 (\d+) .*/', $header, $matches)) {
-      $response['statusCode'] = intval($matches[1]);
-      return strlen($header);
-    }
-
-    if (!preg_match('/:\s*/', $header)) {
-      return strlen($header);
-    }
-
-    [$name, $value] = preg_split('/:\s*/', $header, 2);
-
-    $name = trim($name);
-    $value = trim($value);
-
-    if ($name == '') {
-      return strlen($header);
-    }
-
-    if (!array_key_exists($name, $response['multiValueHeaders'])) {
-      $response['multiValueHeaders'][$name] = array();
-    }
-
-    array_push($response['multiValueHeaders'][$name], $value);
-
-    return strlen($header);
-  });
-
-  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$response) {
-    $response['body'] .= $chunk;
-
-    return strlen($chunk);
-  });
-
-  curl_exec($ch);
-  curl_close($ch);
-
-  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
-
-  $isALB = array_key_exists("elb", $event['requestContext']);
-  if ($isALB) { // Add Headers For ALB
-    $status = $response["statusCode"];
-    if (array_key_exists($status, $http_codes)) {
-        $response["statusDescription"] = "$status ". $http_codes[$status];
-    } else {
-        $response["statusDescription"] = "$status Unknown";
-    }
-    $response["isBase64Encoded"] = false;
-  }
-  $response_json = json_encode($response);
-  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
-  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
-  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
-  if (!$isALB){
-    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
-      'Content-Type: application/json',
-      'Content-Length: ' . strlen($response_json)
-    ));
-  }
-  curl_exec($ch);
-  curl_close($ch);
-}
-
-?>
diff --git a/bootstrap-php73 b/bootstrap-php73
deleted file mode 100644
index 2d7ae93..0000000
--- a/bootstrap-php73
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/opt/bin/php -c/opt/php.ini
-<?php
-
-error_reporting(E_ALL | E_STRICT);
-
-$AWS_LAMBDA_RUNTIME_API = getenv('AWS_LAMBDA_RUNTIME_API');
-
-/* https://gist.github.com/henriquemoody/6580488 */
-$http_codes = [100=>'Continue',101=>'Switching Protocols',102=>'Processing',200=>'OK',201=>'Created',202=>'Accepted',203=>'Non-Authoritative Information',204=>'No Content',205=>'Reset Content',206=>'Partial Content',207=>'Multi-Status',208=>'Already Reported',226=>'IM Used',300=>'Multiple Choices',301=>'Moved Permanently',302=>'Found',303=>'See Other',304=>'Not Modified',305=>'Use Proxy',306=>'Switch Proxy',307=>'Temporary Redirect',308=>'Permanent Redirect',400=>'Bad Request',401=>'Unauthorized',402=>'Payment Required',403=>'Forbidden',404=>'Not Found',405=>'Method Not Allowed',406=>'Not Acceptable',407=>'Proxy Authentication Required',408=>'Request Timeout',409=>'Conflict',410=>'Gone',411=>'Length Required',412=>'Precondition Failed',413=>'Request Entity Too Large',414=>'Request-URI Too Long',415=>'Unsupported Media Type',416=>'Requested Range Not Satisfiable',417=>'Expectation Failed',418=>'I\'m a teapot',419=>'Authentication Timeout',420=>'Enhance Your Calm',420=>'Method Failure',422=>'Unprocessable Entity',423=>'Locked',424=>'Failed Dependency',424=>'Method Failure',425=>'Unordered Collection',426=>'Upgrade Required',428=>'Precondition Required',429=>'Too Many Requests',431=>'Request Header Fields Too Large',444=>'No Response',449=>'Retry With',450=>'Blocked by Windows Parental Controls',451=>'Redirect',451=>'Unavailable For Legal Reasons',494=>'Request Header Too Large',495=>'Cert Error',496=>'No Cert',497=>'HTTP to HTTPS',499=>'Client Closed Request',500=>'Internal Server Error',501=>'Not Implemented',502=>'Bad Gateway',503=>'Service Unavailable',504=>'Gateway Timeout',505=>'HTTP Version Not Supported',506=>'Variant Also Negotiates',507=>'Insufficient Storage',508=>'Loop Detected',509=>'Bandwidth Limit Exceeded',510=>'Not Extended',511=>'Network Authentication Required',598=>'Network read timeout error',599=>'Network connect timeout error'];
-
-function start_webserver() {
-  $pid = pcntl_fork();
-  switch($pid) {
-    case -1:
-      die('Failed to fork webserver process');
-
-    case 0:
-      // exec the command
-      $HANDLER = getenv('_HANDLER');
-      chdir('/var/task');
-      exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.3.d/:/var/task/php-7.3.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/modules '$HANDLER'");
-      exit;
-
-    // return the child pid to parent
-    default:
-      // Wait for child server to start
-      sleep(1);
-      return $pid;
-  }
-}
-
-function fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, $message) {
-  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
-
-  $response = array();
-
-  $response['statusCode'] = 500;
-  $response['body'] = $message;
-
-  $response_json = json_encode($response);
-
-  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
-  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
-  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
-  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
-    'Content-Type: application/json',
-    'Content-Length: ' . strlen($response_json)
-  ));
-
-  curl_exec($ch);
-  curl_close($ch);
-}
-
-start_webserver();
-
-while (true) {
-  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/next");
-
-  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
-  curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
-
-  $invocation_id = '';
-
-  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$invocation_id) {
-    if (!preg_match('/:\s*/', $header)) {
-      return strlen($header);
-    }
-
-    [$name, $value] = preg_split('/:\s*/', $header, 2);
-
-    if (strtolower($name) == 'lambda-runtime-aws-request-id') {
-      $invocation_id = trim($value);
-    }
-
-    return strlen($header);
-  });
-
-  $body = '';
-
-  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$body) {
-    $body .= $chunk;
-
-    return strlen($chunk);
-  });
-
-  curl_exec($ch);
-
-  if (curl_error($ch)) {
-    die('Failed to fetch next Lambda invocation: ' . curl_error($ch) . "\n");
-  }
-
-  if ($invocation_id == '') {
-    die('Failed to determine Lambda invocation ID');
-  }
-
-  curl_close($ch);
-
-  if (!$body) {
-    die("Empty Lambda invocation response\n");
-  }
-
-  $event = json_decode($body, TRUE);
-
-  if (!array_key_exists('requestContext', $event)) {
-    fail($AWS_LAMBDA_RUNTIME_API, $invocation_id, 'Event is not an API Gateway request');
-    continue;
-  }
-
-  $uri = $event['path'];
-
-  if (array_key_exists('multiValueQueryStringParameters', $event) && $event['multiValueQueryStringParameters']) {
-    $first = TRUE;
-    foreach ($event['multiValueQueryStringParameters'] as $name => $values) {
-      foreach ($values as $value) {
-        if ($first) {
-          $uri .= "?";
-          $first = FALSE;
-        } else {
-          $uri .= "&";
-        }
-
-        $uri .= $name;
-
-        if ($value != '') {
-          $uri .= '=' . $value;
-        }
-      }
-    }
-  }
-
-  $ch = curl_init("http://localhost:8000$uri");
-
-  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
-
-  if (array_key_exists('multiValueHeaders', $event)) {
-    $headers = array();
-
-    foreach ($event['multiValueHeaders'] as $name => $values) {
-      foreach ($values as $value) {
-        array_push($headers, "${name}: ${value}");
-      }
-    }
-
-    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
-  }
-
-  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $event['httpMethod']);
-
-  if (array_key_exists('body', $event)) {
-    $body = $event['body'];
-    if (array_key_exists('isBase64Encoded', $event) && $event['isBase64Encoded']) {
-      $body = base64_decode($body);
-    }
-  } else {
-    $body = '';
-  }
-
-  if (strlen($body) > 0) {
-    if($event['httpMethod'] === 'POST'){
-      curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
-    }    
-    curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
-    curl_setopt($ch, CURLOPT_READFUNCTION, function ($ch, $fd, $length) use ($body) {
-      return $body;
-    });
-  }
-
-  $response = array();
-  $response['multiValueHeaders'] = array();
-  $response['body'] = '';
-
-  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$response) {
-    if (preg_match('/HTTP\/1.1 (\d+) .*/', $header, $matches)) {
-      $response['statusCode'] = intval($matches[1]);
-      return strlen($header);
-    }
-
-    if (!preg_match('/:\s*/', $header)) {
-      return strlen($header);
-    }
-
-    [$name, $value] = preg_split('/:\s*/', $header, 2);
-
-    $name = trim($name);
-    $value = trim($value);
-
-    if ($name == '') {
-      return strlen($header);
-    }
-
-    if (!array_key_exists($name, $response['multiValueHeaders'])) {
-      $response['multiValueHeaders'][$name] = array();
-    }
-
-    array_push($response['multiValueHeaders'][$name], $value);
-
-    return strlen($header);
-  });
-
-  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$response) {
-    $response['body'] .= $chunk;
-
-    return strlen($chunk);
-  });
-
-  curl_exec($ch);
-  curl_close($ch);
-
-  $ch = curl_init("http://$AWS_LAMBDA_RUNTIME_API/2018-06-01/runtime/invocation/$invocation_id/response");
-
-  $isALB = array_key_exists("elb", $event['requestContext']);
-  if ($isALB) { // Add Headers For ALB
-    $status = $response["statusCode"];
-    if (array_key_exists($status, $http_codes)) {
-        $response["statusDescription"] = "$status ". $http_codes[$status];
-    } else {
-        $response["statusDescription"] = "$status Unknown";
-    }
-    $response["isBase64Encoded"] = false;
-  }
-  $response_json = json_encode($response);
-  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
-  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
-  curl_setopt($ch, CURLOPT_POSTFIELDS, $response_json);
-  if (!$isALB){
-    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
-      'Content-Type: application/json',
-      'Content-Length: ' . strlen($response_json)
-    ));
-  }
-  curl_exec($ch);
-  curl_close($ch);
-}
-
-?>
diff --git a/build-php72.sh b/build-php-remi.sh
similarity index 53%
rename from build-php72.sh
rename to build-php-remi.sh
index 387ef8e..c0d0ee0 100644
--- a/build-php72.sh
+++ b/build-php-remi.sh
@@ -1,5 +1,9 @@
 #!/bin/bash
 
+PHP_MINOR_VERSION=$1
+
+echo "Building layer for PHP 7.$PHP_MINOR_VERSION - using Remi repository"
+
 yum install -y wget
 yum install -y yum-utils
 wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
@@ -8,19 +12,19 @@ rpm -Uvh remi-release-6.rpm
 rpm -Uvh epel-release-latest-6.noarch.rpm
 
 
-yum-config-manager --enable remi-php72
+yum-config-manager --enable remi-php7${PHP_MINOR_VERSION}
 
 yum install -y httpd
 yum install -y postgresql-devel
 yum install -y libargon2-devel
 
-yum install -y --disablerepo="*" --enablerepo="remi,remi-php72" php php-mbstring php-pdo php-mysql php-pgsql
+yum install -y --disablerepo="*" --enablerepo="remi,remi-php7${PHP_MINOR_VERSION}" php php-mbstring php-pdo php-mysql php-pgsql
 
 
 mkdir /tmp/layer
 cd /tmp/layer
-cp /opt/layer/bootstrap-php72 bootstrap
-cp /opt/layer/php72.ini php.ini
+cp /opt/layer/bootstrap bootstrap
+sed "s/PHP_MINOR_VERSION/${PHP_MINOR_VERSION}/g" /opt/layer/php.ini >php.ini
 
 mkdir bin
 cp /usr/bin/php bin/
@@ -34,7 +38,8 @@ cp /usr/lib64/libedit.so.0 lib/
 cp /usr/lib64/libargon2.so.0 lib/
 cp /usr/lib64/libpq.so.5 lib/
 
-cp -a /usr/lib64/php lib/
+mkdir -p lib/php/7.${PHP_MINOR_VERSION}
+cp -a /usr/lib64/php/modules lib/php/7.${PHP_MINOR_VERSION}/
 
-zip -r /opt/layer/php72.zip .
+zip -r /opt/layer/php7${PHP_MINOR_VERSION}.zip .
 
diff --git a/build-php73.sh b/build-php73.sh
deleted file mode 100644
index 079816d..0000000
--- a/build-php73.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-
-yum install -y wget
-yum install -y yum-utils
-wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
-wget https://rpms.remirepo.net/enterprise/remi-release-6.rpm
-rpm -Uvh remi-release-6.rpm
-rpm -Uvh epel-release-latest-6.noarch.rpm
-
-
-yum-config-manager --enable remi-php73
-
-yum install -y httpd
-yum install -y postgresql-devel
-yum install -y libargon2-devel
-
-yum install -y --disablerepo="*" --enablerepo="remi,remi-php73" php php-mbstring php-pdo php-mysql php-pgsql
-
-
-mkdir /tmp/layer
-cd /tmp/layer
-cp /opt/layer/bootstrap-php73 bootstrap
-cp /opt/layer/php73.ini php.ini
-
-mkdir bin
-cp /usr/bin/php bin/
-
-mkdir lib
-for lib in libncurses.so.5 libtinfo.so.5 libpcre.so.0; do
-  cp "/lib64/${lib}" lib/
-done
-
-cp /usr/lib64/libedit.so.0 lib/
-cp /usr/lib64/libargon2.so.0 lib/
-cp /usr/lib64/libpq.so.5 lib/
-
-cp -a /usr/lib64/php lib/
-
-zip -r /opt/layer/php73.zip .
-
diff --git a/php.ini b/php.ini
index b81ef93..2f19388 100644
--- a/php.ini
+++ b/php.ini
@@ -1,38 +1,5 @@
-extension_dir=/opt/lib/php/7.1/modules
+extension_dir=/opt/lib/php/7.PHP_MINOR_VERSION/modules
 display_errors=On
 
-;extension=bz2.so
-;extension=calendar.so
-;extension=ctype.so
 extension=curl.so
-;extension=dom.so
-;extension=exif.so
-;extension=fileinfo.so
-;extension=ftp.so
-;extension=gettext.so
-;extension=iconv.so
 extension=json.so
-;extension=mbstring.so
-;extension=mysqli.so
-;extension=mysqlnd.so
-;extension=pdo.so
-;extension=pdo_mysql.so
-;extension=pdo_pgsql.so
-;extension=pdo_sqlite.so
-;extension=pgsql.so
-;extension=phar.so
-;extension=posix.so
-;extension=shmop.so
-;extension=simplexml.so
-;extension=sockets.so
-;extension=sqlite3.so
-;extension=sysvmsg.so
-;extension=sysvsem.so
-;extension=sysvshm.so
-;extension=tokenizer.so
-;extension=wddx.so
-;extension=xml.so
-;extension=xmlreader.so
-;extension=xmlwriter.so
-;extension=xsl.so
-;extension=zip.so
diff --git a/php72.ini b/php72.ini
deleted file mode 100644
index a2f7c65..0000000
--- a/php72.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-extension_dir=/opt/lib/php/modules
-display_errors=On
-
-;extension=bz2.so
-;extension=calendar.so
-;extension=ctype.so
-extension=curl.so
-;extension=dom.so
-;extension=exif.so
-;extension=fileinfo.so
-;extension=ftp.so
-;extension=gettext.so
-;extension=iconv.so
-extension=json.so
-;extension=mbstring.so
-;extension=mysqli.so
-;extension=mysqlnd.so
-;extension=pdo.so
-;extension=pdo_mysql.so
-;extension=pdo_pgsql.so
-;extension=pdo_sqlite.so
-;extension=pgsql.so
-;extension=phar.so
-;extension=posix.so
-;extension=shmop.so
-;extension=simplexml.so
-;extension=sockets.so
-;extension=sqlite3.so
-;extension=sysvmsg.so
-;extension=sysvsem.so
-;extension=sysvshm.so
-;extension=tokenizer.so
-;extension=wddx.so
-;extension=xml.so
-;extension=xmlreader.so
-;extension=xmlwriter.so
-;extension=xsl.so
-;extension=zip.so
diff --git a/php73.ini b/php73.ini
deleted file mode 100644
index a2f7c65..0000000
--- a/php73.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-extension_dir=/opt/lib/php/modules
-display_errors=On
-
-;extension=bz2.so
-;extension=calendar.so
-;extension=ctype.so
-extension=curl.so
-;extension=dom.so
-;extension=exif.so
-;extension=fileinfo.so
-;extension=ftp.so
-;extension=gettext.so
-;extension=iconv.so
-extension=json.so
-;extension=mbstring.so
-;extension=mysqli.so
-;extension=mysqlnd.so
-;extension=pdo.so
-;extension=pdo_mysql.so
-;extension=pdo_pgsql.so
-;extension=pdo_sqlite.so
-;extension=pgsql.so
-;extension=phar.so
-;extension=posix.so
-;extension=shmop.so
-;extension=simplexml.so
-;extension=sockets.so
-;extension=sqlite3.so
-;extension=sysvmsg.so
-;extension=sysvsem.so
-;extension=sysvshm.so
-;extension=tokenizer.so
-;extension=wddx.so
-;extension=xml.so
-;extension=xmlreader.so
-;extension=xmlwriter.so
-;extension=xsl.so
-;extension=zip.so
diff --git a/tmp/test/due b/tmp/test/due
new file mode 100644
index 0000000..e69de29
diff --git a/tmp/test/uno b/tmp/test/uno
new file mode 100644
index 0000000..e69de29

From be24d6f54907f313ef66c9f056074fbcb14e4651 Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Fri, 1 Feb 2019 07:54:04 +0100
Subject: [PATCH 23/42] removed test files

---
 tmp/test/due | 0
 tmp/test/uno | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 tmp/test/due
 delete mode 100644 tmp/test/uno

diff --git a/tmp/test/due b/tmp/test/due
deleted file mode 100644
index e69de29..0000000
diff --git a/tmp/test/uno b/tmp/test/uno
deleted file mode 100644
index e69de29..0000000

From 3e6f2d8ba0e9c07b8fe45cdb48c5275df84b878a Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Fri, 1 Feb 2019 08:24:17 +0100
Subject: [PATCH 24/42] minor changes

---
 bootstrap | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bootstrap b/bootstrap
index c6f4d53..527a1df 100755
--- a/bootstrap
+++ b/bootstrap
@@ -18,7 +18,7 @@ function start_webserver() {
       // exec the command
       $HANDLER = getenv('_HANDLER');
       chdir('/var/task');
-	  $phpMinorVersion = PHP_MINOR_VERSION;
+      $phpMinorVersion = PHP_MINOR_VERSION;
       exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.${phpMinorVersion}.d/:/var/task/php-7.${phpMinorVersion}.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.${phpMinorVersion}/modules '$HANDLER'");
       exit;
 

From 064470715a526bc65f0a870a5e412e39be58874f Mon Sep 17 00:00:00 2001
From: Pietro Iglio <igliop@gmail.com>
Date: Fri, 1 Feb 2019 08:25:13 +0100
Subject: [PATCH 25/42] minor changes

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index fc8714e..9d4e5ce 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
 
 php71.zip:
-	docker run --rm -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build.sh
+	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build.sh
 
 php72.zip:
 	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php-remi.sh 2

From 68fd9c55ed03336a73aa1f023443b2572ff59a49 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 5 Feb 2019 14:42:35 -0800
Subject: [PATCH 26/42] Update deployment scripts for multiple PHP version
 layers

---
 publish.sh   | 21 ++++++++++++---------
 regions.sh   |  2 +-
 unpublish.sh | 16 +++++++++-------
 upload.sh    | 13 ++++++++-----
 4 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/publish.sh b/publish.sh
index 1f91f7d..78b3575 100755
--- a/publish.sh
+++ b/publish.sh
@@ -2,18 +2,21 @@
 
 source regions.sh
 
-MD5SUM=$(md5 -q php71.zip)
-S3KEY="php71/${MD5SUM}"
+PHP_VERSION="${1}"
 
-for region in "${PHP71_REGIONS[@]}"; do
+LAYER="php${PHP_VERSION//.}"
+MD5SUM=$(md5 -q "${LAYER}.zip")
+S3KEY="${LAYER}/${MD5SUM}"
+
+for region in "${PHP_REGIONS[@]}"; do
   bucket_name="stackery-layers-${region}"
 
-  echo "Publishing Lambda Layer php71 in region ${region}..."
+  echo "Publishing Lambda Layer ${LAYER} in region ${region}..."
   # Must use --cli-input-json so AWS CLI doesn't attempt to fetch license URL
-  version=$(aws --region $region lambda publish-layer-version --cli-input-json "{\"LayerName\": \"php71\",\"Description\": \"PHP 7.1 Web Server Lambda Runtime\",\"Content\": {\"S3Bucket\": \"${bucket_name}\",\"S3Key\": \"${S3KEY}\"},\"CompatibleRuntimes\": [\"provided\"],\"LicenseInfo\": \"http://www.php.net/license/3_01.txt\"}"  --output text --query Version)
-  echo "Published Lambda Layer php71 in region ${region} version ${version}"
+  version=$(aws --region $region lambda publish-layer-version --cli-input-json "{\"LayerName\": \"${LAYER}\",\"Description\": \"PHP ${PHP_VERSION} Web Server Lambda Runtime\",\"Content\": {\"S3Bucket\": \"${bucket_name}\",\"S3Key\": \"${S3KEY}\"},\"CompatibleRuntimes\": [\"provided\"],\"LicenseInfo\": \"http://www.php.net/license/3_01.txt\"}"  --output text --query Version)
+  echo "Published Lambda Layer ${LAYER} in region ${region} version ${version}"
 
-  echo "Setting public permissions on Lambda Layer php71 version ${version} in region ${region}..."
-  aws --region $region lambda add-layer-version-permission --layer-name php71 --version-number $version --statement-id=public --action lambda:GetLayerVersion --principal '*' > /dev/null
-  echo "Public permissions set on Lambda Layer php71 version ${version} in region ${region}"
+  echo "Setting public permissions on Lambda Layer ${LAYER} version ${version} in region ${region}..."
+  aws --region $region lambda add-layer-version-permission --layer-name "${LAYER}" --version-number $version --statement-id=public --action lambda:GetLayerVersion --principal '*' > /dev/null
+  echo "Public permissions set on Lambda Layer ${LAYER} version ${version} in region ${region}"
 done
diff --git a/regions.sh b/regions.sh
index dc2002f..d1b9e44 100644
--- a/regions.sh
+++ b/regions.sh
@@ -1,4 +1,4 @@
-PHP71_REGIONS=(
+PHP_REGIONS=(
   ap-northeast-1
   ap-northeast-2
   ap-south-1
diff --git a/unpublish.sh b/unpublish.sh
index eb2ff9d..756825f 100755
--- a/unpublish.sh
+++ b/unpublish.sh
@@ -1,16 +1,18 @@
 #!/bin/bash -e
 
-VERSION=$1
+PHP_VERSION="${1}"
+LAYER_VERSION="${2}"
 
 source regions.sh
 
-MD5SUM=$(md5 -q php71.zip)
-S3KEY="php71/${MD5SUM}"
+LAYER="php${PHP_VERSION//.}"
+MD5SUM=$(md5 -q "${LAYER}.zip")
+S3KEY="${LAYER}/${MD5SUM}"
 
-for region in "${PHP71_REGIONS[@]}"; do
+for region in "${PHP_REGIONS[@]}"; do
   bucket_name="stackery-layers-${region}"
 
-  echo "Deleting Lambda Layer php71 version ${VERSION} in region ${region}..."
-  aws --region $region lambda delete-layer-version --layer-name php71 --version-number $VERSION > /dev/null
-  echo "Deleted Lambda Layer php71 version ${VERSION} in region ${region}"
+  echo "Deleting Lambda Layer ${LAYER} version ${VERSION} in region ${region}..."
+  aws --region $region lambda delete-layer-version --layer-name ${LAYER} --version-number $VERSION > /dev/null
+  echo "Deleted Lambda Layer ${LAYER} version ${VERSION} in region ${region}"
 done
diff --git a/upload.sh b/upload.sh
index 89c5afb..191f734 100755
--- a/upload.sh
+++ b/upload.sh
@@ -2,13 +2,16 @@
 
 source regions.sh
 
-MD5SUM=$(md5 -q php71.zip)
-S3KEY="php71/${MD5SUM}"
+PHP_VERSION="${1}"
 
-for region in "${PHP71_REGIONS[@]}"; do
+LAYER="php${PHP_VERSION//.}"
+MD5SUM=$(md5 -q "${LAYER}.zip")
+S3KEY="${LAYER}/${MD5SUM}"
+
+for region in "${PHP_REGIONS[@]}"; do
   bucket_name="stackery-layers-${region}"
 
-  echo "Uploading php71.zip to s3://${bucket_name}/${S3KEY}"
+  echo "Uploading ${LAYER}.zip to s3://${bucket_name}/${S3KEY}"
 
-  aws --region $region s3 cp php71.zip "s3://${bucket_name}/${S3KEY}"
+  aws --region $region s3 cp ${LAYER}.zip "s3://${bucket_name}/${S3KEY}"
 done

From 026e13b3424f3ad3d188961913b8eff8091e6a53 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 5 Feb 2019 14:48:42 -0800
Subject: [PATCH 27/42] Make build-php-remi.sh executable

---
 build-php-remi.sh | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 build-php-remi.sh

diff --git a/build-php-remi.sh b/build-php-remi.sh
old mode 100644
new mode 100755

From 5173fb5076ea8c338c515f78e170f86f70b8d419 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 5 Feb 2019 14:48:59 -0800
Subject: [PATCH 28/42] Update Makefile commands for multiple versions

And drop 7.2 version, we'll only ship the 7.3 version.
---
 .gitignore |  1 -
 Makefile   | 21 +++++++++++++--------
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/.gitignore b/.gitignore
index 59f7c11..6160051 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,2 @@
 php71.zip
-php72.zip
 php73.zip
diff --git a/Makefile b/Makefile
index 9d4e5ce..4057a87 100644
--- a/Makefile
+++ b/Makefile
@@ -1,20 +1,25 @@
 ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
 
+all: php71.zip php73.zip
+
 php71.zip:
 	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build.sh
 
-php72.zip:
-	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php-remi.sh 2
-
 php73.zip:
 	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php-remi.sh 3
 
-upload: php71.zip
-	./upload.sh
+upload71: php71.zip
+	./upload.sh 7.1
+
+upload73: php73.zip
+	./upload.sh 7.3
+
+publish71: php71.zip
+	./publish.sh 7.1
 
-publish: php71.zip
-	./publish.sh
+publish73: php73.zip
+	./publish.sh 7.3
 
 clean:
-	rm -f php71.zip php72.zip php73.zip
+	rm -f php71.zip php73.zip
 

From 26222e9d0f7c76d85dee2497fa9f37f94b96f740 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 5 Feb 2019 16:12:44 -0800
Subject: [PATCH 29/42] Fix layer php.ini for php71 layer

---
 build.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build.sh b/build.sh
index f1ef9f5..7233fd8 100755
--- a/build.sh
+++ b/build.sh
@@ -5,7 +5,7 @@ yum install -y php71-mbstring.x86_64 zip php71-pgsql php71-mysqli
 mkdir /tmp/layer
 cd /tmp/layer
 cp /opt/layer/bootstrap .
-cp /opt/layer/php.ini .
+sed "s/PHP_MINOR_VERSION/1/g" /opt/layer/php.ini >php.ini
 
 mkdir bin
 cp /usr/bin/php bin/

From c5fd4cdb923933f2349bf2125d7a9ffe642a038a Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 5 Feb 2019 16:17:28 -0800
Subject: [PATCH 30/42] Release new layer versions

7.3: 1
7.1: 8
---
 README.md | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index 5122f1d..1e68e48 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,16 @@
 # PHP Layer For AWS Lambda
 
-Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.1/7.2/7.3  webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) or [AWS Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/features/#Details_for_Elastic_Load_Balancing_Products) requests.
+Ever wanted to run PHP websites in AWS Lambda? It's your lucky day! This Lambda Runtime Layer runs the [PHP 7.3/7.1  webserver](http://php.net/manual/en/features.commandline.webserver.php) in response to [AWS API Gateway](https://aws.amazon.com/api-gateway/) or [AWS Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/features/#Details_for_Elastic_Load_Balancing_Products) requests.
 
 And, if you're looking for a great way to build serverless apps of all kinds, be sure to check out [Stackery](https://stackery.io)!
 
 This is an early iteration of the PHP runtime Layer which is not yet ready for production. Please feel free to use this Layer to learn about the Lambda Layers feature and begin experimenting with PHP functions. We welcome feedback and stay tuned for the production-ready version coming soon.
 
 ## Current Layer Version ARN
-When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARN for PHP 7.1 is:
+When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARNs for PHP 7.3 and 7.1 are:
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:7**
+**arn:aws:lambda:\<region\>:887080169480:layer:php73:1**
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:8**
 
 See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
@@ -30,7 +31,7 @@ There are three locations where PHP configuration may be located:
 * Files in function code package located under /php-${PHP_VERSION}.d/
 * php.ini located at the root of the function code package
 
-Replace ${PHP_VERSION} with '7.1', '7.2', or '7.3' according to your preferred runtime.
+Replace ${PHP_VERSION} with '7.3', or '7.1' according to your preferred runtime.
 
 ##### Extensions
 The following extensions are built into the layer and available in /opt/lib/php/${PHP_VERSION}/modules:
@@ -103,7 +104,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php71:7
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php73:1
       Events:
         api:
           Type: Api
@@ -144,24 +145,22 @@ $ sam deploy \
 ```
 
 ### Development
-Build the layer by:
+Build the layers by:
 
 1. Installing a Docker environment
 1. Running `make`
 
-This will launch a Docker container that will build php71.zip.
-
-You can run `make php72.zip` and `make php73.zip` to create a layer that is based on PHP 7.2/7.3.
+This will launch Docker containers that will build php73.zip and php71.zip.
 
 If you are behind a proxy server, just set the environment variable `http_proxy` before
 invoking `make`, eg.:
 
 ```sh
-	$ export http_proyx=http://myproxy.acme.com:8080
+	$ export http_proxy=http://myproxy.acme.com:8080
 	$ make php73.zip
 ```
 
-### Debugging
+#### Debugging Layer Builds
 
 Run:
 
@@ -175,7 +174,7 @@ If you are on Windows, run this instead:
 	> docker run --rm -it -v %cd%:/opt/layer lambci/lambda:build-nodejs8.10 /bin/bash
 ```
 
-and execute manually the commands in the build.sh file.
+then manually execute the commands in the build.sh file.
 
 ### Disclaimer
 

From 9840be8e5c09bc811f72993f1b231c220e3c6279 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 5 Feb 2019 16:24:35 -0800
Subject: [PATCH 31/42] Fix layer version ARNs list

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 1e68e48..2d9a3ce 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ This is an early iteration of the PHP runtime Layer which is not yet ready for p
 When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARNs for PHP 7.3 and 7.1 are:
 
 **arn:aws:lambda:\<region\>:887080169480:layer:php73:1**
+<br>
 **arn:aws:lambda:\<region\>:887080169480:layer:php71:8**
 
 See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
@@ -189,4 +190,4 @@ then manually execute the commands in the build.sh file.
 > HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 > STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 > ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-> OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
+> OF THE POSSIBILITY OF SUCH DAMAGE.

From fc86f1caa6d692028b300ad910061aa60d7615c8 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Wed, 6 Feb 2019 11:07:38 -0800
Subject: [PATCH 32/42] Fix newlines on die messages

---
 bootstrap | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bootstrap b/bootstrap
index 9609a20..78f5e70 100755
--- a/bootstrap
+++ b/bootstrap
@@ -12,7 +12,7 @@ function start_webserver() {
   $pid = pcntl_fork();
   switch($pid) {
     case -1:
-      die('Failed to fork webserver process');
+      die("Failed to fork webserver process\n");
 
     case 0:
       // exec the command
@@ -94,7 +94,7 @@ while (true) {
   }
 
   if ($invocation_id == '') {
-    die('Failed to determine Lambda invocation ID');
+    die("Failed to determine Lambda invocation ID\n");
   }
 
   curl_close($ch);

From 88e106acfa80415a6f62c05dea97261da641f730 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Wed, 6 Feb 2019 11:09:34 -0800
Subject: [PATCH 33/42] Check for webserver startup every millisecond

This cuts down cold starts from over one second to usually around 50 to
100 milliseconds.
---
 bootstrap | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/bootstrap b/bootstrap
index 78f5e70..91969bd 100755
--- a/bootstrap
+++ b/bootstrap
@@ -9,6 +9,8 @@ $AWS_LAMBDA_RUNTIME_API = getenv('AWS_LAMBDA_RUNTIME_API');
 $http_codes = [100=>'Continue',101=>'Switching Protocols',102=>'Processing',200=>'OK',201=>'Created',202=>'Accepted',203=>'Non-Authoritative Information',204=>'No Content',205=>'Reset Content',206=>'Partial Content',207=>'Multi-Status',208=>'Already Reported',226=>'IM Used',300=>'Multiple Choices',301=>'Moved Permanently',302=>'Found',303=>'See Other',304=>'Not Modified',305=>'Use Proxy',306=>'Switch Proxy',307=>'Temporary Redirect',308=>'Permanent Redirect',400=>'Bad Request',401=>'Unauthorized',402=>'Payment Required',403=>'Forbidden',404=>'Not Found',405=>'Method Not Allowed',406=>'Not Acceptable',407=>'Proxy Authentication Required',408=>'Request Timeout',409=>'Conflict',410=>'Gone',411=>'Length Required',412=>'Precondition Failed',413=>'Request Entity Too Large',414=>'Request-URI Too Long',415=>'Unsupported Media Type',416=>'Requested Range Not Satisfiable',417=>'Expectation Failed',418=>'I\'m a teapot',419=>'Authentication Timeout',420=>'Enhance Your Calm',420=>'Method Failure',422=>'Unprocessable Entity',423=>'Locked',424=>'Failed Dependency',424=>'Method Failure',425=>'Unordered Collection',426=>'Upgrade Required',428=>'Precondition Required',429=>'Too Many Requests',431=>'Request Header Fields Too Large',444=>'No Response',449=>'Retry With',450=>'Blocked by Windows Parental Controls',451=>'Redirect',451=>'Unavailable For Legal Reasons',494=>'Request Header Too Large',495=>'Cert Error',496=>'No Cert',497=>'HTTP to HTTPS',499=>'Client Closed Request',500=>'Internal Server Error',501=>'Not Implemented',502=>'Bad Gateway',503=>'Service Unavailable',504=>'Gateway Timeout',505=>'HTTP Version Not Supported',506=>'Variant Also Negotiates',507=>'Insufficient Storage',508=>'Loop Detected',509=>'Bandwidth Limit Exceeded',510=>'Not Extended',511=>'Network Authentication Required',598=>'Network read timeout error',599=>'Network connect timeout error'];
 
 function start_webserver() {
+  $SERVER_STARTUP_TIMEOUT = 1000000; // 1 second
+
   $pid = pcntl_fork();
   switch($pid) {
     case -1:
@@ -25,11 +27,20 @@ function start_webserver() {
       exec("PHP_INI_SCAN_DIR=/opt/etc/php-7.${phpMinorVersion}.d/:/var/task/php-7.${phpMinorVersion}.d/ php -S localhost:8000 -c /var/task/php.ini -d extension_dir=/opt/lib/php/7.${phpMinorVersion}/modules '$handler_filename'");
       exit;
 
-    // return the child pid to parent
     default:
       // Wait for child server to start
-      sleep(1);
-      return $pid;
+      $start = microtime(true);
+
+      do {
+        if (microtime(true) - $start > $SERVER_STARTUP_TIMEOUT) {
+          die("Webserver failed to start within one second\n");
+        }
+
+        usleep(1000);
+        $fp = @fsockopen('localhost', 8000, $errno, $errstr, 1);
+      } while ($fp == false);
+
+      fclose($fp);
   }
 }
 

From d6f41bd02423d9e97f41195fb95c4a4d1576e841 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Wed, 6 Feb 2019 11:25:54 -0800
Subject: [PATCH 34/42] Release new layer versions

7.3: 2
7.1: 9
---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 2d9a3ce..c6d8b71 100644
--- a/README.md
+++ b/README.md
@@ -9,9 +9,9 @@ This is an early iteration of the PHP runtime Layer which is not yet ready for p
 ## Current Layer Version ARN
 When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARNs for PHP 7.3 and 7.1 are:
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php73:1**
-<br>
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:8**
+**arn:aws:lambda:\<region\>:887080169480:layer:php73:2**
+
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:9**
 
 See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
@@ -105,7 +105,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php73:1
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php73:2
       Events:
         api:
           Type: Api

From 51051dd5f21d6d4982eeb7c59de3810b5dc2eae0 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Wed, 15 May 2019 08:22:24 -0700
Subject: [PATCH 35/42] Update README.md for included extensions in PHP 7.3

---
 README.md | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/README.md b/README.md
index c6d8b71..f8bf556 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,33 @@ Replace ${PHP_VERSION} with '7.3', or '7.1' according to your preferred runtime.
 ##### Extensions
 The following extensions are built into the layer and available in /opt/lib/php/${PHP_VERSION}/modules:
 
+PHP 7.3 Layer:
+```
+bz2.so
+calendar.so
+ctype.so
+curl.so
+exif.so
+fileinfo.so
+ftp.so
+gettext.so
+iconv.so
+json.so
+mbstring.so
+mysqli.so
+mysqlnd.so
+pdo.so
+pdo_mysql.so
+pdo_pgsql.so
+pdo_sqlite.so
+pgsql.so
+phar.so
+sockets.so
+sqlite3.so
+tokenizer.so
+```
+
+PHP 7.1 Layer:
 ```
 bz2.so
 calendar.so

From 28e6e8d9160b381218e57ea6c2aafa1a8d43c6ce Mon Sep 17 00:00:00 2001
From: Tito Costa <tito.costa@mightyape.co.nz>
Date: Wed, 29 May 2019 10:46:45 +1200
Subject: [PATCH 36/42] fixed issue with installing remi repo and added the php
 xml and process extensions

---
 build-php-remi.sh | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/build-php-remi.sh b/build-php-remi.sh
index c0d0ee0..9c6ae8f 100755
--- a/build-php-remi.sh
+++ b/build-php-remi.sh
@@ -8,9 +8,8 @@ yum install -y wget
 yum install -y yum-utils
 wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
 wget https://rpms.remirepo.net/enterprise/remi-release-6.rpm
-rpm -Uvh remi-release-6.rpm
 rpm -Uvh epel-release-latest-6.noarch.rpm
-
+rpm -Uvh remi-release-6.rpm
 
 yum-config-manager --enable remi-php7${PHP_MINOR_VERSION}
 
@@ -18,7 +17,7 @@ yum install -y httpd
 yum install -y postgresql-devel
 yum install -y libargon2-devel
 
-yum install -y --disablerepo="*" --enablerepo="remi,remi-php7${PHP_MINOR_VERSION}" php php-mbstring php-pdo php-mysql php-pgsql
+yum install -y --disablerepo="*" --enablerepo="remi,remi-php7${PHP_MINOR_VERSION}" php php-mbstring php-pdo php-mysql php-pgsql php-xml php-process
 
 
 mkdir /tmp/layer

From b507b5ec648ae99f393bb43fa0a69103687d2dd1 Mon Sep 17 00:00:00 2001
From: Tito Miguel Costa <titomiguelcosta@gmail.com>
Date: Sat, 1 Jun 2019 09:26:52 +1200
Subject: [PATCH 37/42] updated readme with list of extensions provided on php
 7.3

---
 README.md | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index f8bf556..5e47a4a 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,7 @@ bz2.so
 calendar.so
 ctype.so
 curl.so
+dom.so
 exif.so
 fileinfo.so
 ftp.so
@@ -52,15 +53,26 @@ json.so
 mbstring.so
 mysqli.so
 mysqlnd.so
-pdo.so
 pdo_mysql.so
 pdo_pgsql.so
+pdo.so
 pdo_sqlite.so
 pgsql.so
 phar.so
+posix.so
+shmop.so
+simplexml.so
 sockets.so
 sqlite3.so
+sysvmsg.so
+sysvsem.so
+sysvshm.so
 tokenizer.so
+wddx.so
+xmlreader.so
+xml.so
+xmlwriter.so
+xsl.so
 ```
 
 PHP 7.1 Layer:

From 9daecf19d9e1f0ed2a0dc080b955cbc585e721a6 Mon Sep 17 00:00:00 2001
From: Keitaroh Kobayashi <keita@kbys.me>
Date: Mon, 24 Jun 2019 17:36:59 +0900
Subject: [PATCH 38/42] Add libonig.so.5 for mbstring

---
 build-php-remi.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/build-php-remi.sh b/build-php-remi.sh
index 9c6ae8f..cb2f71d 100755
--- a/build-php-remi.sh
+++ b/build-php-remi.sh
@@ -36,6 +36,7 @@ done
 cp /usr/lib64/libedit.so.0 lib/
 cp /usr/lib64/libargon2.so.0 lib/
 cp /usr/lib64/libpq.so.5 lib/
+cp /usr/lib64/libonig.so.5 lib/
 
 mkdir -p lib/php/7.${PHP_MINOR_VERSION}
 cp -a /usr/lib64/php/modules lib/php/7.${PHP_MINOR_VERSION}/

From 5afa317d8033af21f2789d5e2ddd819858d79a96 Mon Sep 17 00:00:00 2001
From: Keitaroh Kobayashi <keita@kbys.me>
Date: Tue, 25 Jun 2019 10:18:53 +0900
Subject: [PATCH 39/42] Send body regardless of what the HTTP method is.

This allows PUT and PATCH requests, for example.
---
 bootstrap         | 8 +-------
 build-php-remi.sh | 2 +-
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/bootstrap b/bootstrap
index 91969bd..fddbc5c 100755
--- a/bootstrap
+++ b/bootstrap
@@ -171,13 +171,7 @@ while (true) {
   }
 
   if (strlen($body) > 0) {
-    if($event['httpMethod'] === 'POST'){
-      curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
-    }    
-    curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
-    curl_setopt($ch, CURLOPT_READFUNCTION, function ($ch, $fd, $length) use ($body) {
-      return $body;
-    });
+    curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
   }
 
   $response = array();
diff --git a/build-php-remi.sh b/build-php-remi.sh
index cb2f71d..8d8fbef 100755
--- a/build-php-remi.sh
+++ b/build-php-remi.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
 
 PHP_MINOR_VERSION=$1
 

From a553e85cc538ef5add73176af6269e283969ffaa Mon Sep 17 00:00:00 2001
From: Keitaroh Kobayashi <keita@kbys.me>
Date: Mon, 24 Jun 2019 15:56:34 +0900
Subject: [PATCH 40/42] Fix redirecting from PHP

---
 bootstrap | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bootstrap b/bootstrap
index fddbc5c..5fcf610 100755
--- a/bootstrap
+++ b/bootstrap
@@ -145,7 +145,7 @@ while (true) {
 
   $ch = curl_init("http://localhost:8000$uri");
 
-  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
+  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
 
   if (array_key_exists('multiValueHeaders', $event)) {
     $headers = array();

From a6dc45ebf453fd4f5daa569cd9544b75c5d15e52 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 2 Jul 2019 16:12:17 -0700
Subject: [PATCH 41/42] Build with updated lambci 'provided' images

---
 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 4057a87..eee5fce 100644
--- a/Makefile
+++ b/Makefile
@@ -3,10 +3,10 @@ ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
 all: php71.zip php73.zip
 
 php71.zip:
-	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build.sh
+	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-provided /opt/layer/build.sh
 
 php73.zip:
-	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-nodejs8.10 /opt/layer/build-php-remi.sh 3
+	docker run --rm -e http_proxy=${http_proxy} -v $(ROOT_DIR):/opt/layer lambci/lambda:build-provided /opt/layer/build-php-remi.sh 3
 
 upload71: php71.zip
 	./upload.sh 7.1

From 90b4d55e6b3b4d1c389e37af9a74b819bf0b486e Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase@stackery.io>
Date: Tue, 2 Jul 2019 15:11:56 -0700
Subject: [PATCH 42/42] Release new layer versions

7.3: 3
7.1: 10
---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 5e47a4a..f71456d 100644
--- a/README.md
+++ b/README.md
@@ -9,9 +9,9 @@ This is an early iteration of the PHP runtime Layer which is not yet ready for p
 ## Current Layer Version ARN
 When creating/updating a Lambda function you must specify  a specific version of the layer. This readme will be kept up to date with the latest version available. The latest available Lambda Layer Version ARNs for PHP 7.3 and 7.1 are:
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php73:2**
+**arn:aws:lambda:\<region\>:887080169480:layer:php73:3**
 
-**arn:aws:lambda:\<region\>:887080169480:layer:php71:9**
+**arn:aws:lambda:\<region\>:887080169480:layer:php71:10**
 
 See [Releases](https://github.com/stackery/php-lambda-layer/releases) for release notes.
 
@@ -144,7 +144,7 @@ Resources:
       Timeout: 30
       Tracing: Active
       Layers:
-        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php73:2
+        - !Sub arn:aws:lambda:${AWS::Region}:887080169480:layer:php73:3
       Events:
         api:
           Type: Api
