构建自定义PHP运行时

大约一年前,撰写了一篇关于构建自定义Lambda运行时的文章,该运行时可以运行PHP。以这种方式运行PHP有许多好处,它可以很好地扩展,托管成本非常低,如果熟悉PHP而不是AWS,那么这可能是一个有趣的项目可以尝试。在过去的一年中,有几个人就这个话题联系了,这个周末,帮助某人使其工作。在回忆PHP的使用过程中,决定稍微调整一下,并用PHP编写了一个微型MVC框架

背景方面,这里有很多好的资源。实际上,很多示例资源都是基于这个的,但是如果还没有设置PHP,这可能很难部署,并且弄清楚如何安装所有依赖项和安装composer可能会很困难。因此,除了代码之外,还添加了在Cloud9中设置和运行的说明以及一个短视频。

使用代码

如果不使用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(一个层是运行代码所需的附加依赖项)
  • 指定代码文件夹作为将部署的代码的源代码,如果需要,这可以包含许多文件和文件夹
  • 强制所有传入请求的入口点为index.php
  • 为此函数分配4096MB的RAM,并指定最大运行时间为3秒

部署

选择了制作一个短视频,而不是添加静态图片:

  • 创建一个新的Cloud9环境,最小的实例大小就可以了,但请确保选择Amazon Linux 2。
  • 在Cloud 9中,在终端执行以下步骤:
PHP 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/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和其它依赖。 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{ // 删除第一个'/' $__pos = strpos($_SERVER['REQUEST_URI'], "/"); if($__pos !== false) { // 提取视图(/sample/page将变为--> view/sample/page.php) $__view = "view/" . substr_replace($_SERVER['REQUEST_URI'], "/", $__pos, 1) . ".php"; // 提取控制器,此时它将是(sample/page) $__controller = "controller/" . substr_replace($_SERVER['REQUEST_URI'], "/", $__pos, 1); } // 转换为数组并获取最后一个项目(page) $__method_arr = explode("/", $__controller); $__controllerMethod = end($__method_arr); // 在路径中删除最后一个项目(sample/page --> sample) array_pop($__method_arr); // 重建控制器路径(controller/sample.php) $__controller = implode($__method_arr, "/") . '.php'; } // Include控制器,它提供了访问.... include $__controller; // 将调用的方法(在这种情况下是page),结果将被放回$_rc $_rc = call_user_func($__controllerMethod); // include视图,视图应该只访问$_rc,没有其他作用域用于数据。 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(示例视图)

这是随机笑话页面!

享受笑话文本:

setup; ?>
punchline; ?>
    
首页

Krumo包含用于基本调试。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485