PHP 7/8 运行时环境

PHP 运行时是负责安装 Web 服务代码及其依赖项和运行服务的软件堆栈。

如需为 App Engine 标准环境指定 PHP 7/8,请在 app.yaml 文件中声明运行时。例如:

runtime: phpVERSION

其中 VERSION 是 PHP MAJOR MINOR 版本号。例如,PHP 8.3 使用 83

如需了解其他受支持的 PHP 版本以及 PHP 版本对应的 Ubuntu 版本,请参阅运行时支持时间表

PHP 版本

PHP 运行时使用 app.yaml 文件中指定的版本的最新稳定版本。App Engine 会自动更新到新的补丁程序版本,但不会自动更新次要版本。

举例来说,您的应用可能部署在 PHP 7.3.0 上,并随后自动更新到 7.3.1 版,但它不会自动更新到 PHP 7.4.0。

应用启动

您需要部署前端控制器来处理所有请求路由。

以下示例展示了提供应用的不同方式:

  • 如果您的应用包含 public/index.phpindex.php 文件,App Engine 将使用此文件来提供您的应用。

    我们建议您使用 Laravel、Symfony 或 Slim 等框架,因为此类框架提供轻量级路由,允许快速编写和部署 PHP 应用。请参阅 Slim 前端控制器示例

    但是,如果要迁移旧版应用,请参阅以下示例 index.php 文件以导入所需的 PHP 文件,并手动实现前端控制器:

    switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
        case '/':
            require 'homepage.php';
            break;
        case '/contact.php':
            require 'contact.php';
            break;
        default:
            http_response_code(404);
            exit('Not Found');
    }
  • 如果您在 app.yaml 文件中指定了可选 entrypoint 元素,App Engine 将使用 entrypoint 元素中的命令来提供应用,而不是使用 public/index.phpindex.php

        entrypoint: serve path/to/my/front/controller.php
    

    entrypoint 字段使用内置的 serve 命令,此命令是 PHP 7/8 运行中的一个程序,用于在后台启动 php-fpm 实现和 Web 服务器。此网络服务器使用前端控制器设计模式将所有流量路由到提供的 PHP 文件。

    serve 命令有两个可选标志:

    • --workers=N:指定 php-fpm 工作器的数量 (N)。如果未设置 --workers 标志,则 serve 命令会根据可用内存量来估算工作器数量。为了获得最佳效果,请在 serve 命令和 max_concurrent_requests 元素上将 --workers 标志的值设置为同一数字。

    • --enable-dynamic-workers:指定您希望仅在需要时衍生的 php-fpm 工作器。默认设置是对 php-fpm 工作器使用静态政策。您可以使用 --workers=N 标志来更改最大衍生工作器数量。默认情况下,衍生的工作器的最大数量默认为静态政策设置的数量。

    可选标志必须位于前端控制器路径之前:

        entrypoint: serve --workers=2 --enable-dynamic-workers path/to/index.php
    
  • 您可以通过将 entrypoint 元素设置为工作器进程的文件路径来部署长时间运行的工作器进程:

        entrypoint: php long-running-worker-file.php
    

    如果 entrypoint 元素执行具有长时间运行进程(例如订阅了某个主题的 Pub/Sub 工作器)的脚本,请勿使用 serve 命令。

如需了解详情,请参阅 app.yaml 参考文档

已启用的扩展程序

PHP 7/8 运行时中已为 App Engine 启用以下扩展程序:

  • BCMath
  • bz2
  • Calendar
  • core
  • cgi
  • ctype
  • cURL
  • date
  • dba
  • dom
  • enchant
  • Exif
  • fcgi
  • fileinfo
  • filter
  • FTP
  • GD
  • gettext
  • GMP
  • hash
  • iconv
  • intl
  • json
  • LDAP
  • libxml
  • mbstring
  • MYSQLi
  • mysqlnd
  • MySQL (PDO)
  • OPcache
  • OpenSSL
  • PCNTL
  • pcre
  • PDO
  • pgsql
  • Phar
  • posix
  • PostgreSQL (PDO)
  • Reflection
  • session
  • Shmop
  • SimpleXML
  • SOAP
  • Sockets
  • sodium (PHP 8.x only, not available for PHP 7.x)
  • SPL
  • SQLite (PDO)
  • SQLite3
  • standard
  • test
  • tidy
  • tokenizer
  • XML
  • XMLreader
  • XMLrpc (PHP 7.x only, not available for PHP 8.x)
  • XMLwriter
  • XSL
  • zend
  • Zip
  • Zlib

可动态加载的扩展程序

以下扩展程序可通过配置 php.ini 实现动态加载:

如需启用这些扩展程序,请在 extension 文件中的 php.ini 下方添加扩展程序的指令,如下所示:

extension=memcached.so
extension=grpc.so
extension=protobuf.so
extension=mongodb.so
extension=imagick.so
extension=opencensus.so
extension=redis.so

环境变量

以下环境变量由运行时设置:

环境变量 说明
GAE_APPLICATION App Engine 应用的 ID。此 ID 以“region code~”为前缀,例如“e~”(对于在欧洲部署的应用)。
GAE_DEPLOYMENT_ID 当前部署的 ID。
GAE_ENV App Engine 环境。设置为 standard
GAE_INSTANCE 当前运行您的服务的实例的 ID。
GAE_MEMORY_MB 可供应用进程使用的内存量,以 MB 为单位。
GAE_RUNTIME app.yaml 文件中指定的运行时环境。
GAE_SERVICE app.yaml 文件中指定的服务名称。如果未指定服务名称,则将其设置为 default
GAE_VERSION 服务的当前版本标签。
GOOGLE_CLOUD_PROJECT 与您的应用关联的 Google Cloud 项目 ID。
PORT 接收 HTTP 请求的端口。
NODE_ENV(仅在 Node.js 运行时中可用) 当服务已部署时,将其设置为 production

您可以app.yaml 文件中定义其他环境变量,但不能替换上述值(NODE_ENV 除外)。

HTTPS 和转发代理

App Engine 在负载均衡器上终止 HTTPS 连接,并将请求转发到您的应用。某些应用需要确定原始请求 IP 地址和协议。用户的 IP 地址可在标准 X-Forwarded-For 标头中获取。对于需要此信息的应用,应将其 Web 框架配置为信任代理。

文件系统

运行时包括可写的 /tmp 目录,其他所有目录仅具有只读权限。对 /tmp 执行写入操作会占用系统内存。如需了解详情,请参阅 tempnam()sys_get_temp_dir() 支持

元数据服务器

应用的每个实例都可以使用 App Engine 元数据服务器来查询有关实例和项目的信息。

您可以通过以下端点访问元数据服务器:

  • http://metadata
  • http://metadata.google.internal

发送到元数据服务器的请求必须包含请求标头 Metadata-Flavor: Google。此标头表明请求是为了检索元数据值而发出的。

下表列出了您可以针对特定元数据发出 HTTP 请求的端点:

元数据端点 说明
/computeMetadata/v1/project/numeric-project-id 分配给项目的项目编号。
/computeMetadata/v1/project/project-id 分配给项目的项目 ID。
/computeMetadata/v1/instance/region 实例运行的区域。
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email 分配给项目的默认服务账号电子邮件地址。
/computeMetadata/v1/instance/service-accounts/default/ 列出项目的所有默认服务账号。
/computeMetadata/v1/instance/service-accounts/default/scopes 列出默认服务账号的所有受支持范围。
/computeMetadata/v1/instance/service-accounts/default/token 返回可用于向其他 Google Cloud API 验证您的应用的身份验证令牌。

例如,如需检索您的项目 ID,请向 http://metadata.google.internal/computeMetadata/v1/project/project-id 发送请求。

以下示例显示了如何使用 cURL 或 Google Cloud 客户端库调用元数据端点:

/**
 * Requests a key from the Metadata server using the Google Cloud SDK. Install
 * the Google Cloud SDK by running "composer install google/cloud"
 *
 * @param $metadataKey the key for the metadata server
 */
function request_metadata_using_google_cloud($metadataKey)
{
    $metadata = new Google\Cloud\Core\Compute\Metadata();
    $metadataValue = $metadata->get($metadataKey);

    return $metadataValue;
}

/**
 * Requests a key from the Metadata server using cURL.
 *
 * @param $metadataKey the key for the metadata server
 */
function request_metadata_using_curl($metadataKey)
{
    $url = 'http://metadata/computeMetadata/v1/' . $metadataKey;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Metadata-Flavor: Google'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    return curl_exec($ch);
}

会话

PHP 提供了一个会话管理层,使 Web 应用可以保留请求之间的用户状态信息。App Engine 中的会话的工作原理与任何其他 PHP 应用中的会话十分相似。

如需在用户的会话中设置变量,您可以使用以下代码:

session_start();
$_SESSION['Foo'] = 'Bar';

以下代码将在同一用户的后续请求下显示 Bar

session_start();
print $_SESSION['Foo']; // prints Bar

对于存在时间较长的会话,请使用替代存储服务,例如 Cloud SQL

专用 $_SERVER 键

PHP 在请求范围内提供了特殊的 $_SERVER[] 数组。除了标准 CGI 参数,App Engine 还额外添加了一些有用的键:

  • GAE_APPLICATION - 当前应用的 Google Cloud 项目 ID。
  • GAE_DEPLOYMENT_ID - 已部署源代码的 ID。
  • GAE_ENV - 运行您的应用的 App Engine 环境(标准或柔性)。
  • GAE_INSTANCE - 当前正在执行的实例名称。
  • GAE_MEMORY_MB - 应用进程可用的内存量,以 MB 为单位。
  • GAE_RUNTIME - 在 app.yaml 文件中指定的运行时,例如 php72。
  • GAE_SERVICE - 当前部署的服务名称。
  • GAE_VERSION - 当前部署的版本名称。
  • GOOGLE_CLOUD_PROJECT - Google Cloud 项目 ID。
  • HTTP_X_APPENGINE_CITY - 从中发起请求的城市的名称。例如,对于从美国山景城 (Mountain View) 发起的请求,其标头值可能为 mountain view。
  • HTTP_X_APPENGINE_CITYLATLONG - 从中发起请求的城市的纬度和经度。对于来自美国山景城的请求,此字符串可能类似于“37.386051,-122.083851”。
  • HTTP_X_APPENGINE_COUNTRY - 从中发起请求的国家/地区,用 ISO 3166-1 二位字母国家/地区代码表示。App Engine 通过客户端的 IP 地址来确定此代码。
  • HTTP_X_APPENGINE_HTTPS - 验证 HTTPS 使用情况。
  • HTTP_X_APPENGINE_REGION - 从中发起请求的地区的名称。此值仅在 X-Appengine-Country 中的国家/地区的上下文中有意义。例如,如果国家/地区为“US”,地区为“ca”,则“ca”表示“加利福尼亚州”,而不是加拿大。
  • HTTP_X_APPENGINE_USER_IP - 客户端 IP 地址。请注意,$_SERVER['HTTP_X_APPENGINE_USER_IP'] 是应用检索客户端 IP 地址的唯一方式。$_SERVER['REMOTE_ADDR'] 变量在 App Engine 中不可用。

带有新初始化默认值的指令

下表列出初始化默认值与 php.net 上的标准 PHP 解析器提供的默认值不同的指令。如需查找下表中未列出的指令的默认值,请参阅 php.ini 指令

指令 App Engine 中的默认值
expose_php Off
memory_limit -1
max_execution_time 0
error_reporting E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors Off
display_startup_errors Off
log_errors On
log_errors_max_len 0
ignore_repeated_errors Off
ignore_repeated_source Off
html_errors Off
opcache.enable On
opcache.validate_timestamps Off
opcache.memory_consumption 32

通过将这些默认指令添加到应用的 php.ini 文件中来替换它们。

tempnam()sys_get_temp_dir() 支持

App Engine 应用在安全沙盒中运行,其中只有 /tmp 目录可写入并存储在实例的 RAM 中。因此,App Engine 的 tempnam() 版本会返回内存中的临时文件,该文件可写入 Cloud Storage 存储桶等永久性存储解决方案。

以下示例演示了如何使用 file_put_contents()fwrite() 向内存中的临时文件写入内容。

<?php
$dir = sys_get_temp_dir();
$tmp = tempnam($dir, "foo");
file_put_contents($tmp, "hello");
$f = fopen($tmp, "a");
fwrite($f, " world");
fclose($f);
echo file_get_contents($tmp);

该示例的预期输出将为:

hello world

使用 Composer 管理依赖项

如需了解详情,请参阅“指定依赖项”页面