我有两个文件:index.js和php-cgi
当我在AWS Lambda控制台中按下测试按钮时,我看到一个空字符串而不是php版本。
这是我的Index.js代码:
Response.Clear();
Response.ContentType = "text/plain";
Response.Write("{'some': 'json'}");
Response.End();
我如何执行php-cgi。 谢谢
答案 0 :(得分:1)
您需要使用AMI Amazon Linux 1启动EC2实例并遵循以下命令:
mkdir php-lambda
cd php-lambda
下载https://github.com/akrabat/lambda-php/blob/2019-01-02-article/doc/compile_php.sh并使用所需的php sh compile_php.sh 7.3.6版本执行
它将创建一个名为php-7-bin的文件夹。在/ bin / php文件夹中,是我们需要的php二进制文件。
从https://github.com/akrabat/lambda-php/tree/2019-01-02-article/layer/php
下载bootstrap和runtime.php创建一个新文件夹,并将php二进制文件,bootstrap和runtime.php添加到其中。
使用此内容创建一个zip。
zip -r9 php-layer.zip *
使用此zip创建图层。
用于在lambda中使用php。您需要创建一个lambda函数,然后选择自定义运行时,并添加上面创建的php层。
为例如handler.php创建一个文件,并在其中添加下一个代码:
<?php
function hello($eventData) : array
{
echo "Prueba";
return ["msg" => "hola"];
}
现在您的PHP Lambda可以正常工作了。
我对runtime.php添加了一些更改,所以我现在只接收json数据。
<?php
/**
*
* Modified from: https://github.com/pagnihotry/PHP-Lambda-Runtime/blob/master/runtime/runtime.php
* Copyright (c) 2018 Parikshit Agnihotry
*
* RKA Changes:
* - JSON encode result of handler function
* - Catch any Throwables and write to error log
*/
/**
* PHP class to interact with AWS Runtime API
*/
class LambdaRuntime
{
const POST = "POST";
const GET = "GET";
private $url;
private $functionCodePath;
private $requestId;
private $response;
private $rawEventData;
private $eventPayload;
private $handler;
/**
* Constructor to initialize the class
*/
function __construct()
{
$this->url = "http://".getenv("AWS_LAMBDA_RUNTIME_API");
$this->functionCodePath = getenv("LAMBDA_TASK_ROOT");
$this->handler = getenv("_HANDLER");
}
/**
* Get the current request Id being serviced by the runtime
*/
public function getRequestId() {
return $this->requestId;
}
/**
* Get the handler setting defined in AWS Lambda configuration
*/
public function getHandler() {
return $this->handler;
}
/**
* Get the current event payload
*/
public function getEventPayload() {
return json_decode($this->eventPayload);
}
/**
* Get the buffered response
*/
public function getResponse() {
return $this->response;
}
/**
* Reset the response buffer
*/
public function resetResponse() {
$this->response = "";
}
/**
* Add string to the response buffer. This is printed out on success.
*/
public function addToResponse($str) {
$this->response = $this->response.$str;
}
public function flushResponse() {
$result = $this->curl(
"/2018-06-01/runtime/invocation/".$this->getRequestId()."/response",
LambdaRuntime::POST,
$this->getResponse()
);
$this->resetResponse();
}
/**
* Get the Next event data
*/
public function getNextEventData() {
$this->rawEventData = $this->curl("/2018-06-01/runtime/invocation/next", LambdaRuntime::GET);
if(!isset($this->rawEventData["headers"]["lambda-runtime-aws-request-id"][0])) {
//Handle error
$this->reportError(
"MissingEventData",
"Event data is absent. EventData:".var_export($this->rawEventData, true)
);
//setting up response so the while loop does not try to invoke the handler with unexpected data
return array("error"=>true);
}
$this->requestId = $this->rawEventData["headers"]["lambda-runtime-aws-request-id"][0];
$this->eventPayload = $this->rawEventData["body"];
return $this->rawEventData;
}
/**
* Report error to Lambda runtime
*/
public function reportError($errorType, $errorMessage) {
$errorArray = array("errorType"=>$errorType, "errorMessage"=>$errorMessage);
$errorPayload = json_encode($errorArray);
$result = $this->curl(
"/2018-06-01/runtime/invocation/".$this->getRequestId()."/error",
LambdaRuntime::POST,
$errorPayload
);
}
/**
* Report initialization error with runtime
*/
public function reportInitError($errorType, $errorMessage) {
$errorArray = array("errorType"=>$errorType, "errorMessage"=>$errorMessage);
$errorPayload = json_encode($errorArray);
$result = $this->curl(
"/2018-06-01/runtime/init/error",
LambdaRuntime::POST,
$errorPayload
);
}
/**
* Internal function to make curl requests to the runtime API
*/
private function curl($urlPath, $method, $payload="") {
$fullURL = $this->url . $urlPath;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $fullURL);
curl_setopt($ch, CURLOPT_NOBODY, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$headers = [];
// Parse curl headers
curl_setopt($ch, CURLOPT_HEADERFUNCTION,
function($curl, $header) use (&$headers)
{
$len = strlen($header);
$header = explode(':', $header, 2);
if (count($header) < 2) // ignore invalid headers
return $len;
$name = strtolower(trim($header[0]));
if (!array_key_exists($name, $headers))
$headers[$name] = [trim($header[1])];
else
$headers[$name][] = trim($header[1]);
return $len;
}
);
//handle post request
if($method == LambdaRuntime::POST) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
// Set HTTP Header for POST request
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Length: ' . strlen($payload)
)
);
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return array("headers"=>$headers, "body"=>$response, "httpCode" => $httpCode);
}
}
$lambdaRuntime = new LambdaRuntime();
$handler = $lambdaRuntime->getHandler();
//Extract file name and function
list($handlerFile , $handlerFunction) = explode(".", $handler);
//Include the handler file
require_once($handlerFile.".php");
//Poll for the next event to be processed
while (true) {
//Get next event
$data = $lambdaRuntime->getNextEventData();
//Check if there was an error that runtime detected with the next event data
if(isset($data["error"]) && $data["error"]) {
continue;
}
//Process the events
$eventPayload = $lambdaRuntime->getEventPayload();
try {
//Handler is of format Filename.function
//Execute handler
$functionReturn = $handlerFunction($eventPayload);
$json = json_encode($functionReturn, true);
$lambdaRuntime->addToResponse($json);
} catch (\Throwable $e) {
error_log((string)$e);
}
//Report result
$lambdaRuntime->flushResponse();
}