thinkphp5.1 运行在 腾讯云 阿里云 serverless 环境
用阿里云吧
https://help.aliyun.com/document_detail/159783.html
阿里云存储配置
ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
blog:
Type: 'Aliyun::Serverless::Service'
Properties:
Description: typecho博客
Role: 'acs:ram::1157897650908336:role/new-service1578321763398-role'
VpcConfig:
VpcId: vpc-uf6kcg6z74ayq0pa9nliu
VSwitchIds:
- vsw-uf6atq97d8jdokd8r4e5r
SecurityGroupId: sg-uf60rdm0o11g8ajzf56d
NasConfig:
UserId: 10000
GroupId: 10000
MountPoints:
- ServerAddr: '39d4c4be1d-amf86.cn-shanghai.nas.aliyuncs.com:/blog'
MountDir: /mnt/blog
InternetAccess: true
serverless:
Type: 'Aliyun::Serverless::Function'
Properties:
Handler: typecho_aliyun.handler
Runtime: php7.2
CodeUri: './'
Timeout: 600
MemorySize: 128
EnvironmentVariables:
PHP_INI_SCAN_DIR: '/code/extension'
Events:
httpTrigger:
Type: HTTP
Properties:
AuthType: ANONYMOUS
Methods: ['POST', 'GET', 'HEAD', 'PUT', 'DELETE']
阿里云
require_once './vendor/autoload.php';
use RingCentral\Psr7\Response;
use ServerlessFC\PhpCgiProxy;
define('ROOT_DIR', '/mnt/blog');
define('TEXT_REG', '#\.html.*|\.js.*|\.css.*|\.html.*#');
define('BINARY_REG', '#\.gif.*|\.jpg.*|\.png.*|\.jepg.*|\.swf.*|\.bmp.*|\.ico.*|\.svg.*#');
function debug($contents, $code = 200, $headers = ['Content-Type' => 'text/html'])
{
if (!is_string($contents)) {
$contents = json_encode($contents, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
return new Response(
$code,
$headers,
$contents
);
}
function fileHandler($filename)
{
$filename = rawurldecode($filename);
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
try {
$type = $GLOBALS['fcPhpCgiProxy']->getMimeType($filename);
} catch (\Exception $e) {
$type = 'application/octet-stream';
}
$headers = [
'Content-Type' => $type,
'Accept-Ranges' => 'bytes',
'Cache-Control' => 'max-age=3600',
];
return new Response(200, $headers, $contents);
}
function appHandler($request, $host, $scheme, $script = 'index.php')
{
$param = [
$request, ROOT_DIR, $script,
[
'HTTP_HOST' => $host,
'SERVER_NAME' => $host,
'SERVER_PORT' => '80',
'REQUEST_SCHEME' => $scheme,
'SCRIPT_FILENAME' => ROOT_DIR . '/' . $script,
'SCRIPT_NAME' => $script,
],
[
'debug_show_cgi_params' => false,
'readWriteTimeout' => 50000,
],
];
try {
$resp = call_user_func_array([$GLOBALS['fcPhpCgiProxy'], 'requestPhpCgi'], $param);
} catch (\Exception $e) {
$GLOBALS['fcPhpCgiProxy'] = new PhpCgiProxy;
$resp = call_user_func_array([$GLOBALS['fcPhpCgiProxy'], 'requestPhpCgi'], $param);
}
return $resp;
}
function trace(string $log, string $level = 'info')
{
$logger = $GLOBALS['fcLogger'];
call_user_func([$logger, $level], $log);
}
function handler($request, $context): Response
{
$uri = $request->getAttribute('requestURI');
$host = $request->getHeaderLine('Host');
$method = $request->getMethod();
$scheme = $request->getHeaderLine('X-Forwarded-Proto');
$clientIP = $request->getAttribute('clientIP');
$userAgent = $request->getHeaderLine('user-agent');
// 访问日志
$log = sprintf('%s %s %s %s %s', $method, $host, $uri, $clientIP, $userAgent);
// trace($log);
$urlInfo = parse_url($uri);
$path = $urlInfo['path'];
$query = $urlInfo['query'] ?? '';
$pathInfo = pathinfo($path);
$extension = $pathInfo['extension'] ?? '';
$filePath = ROOT_DIR . $path;
// 目录跳转
if (!preg_match('#/$#', $path) && is_dir($filePath . '/') && $method == 'GET') {
return new Response(301, ['Location' => str_replace($path, $path . '/', $uri)], '');
}
// 静态文件
if (file_exists($filePath) && (preg_match(TEXT_REG, $path) || preg_match(BINARY_REG, $path))) {
return fileHandler($filePath);
}
// 直接访问
if (strpos($path, '.php')) {
$script = $path;
}
// 伪静态
if (!strpos($path, '.php')) {
// 优先访问index.php
if (is_dir($filePath)) {
$requestUri = $path . 'index.php' . '?' . $query;
$request = $request->withAttribute('requestURI', $requestUri);
$script = $path . 'index.php';
} else {
$script = 'index.php';
}
}
return appHandler($request, $host, $scheme, $script);
}
// 显示nas目录
// fun nas ls -a nas://
腾讯云
<?php
/**
* thinkphp5.1运行在腾讯云serverless的容器
*
* 2020-03-03
*
* 范国金
*/
require_once __DIR__ . '/thinkphp/base.php';
// 应用目录
define('APP_PATH', __DIR__ . '/application/');
// 缓存目录
define('RUNTIME_PATH', '/tmp/');
// 静态目录
define('STATIC_PATH', __DIR__ . '/public');
// 文本文件
define('TEXT_REG', '#\.html.*|\.js.*|\.css.*|\.html.*#');
// 其他文件
define('BINARY_REG', '#\.gif.*|\.jpg.*|\.png.*|\.jepg.*|\.swf.*|\.bmp.*|\.ico.*#');
use think\Container;
use think\Db;
use think\Error;
use think\exception\ClassNotFoundException;
use think\exception\HttpResponseException;
use think\facade\Request;
use think\Loader;
use think\Route;
use think\route\Dispatch;
class App extends \think\App
{
public static function mainHandler($event, $context)
{
// 请求路径
$path = str_replace("//", "/", $event->path);
// 静态文件
if (preg_match(TEXT_REG, $path) || preg_match(BINARY_REG, $path)) {
return static::handlerStatic($path);
}
// 请求数据
$req = $event->body ?? '';
$data = !empty($req) ? json_decode($req, true) : [];
// 请求头部
$headers = $event->headers ?? [];
$headers = json_decode(json_encode($headers), true);
$headers['HTTP_X_REAL_IP'] = $event->requestContext->sourceIp;
$headers['HTTP_REMOTE_ADDR'] = $event->requestContext->sourceIp;
// 请求参数
$query = $event->queryString ?? [];
$query = json_decode(json_encode($query), true);
$params = json_decode($event->body ?? '', true) ?? [];
$params = array_merge($query, $params);
// 启动框架
Container::set('app', \App::class);
$app = Container::get('app');
$app->path(APP_PATH)->initialize();
// 重置数据
$app->setBeginTime(microtime(true));
$app->setBeginMem(memory_get_usage());
$app->delete('think\Request');
Db::$queryTimes = 0;
Db::$executeTimes = 0;
// 请求内容
$uri = $event->path . '?' . http_build_query($query);
$app->request = Request::create($uri, $event->httpMethod, $params, $cookie = [], $files = [], $server = [], $content = null);
$app->request->withHeader($headers);
$app->route->setRequest($app->request);
// 执行请求
$resp = $app->run();
$body = $resp->getContent();
$status = $resp->getCode();
$header = $resp->getHeader();
// 调试注入
if ($app->env->get('app_trace', $app->config->get('app_trace'))) {
$app->debug->inject($resp, $body);
}
return [
'isBase64Encoded' => false,
'statusCode' => $status,
'headers' => $header,
'body' => $body,
];
}
public static function handlerStatic($path)
{
$filename = STATIC_PATH . $path;
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
$base64Encode = false;
$headers = [
'Content-Type' => '',
'Accept-Ranges' => 'bytes',
];
$body = $contents;
if (preg_match(BINARY_REG, $path)) {
$base64Encode = true;
$headers = [
'Content-Type' => '',
];
$body = base64_encode($contents);
}
return [
"isBase64Encoded" => $base64Encode,
"statusCode" => 200,
"headers" => $headers,
"body" => $body,
];
}
public function setBeginTime($value)
{
$this->beginTime = $value;
return $this;
}
public function setBeginMem($value)
{
$this->beginMem = $value;
return $this;
}
/**
* 初始化应用
* @access public
* @return void
*/
public function initialize()
{
if ($this->initialized) {
return;
}
$this->initialized = true;
$this->beginTime = microtime(true);
$this->beginMem = memory_get_usage();
$this->rootPath = dirname($this->appPath) . DIRECTORY_SEPARATOR;
// 修改写入路径
$this->runtimePath = defined('RUNTIME_PATH') ? RUNTIME_PATH : $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR;
$this->routePath = $this->rootPath . 'route' . DIRECTORY_SEPARATOR;
$this->configPath = $this->rootPath . 'config' . DIRECTORY_SEPARATOR;
static::setInstance($this);
$this->instance('app', $this);
if (is_file($this->rootPath . '.env')) {
$this->env->load($this->rootPath . '.env');
}
$this->configExt = $this->env->get('config_ext', '.php');
$this->config->set(include $this->thinkPath . 'convention.php');
$this->env->set([
'think_path' => $this->thinkPath,
'root_path' => $this->rootPath,
'app_path' => $this->appPath,
'config_path' => $this->configPath,
'route_path' => $this->routePath,
'runtime_path' => $this->runtimePath,
'extend_path' => $this->rootPath . 'extend' . DIRECTORY_SEPARATOR,
'vendor_path' => $this->rootPath . 'vendor' . DIRECTORY_SEPARATOR,
]);
$this->namespace = $this->env->get('app_namespace', $this->namespace);
$this->env->set('app_namespace', $this->namespace);
Loader::addNamespace($this->namespace, $this->appPath);
$this->init();
$this->suffix = $this->config('app.class_suffix');
$this->appDebug = $this->env->get('app_debug', $this->config('app.app_debug'));
$this->env->set('app_debug', $this->appDebug);
if (!$this->appDebug) {
ini_set('display_errors', 'Off');
} elseif (PHP_SAPI != 'cli') {
if (ob_get_level() > 0) {
$output = ob_get_clean();
}
ob_start();
if (!empty($output)) {
echo $output;
}
}
if ($this->config('app.exception_handle')) {
Error::setExceptionHandler($this->config('app.exception_handle'));
}
if (!empty($this->config('app.root_namespace'))) {
Loader::addNamespace($this->config('app.root_namespace'));
}
Loader::loadComposerAutoloadFiles();
Loader::addClassAlias($this->config->pull('alias'));
Db::init($this->config->pull('database'));
date_default_timezone_set($this->config('app.default_timezone'));
$this->loadLangPack();
$this->routeInit();
}
}
// 入口函数
function main_handler($event, $context)
{
return App::mainHandler($event, $context);
}
serverless cli部署
service: thinkphp51
provider:
name: tencent
runtime: Php7
credentials: ~/credentials
region: ap-shanghai
plugins:
- serverless-tencent-scf
functions:
thinkphp5:
handler: tencent.main_handler
memorySize: 128
timeout: 600
最后更新于 2020-04-24 09:06:21 并被添加「运行在 serverless 环境」标签,已有 793 位童鞋阅读过。
此处评论已关闭