thinkphp项目迁移到函数计算

前言

阿里云函数计算 Function Compute(FC),旨在帮助用户采用弹性伸缩、动态分配资源的方式,来执行业务函数。让用户无需购买部署服务器,无需考虑业务负载,就能快速搭建可处理高并发的后台服务。
本文介绍HTTP触发器快速迁移Thinkphp应用到函数计算。函数计算运行 PHP 框架原理可以参考一下《十分钟上线-函数计算玩转 WordPress》

案例开发配置步骤

  1. 打开tp5的入口文件(/public/index.php)在namespace think; 这句的下面,加如下代码:
if(!$_SERVER['PATH_INFO']) $_SERVER['PATH_INFO'] = preg_replace("/^(\?s\=\/)/","",$_SERVER['REQUEST_URI']);

2.准备tp5源码,将 thinkphp 工程包移动到的/code/2016-08-15/proxy/demo.LATEST/thinkphp 目录,在根目录创建index.php文件(作为函数的入口文件),代码包目录结构如图!thinkphp项目迁移到函数计算

代码如下:

<?php
#自定义的域名,绑定了自定义域名的,可以换成自己自定义的。
$MY_HOST    = "1986114430573743.cn-hangzhou.fc.aliyuncs.com";
#web目录绝对路径,如:/code
$WWW_DIR = '/code';

function handler($request, $context){

    #如果不使用函数计算后台提供的那个厂厂的域名,这句可以注释掉。
    if(strpos($request->getAttribute("requestURI"),"/2016-08-15/proxy") !== false) $request = clearFcHost($request,$context);#兼容 fc后台的url地址

    $uri  = $request->getAttribute("requestURI");
    $file = explode("?", $uri)[0];
    if($file=='/') $uri='/';#
    $file = $GLOBALS['WWW_DIR'].$file;

    if(file_exists($file) and $uri!='/'){
        if(strpos($uri,".php")) return php_run(basename($file), $request, $context);#php_run
        return static_run($uri);#static_run
    }

    $request = $request->withAttribute("requestURI", "?s=".$uri);
    return php_run('index.php', $request, $context);# php_run

}

function php_run($name,$request, $context)
{
    return $GLOBALS['fcPhpCgiProxy']->requestPhpCgi($request, $GLOBALS['WWW_DIR'], $name,['SERVER_NAME' => $GLOBALS['MY_HOST'], 'SERVER_PORT' => '80', 'HTTP_HOST' => $GLOBALS['MY_HOST']],['debug_show_cgi_params' => false, 'readWriteTimeout' => 15000]);
}
use RingCentral\Psr7\Response;
function static_run($uri): Response{
    $file_dir = $GLOBALS['WWW_DIR'].$uri; #完整文件路径
    $file_dir = explode("?", $file_dir)[0]; #去掉动态路径
    if(is_dir($file_dir)) $file_dir .= '/index.html';# 可以这里定义目录的默认索引页
    $handle   = fopen($file_dir, "r");
    $contents = fread($handle, filesize($file_dir));
    fclose($handle);
    return new Response(200, ['Content-Type'  => $GLOBALS['fcPhpCgiProxy']->getMimeType($file_dir),'Cache-Control' => "max-age=8640000",'Accept-Ranges' => 'bytes'], $contents);
}

function clearFcHost($request,$context){
    $uri  = $request->getAttribute("requestURI");
    $uri  = str_replace("/2016-08-15/proxy/".$context['service']['name']."/".$context['function']['name'],"",$uri);
    $request = $request->withAttribute("requestURI", $uri);
    return $request;
}

#错误处理
function error($code) {
    #if($resp->getStatusCode() !=200) return error($resp->getStatusCode());
    return 'thinkphp框架测试~~';
}

Q1: 为什么创建 /2016-08-15/proxy/share/wp-func 这么奇怪的目录?
A:因为http trigger, 函数访问的格式为下面的url: http://${account_id}.${region}.fc.aliyuncs.com/2016-08-15/proxy/$(seevice_name.LATEST}/{function_name}/,为了保证从一个页面跳转到另外一个页面的时候,能自动带上/2016-08-15/proxy/$(seevice_name.LATEST}/{function_name}/,我们需要建立这样目录和设置 cgi 相关参数达到 PHP 框架内部自动跳转正确的目的。

3.由于函数计算只有/tmp 目录可写,所以要改一下tp5的配置文件
编辑/config/log.php

'path'  => '/tmp/log',

编辑/config/cache.php

'path'  => '/tmp/cache',

4.使用fun工具部署函数,在项目根目录下创建template.yml名称文件,内容如下:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  demo:
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: 'thinkphp测试'
    thinkphp:
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: index.handler
        Runtime: php7.2
        CodeUri: './'
      Events:
        http-test:
          Type: HTTP
          Properties:
            AuthType: ANONYMOUS
            Methods: ['GET', 'POST', 'PUT']
  

执行fun deploy部署函数,部署成功如图!thinkphp项目迁移到函数计算

5.您可以到FC控制台执行函数了,如图!thinkphp项目迁移到函数计算

但是如果在浏览器中执行 HTTP 触发器的请求地址,web 页面将会已文件的形式下载。这是因为函数计算为了安全强制设置了请求返回的 header 为 Content-Disposition: attachment,所以返回结果会以附件形式下载。为了解决这个问题,需要用户申请自定义域名,并绑定域名解析到函数计算中,请参考函数计算绑定自定义域名

总结

函数计算有如下优势:

  • 无需采购和管理服务器等基础设施
  • 专注业务逻辑的开发
  • 提供日志查询、性能监控、报警等功能快速排查故障
  • 以事件驱动的方式触发应用响应用户请求
  • 毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力
  • 按需付费。只需为实际使用的计算资源付费,适合有明显波峰波谷的用户访问场景
  • 除了上面所列的优势,FC 可以做为 Web Backend,只需要编写一个函数实现传统 Web 服务器中的 conf 中的逻辑,就可以将一个完整的 Web 工程迁移到 FC ,从而从传统的 Web 网站运维,监控等繁琐的事务中解放出来。

最后欢迎大家通过扫码加入我们用户群中,搭建过程中有问题或者有其他问题可以在群里提出来。

函数计算官网客户群(11721331)。

上一篇:在阿里云函数计算上部署kintone应用


下一篇:Serverless 解惑——函数计算如何访问 Redis 数据库