PHP 7.4 现已正式发布。

PHP 7 运行时环境

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

适用于 App Engine 标准环境的 PHP 7 运行时在 app.yaml 文件中进行声明:

PHP 7.2

runtime: php72

PHP 7.3

runtime: php73

PHP 7.4

runtime: php74

PHP 版本

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

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

应用启动

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

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

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

    我们建议您使用 LaravelSymfonySlim 等框架,因为此类框架提供轻量级路由,允许快速编写和部署 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 运行时中启动 php-fpm 实现和后台 Web 服务器的程序。此 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 运行时中已为 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
  • SPL
  • SQLite (PDO)
  • SQLite3
  • standard
  • test
  • tidy
  • tokenizer
  • XML
  • XMLreader
  • XMLrpc
  • 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
extension=stackdriver_debugger.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 与您的应用关联的 Cloud 项目 ID。
PORT 接收 HTTP 请求的端口。

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

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

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

元数据端点 说明
/computeMetadata/v1/project/numeric-project-id 分配给项目的项目编号。
/computeMetadata/v1/project/project-id 分配给项目的项目 ID。
/computeMetadata/v1/instance/zone 实例运行的区域。
/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 解析器提供的默认值不同。

指令 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 管理依赖项

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