全部产品

PHP 函数入口

更新时间:2018-12-08 09:29:07

在函数计算中使用 PHP 编程,您需要定义一个 PHP 编写的函数作为入口。本文详细介绍了 PHP 的函数入口定义项。

函数入口概述

php 运行环境根据是否支持 HTTP 触发器分为 普通函数入口设置 HTTP 触发器 两种函数入口,为函数设置 HTTP 触发器后的函数入口形式会不同,这是为了方便处理发来的 HTTP request 请求。其中 普通函数入口 又分为 处理函数入口 initializer 入口

普通函数入口

处理函数入口

以下为一个最基本的函数入口示例:

  1. <?php
  2. function handler($event, $context) {
  3. return "hello world";
  4. }

函数名

handler 需要与创建函数时的 “handler” 字段相对应。例如,创建函数时指定的 “handler” 为 index.handler,函数计算则会加载 index.php 文件中定义的 handler 函数。

$event 参数

$event 参数是函数的输入参数,也是您调用函数时传入的数据,其数据类型是字符串(String)。PHP 函数直接使用您指定的 $event 参数,不会做任何预处理。您在函数中可以根据实际情况解析 $event。例如输入数据是一个 JSON String ,您可以转换成一个数组(array)。以下为一个参数解析示例:

  • 传入的 $event

    1. {
    2. "key": "value"
    3. }
  • 在 PHP 函数代码中如下解析 $event,返回结果则为 value

    1. <?php
    2. function handler($event, $context) {
    3. $eventObj = json_decode($event, $assoc = true);
    4. return $eventObj['key'];
    5. }

$context 参数

$context 参数中包含函数的运行时信息,例如请求 ID(requestId)与临时身份验证 securityToken 等,便于您在代码中使用这些信息。$context 数据类型类型是 Array$context 定义如下所示:

  1. [
  2. 'requestId' => 'b1c5100f-819d-c421-3a5e-7782a27d8a33',
  3. 'credentials' => [
  4. 'accessKeyId' => 'STS.access_key_id',
  5. 'accessKeySecret' => 'access_key_secret',
  6. 'securityToken' => 'security_token',
  7. ],
  8. 'function' => [
  9. 'name' => 'my-func',
  10. 'handler' => 'index.handler',
  11. 'memory' => 128,
  12. 'timeout' => 10,
  13. ],
  14. 'service' =>[
  15. 'name' => 'my-service',
  16. 'logProject' => 'my-log-project',
  17. 'logStore' => 'my-log-store',
  18. 'qualifier' => 'qualifier',
  19. 'versionId' => '1',
  20. 'initializer' => 'index.initializer',
  21. 'initializationTimeout' => 10,
  22. ],
  23. 'region' => 'cn-shanghai',
  24. 'accountId' => '123456'
  25. ]

以上定义中,$context 中包含了六个字段的信息:

参数 类型 描述
requestId String 当前调用请求的唯一 ID,常用于问题复查或者历史调用计数等。
function Array 当前调用的函数的基本信息,如函数名、函数入口、函数内存和超时时间等。
credentials Array 函数计算服务通过扮演您提供的 服务角色 获得的一组临时密钥 securityToken,每 15 分钟更新一次。您可以在函数代码中使用临时密钥去访问其他阿里云服务,例如 OSS,避免您将重要的身份凭证 AccessKey 写死在函数代码里。
service Array 当前调用的函数所在的服务的信息,包括服务名称,接入的日志服务的 logProject 和 logStore 信息, service的版本信息qualifier和version_id,qualifier表示调用函数时指定的service版本或别名,version_id表示实际调用的service版本。
region String 当前调用的函数所在地域,如 cn-shanghai。更多详情,请参阅 地域与可用区
accountId String 当前调用函数用户的阿里云账号 ID。更多详情,请参阅 获取账号ID

普通函数入口示例

临时密钥用于辨识请求者身份和权限,在访问其他服务,例如 OSS 时,您必须设置 securityToken。下面的示例 PHP 代码使用临时密钥,向 OSS 的一个 Bucket 上传了一份 TXT 文件:

  1. <?php
  2. use OSS\OssClient;
  3. function handler($event, $context) {
  4. $accessKeyId = $context["credentials"]["accessKeyId"];
  5. $accessKeySecret = $context["credentials"]["accessKeySecret"];
  6. $securityToken = $context["credentials"]["securityToken"];
  7. $endpoint = "oss-cn-shenzhen.aliyuncs.com";
  8. $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken);
  9. $bucket = "my-bucket";
  10. $object = "php.txt";
  11. $content = "Hello fc.";
  12. try {
  13. $ossClient->putObject($bucket, $object, $content);
  14. } catch (OssException $e) {
  15. print($e->getMessage());
  16. }
  17. return 'sucess';
  18. };

initializer 入口

一个最简单的 initializer 定义如下:

  1. <?php
  2. function my_initializer($context) {
  3. $logger = $GLOBALS['fcLogger'];
  4. $logger->info("hello world");
  5. }
  6. ?>

initializer 函数名

  • my_initializer 需要与添加 initializer 函数时的 “initializer” 字段相对应:例如创建函数时指定的 initializer 入口 为 main.my_initializer,那么函数计算在配置 initializer 功能后会首先加载 main.php 中定义的 my_initializer 函数。

initializer 特点

  • initializer 输入参数只有 context,具体含义和上文描述的处理函数中相关参数的含义是一致的。
  • context 中 initializerinitializationTimeout 两个信息是为 initializer 设计的,当使用 initializer 功能时,会被设置为用户创建函数时所设置的值,否则为空,且不生效。
  • 无返回值。在函数末尾增加 return 操作是无效的。

HTTP 触发器的函数入口

设置了 HTTP 触发器的函数入口与其他触发器要求的函数入口不同,以下为一个基本的 HTTP 触发器规定的函数入口定义:

  1. <?php
  2. use RingCentral\Psr7\Response;
  3. function handler($request, $context): Response{
  4. /*
  5. $body = $request->getBody()->getContents();
  6. $queries = $request->getQueryParams();
  7. $method = $request->getMethod();
  8. $headers = $request->getHeaders();
  9. $path = $request->getAttribute("path");
  10. $requestURI = $request->getAttribute("requestURI");
  11. $clientIP = $request->getAttribute("clientIP");
  12. */
  13. return new Response(
  14. 200,
  15. array(
  16. "custom_header1" => "v1",
  17. "custom_header2" => ["v2", "v3"],
  18. "Set-Cookie" => urlencode("test php") . '=' . urlencode('test;more')
  19. ),
  20. "hello world"
  21. );
  22. }

注意:强烈建议您所有返回的headers都放在构造Response对象的参数里面,如上面示例,不要单独使用能改变header的方法,比如 header 、 setcookie 等

$context 参数

$context 参数与普通函数接口的 $context 接口相同。

$request 参数

$request 遵循 PSR(HTTP message interfaces)标准。更多详情,请参阅 PSR-7-http-message。具体的代码定义遵循 PSR Http Message

如下为 $request 参数携带的可用信息示例:

  1. <?php
  2. $queries = $request->getQueryParams();
  3. $method = $request->getMethod();
  4. $headers = $request->getHeaders();
  5. $path = $request->getAttribute("path");
  6. $requestURI = $request->getAttribute("requestURI");
  7. $clientIP = $request->getAttribute("clientIP");
  8. $body = $request->getBody()->getContents();
参数 类型 描述
$headers Array 存放来自 HTTP 客户端的键值对,键值对中的值(value)为数组(Array)类型,遵循 PSR-7 标准。
$path String HTTP URL 中的 path。
$queries Array 存放来自 HTTP URL 中的 query 部分的键值对,键值对中的值(value)可以为字符串或是数组。
$method String HTTP 方法。
$clientIP String HTTP 客户端的 IP 地址。
$requestURI String 请求中除 host 以外的 url。
$body String HTTP 请求中的 body 数据。

说明
函数计算会默认使用一些系统定义字段,不支持自定义。因此,您的 Headers 的 key 中不能使用系统定义字段:accept-encodingconnectionkeep-aliveproxy-authorizationtetrailertransfer-encoding 以及以 x-fc- 开头的字段。

$response 参数

$response 遵循 PSR(HTTP message interfaces)标准。以下为 Response 构造示例:

  1. <?php
  2. /**
  3. * @param int $status Status code for the response, if any.
  4. * @param array $headers Headers for the response, if any.
  5. * @param mixed $body Stream body.
  6. */
  7. public function __construct(
  8. $status = 200,
  9. array $headers = array(),
  10. $body = null,
  11. )
  12. {
  13. //...
  14. }

body 可以是 String,也可以是 Stream。Stream 的 body 必须要实现 PSR-7-http-message 中的 StreamInterface

HTTP 触发器的函数入口示例

以下示例示范了如何使用 HTTP 触发器的函数入口中的 $requestResponse

  1. use RingCentral\Psr7\Response;
  2. function php_http_handler($request, $context): Response{
  3. $body = $request->getBody()->getContents();
  4. $queries = $request->getQueryParams();
  5. $method = $request->getMethod();
  6. $headers = $request->getHeaders();
  7. $path = $request->getAttribute("path");
  8. $requestURI = $request->getAttribute("requestURI");
  9. $clientIP = $request->getAttribute("clientIP");
  10. $params = array(
  11. 'method' => $method,
  12. 'clientIP' => $clientIP,
  13. 'requestURI' => $requestURI,
  14. 'path' => $path,
  15. 'queriesMap' => $queries,
  16. 'headersMap' => $headers,
  17. 'body' => $body,
  18. );
  19. $respHeaders = array('Content-Type' => 'application/json');
  20. $respBody = json_encode($params);
  21. return new Response(200, $respHeaders, $respBody);
  22. }

HTTP 触发器的函数入口限制项

Request 限制项

如果 HTTP 触发器的函数入口 Request 超过以下限制,会抛出 400 状态码和 InvalidArgument 错误码

参数 限制 HTTP 状态码 错误码
headers headers 中的所有键值对(key 和 value)的大小不能超过 4 KB。 400 InvalidArgument
path path 以及所有 query 参数(params)的大小不能超过 4 KB。
body HTTP body 的大小不能超过 6 MB。

Response 限制项

如果超过以下限制,会抛出 502 状态码和 BadResponse 错误码。

参数 限制 HTTP 状态码 错误码
headers headers 中的所有键值对(key 和 value)的大小不能超过 4 KB。 502 BadResponse
body HTTP body 的大小不能超过 6 MB。

参考链接

有关 PHP 运行环境的详细信息,请参阅 PHP 运行环境