在 Lambda 上运行 PHP,使用 Homebrew MVC 框架





5.00/5 (1投票)
30 分钟内构建自定义 PHP MVC 并部署到 AWS lambda。
演示URL: https://0qdhumcwd5.execute-api.ap-southeast-2.amazonaws.com/Prod/
引言
大约一年前,我撰写了一篇关于为AWS Lambda构建自定义运行时环境的文章,使您能够运行PHP。以这种方式运行PHP有很多好处,它可以很好地扩展、托管成本很低,如果您熟悉PHP而不是AWS,那么这可能是一个有趣的尝试项目。过去一年中,有几个人就此与我联系,这个周末,我正在帮助某人让它工作。在回忆如何使用PHP的同时,我决定稍微修补一下,并用PHP编写一个迷你MVC框架。
最终的应用程序可以在这里看到https://dsemyh3dx0.execute-api.ap-southeast-2.amazonaws.com/Prod。
背景
对于一些背景知识,这里有许多好的资源库https://github.com/aws-samples/php-examples-for-aws-lambda。实际上,我的许多示例存储库都基于此,但是如果您尚未设置PHP,则可能很难部署并弄清楚如何安装所有依赖项以及安装composer。因此,除了代码之外,我还添加了在Cloud9中设置和运行此代码的说明以及一个短视频。
Using the Code
如果您未使用AWS,那么SAM可能对您来说是新的,我将快速介绍一下。 SAM是无服务器应用程序模型,它帮助您使用模板yaml文件快速为AWS构建无服务器基础设施。 让我们快速看一下这个文件
请注意,我已经对正在使用的层硬编码了区域
AWSTemplateFormatVersion: 2010-09-09
Description: Testing PHP and Lambda
Transform: AWS::Serverless-2016-10-31
##########################################################################
# Parameters & Globals #
##########################################################################
Globals:
Function:
Timeout: 3
Resources:
##########################################################################
# Lambda function with PHP runtime provided by layers #
##########################################################################
CatchAllLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Description: Lambda function to hosts entire application codebase
CodeUri: ./code/
Runtime: provided
Handler: index.php
MemorySize: 4096
Timeout: 30
Tracing: Active
Layers:
- 'arn:aws:lambda:ap-southeast-2:209497400698:layer:php-73-fpm:25'
Events:
DynamicRequestsRoot:
Type: Api
Properties:
Path: /
Method: ANY
DynamicRequestsProxy:
Type: Api
Properties:
Path: /{proxy+}
Method: ANY
##########################################################################
# Stack Outputs #
##########################################################################
Outputs:
WebEndpoint:
Description: "API Gateway endpoint URL for Prod stage"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
从高层次上看,此模板指定了以下内容
- 部署一个lambda函数
- 部署一个API网关,这样我们就可以在浏览器中调用PHP函数。
- 将一个层附加到lambda函数,该层已预构建以支持PHP(一个层是运行代码所需的其他依赖项)。
- 将code文件夹指定为我们将要部署的代码的来源,如果需要,它可以包含许多文件和文件夹。
- 强制将所有传入请求的入口点设置为index.php。
- 为此函数分配4096MB的RAM,并指定最大运行时时间为3秒。
如果我们考虑一下这个文件,它做了很多事情,它完全取代了构建服务器、安装PHP、安装Apache或nginx、配置PHP和服务器强化。这是一个巨大的好处和节省时间的措施。
部署
我选择制作一个小视频,而不是添加静态图像
创建一个新的Cloud9环境,最小的实例大小就足够了,但请确保选择Amazon Linux 2。
在Cloud 9中,在终端中执行以下步骤
sudo yum -y update
sudo amazon-linux-extras install -y php7.2 php-mbstring
git clone https://github.com/kukielp/aws-lambda-php-mvc.git
cd aws-lambda-php-mvc
php -r "copy('https://getcomposer.org.cn/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
这将安装PHP 7.2,克隆存储库并安装composer,接下来我们将安装bref
和guzzel
。
cd code
php ../composer.phar require bref/bref
php ../composer.phar require guzzlehttp/guzzle
打开template.yaml,更新第27行以对齐您希望部署到的区域。您可以在此处查找可用的层:https://runtimes.bref.sh/。
然后运行
cd ..
sam deploy --guided
按照说明进行操作,并确保部署到您在template.yaml中指定的区域。
部署完成后,您可以在浏览器中从输出部分打开WebEndpoint,您将看到应用程序正在运行。
MVC代码
index.php
// Include breff/guzzel and other dependencies.
require_once 'vendor/autoload.php';
$__path = explode("/", $_SERVER['REQUEST_URI']);
if(count($__path) < 3){
$__controller = 'controller/base.php';
$__view = 'view/base/base.php';
$__controllerMethod = 'base';
}else{
//Delete the first '/'
$__pos = strpos($_SERVER['REQUEST_URI'], "/");
if ($__pos !== false) {
//extract the view (/sample/page will be --> view/sample/page.php)
$__view = "view/" .substr_replace($_SERVER['REQUEST_URI'], "/", $__pos, 1) .".php";
//extract the controller at this point it ill be (sample/page)
$__controller = "controller/" .substr_replace($_SERVER['REQUEST_URI'], "/", $__pos, 1);
}
//Convert to an array and get the last item (page)
$__method_arr = explode ("/", $__controller);
$__controllerMethod = end($__method_arr);
//Remove the last item in the path (sample/page --> sample)
array_pop($__method_arr);
//rebuild the path to the controller (controller/sample.php)
$__controller = implode ($__method_arr, "/") .'.php';
}
// Include the controller which provides access to....
include $__controller;
// the methods we will call (in this case page), the result will be placed back in $_rc
$_rc = call_user_func($__controllerMethod);
// include the view, the view should only ever access $_rc no other scopes for data.
include $__view;
所有这些代码的作用基本上是解析要“include”的两个文件以及要运行的方法。 $__rc
用作请求上下文变量,用于将信息从控制器传递到视图。控制器将处理任何业务逻辑,与数据库或外部源进行通信,而视图应仅包含用于显示目的的基本逻辑。
random.php(示例控制器)
function joke() {
$client = new GuzzleHttp\Client();
$res = $client->get('https://official-joke-api.appspot.com/random_joke');
$json = $res->getBody();
$result = json_decode($json);
$_rc = [
"httpResult" => $result
];
return $_rc;
}
joke.php(示例视图)
<html>
<body>
<h1>This is the Random Joke page!.</h1>
<p>Enjoy the Joke Text:</p>
<div>Setup: <?php echo $_rc["httpResult"]->setup; ?></div>
<div>Punchline: <?php echo $_rc["httpResult"]->punchline; ?></div>
<pre>
<?php
krumo($_rc["httpResult"]);
?>
</pre>
<a href="/Prod">Home</a>
</body>
</html>
包含Krumo以进行基本调试。
存储库:https://github.com/kukielp/aws-lambda-php-mvc
这是一个有趣的小实验,希望您喜欢阅读!
历史
- 2021年6月14日:初始版本