访问适用于 PHP 7/8 的旧版捆绑服务

本页面介绍如何安装捆绑服务并将其与适用于 App Engine 标准环境的 PHP 7/8 运行时搭配使用。您的应用可以通过 PHP 7/8 版 App Engine 服务 SDK 访问捆绑服务。

准备工作

  1. 请参阅您可以在 PHP 7/8 运行时中调用的旧版捆绑服务 API 列表

  2. 更新您的 app.yaml 文件,在其中添加以下代码行:

    app_engine_apis: true
    
  3. 如需测试 PHP 7/8 应用,您必须使用 gcloud app deploy 进行部署。

安装 PHP App Engine SDK

您可以在 GitHub 上的 appengine-php-sdk 中找到 PHP App Engine SDK。PHP 8.1+ 必须使用 2.1 或更高版本,PHP 7.x 必须使用 2.0.1 或更高版本。

您可以通过以下两种方式将 SDK 整合到项目中:

  1. 执行 Packagist 命令以将 SDK 添加到 composer.json 文件:

    composer require google/appengine-php-sdk
    
  2. 手动创建 composer.json 文件,其中包含以下详细信息:

    PHP 7/8

    {
        "require": {
            "google/appengine-php-sdk": "^2.1" // Or any later version
        }
    }
    

在 PHP 7/8 中,App Engine API 需要显式依赖项规范。如需了解如何添加 autoload.php,请参阅文档。

导入库

使用 use 运算符从可用 API 列表中导入所需的类。例如,Google\AppEngine\Api\AppIdentity\ClassName 可以使用语句导入:

use Google\AppEngine\Api\AppIdentity\ClassName;

迁移注意事项

应用身份

升级到 PHP 7/8 时,您无需更改应用的配置。App Identity API 的行为、功能和设置说明保持不变。如需了解详情,请参阅 API Identity 概览App Identity API 参考指南

Mail

PHP 7/8 Mail API 与 PHP 5 Mail API 大体相同,但在启用和停用邮件服务方面存在一些细微差别。以下部分介绍了两种运行时之间的差异。

Message 类

在 PHP 7/8 中,Message 类的工作方式与在 PHP 5.5 中相同,只是更新了 use 导入项。区别如下:

PHP 5.5

use google\appengine\api\mail\Message;

PHP 7/8

use Google\AppEngine\Api\Mail\Message;

如果您无法更改导入语句,则原始 PHP 5.5 导入语句也适用于 PHP 7/8。

邮件功能

在 PHP 5.5 中,原生 PHP mail() 函数已被 App Engine 的 Mail 函数过载。

在 PHP 7/8 中,App Engine 邮件功能默认不再过载,必须明确启用。通过这种新行为,您可以调整 Mail 函数的用途,以更好地满足您的需求。此变更还可让您了解当前正在用于所有邮件功能调用的实现。

如果您希望使用原生 PHP mail() 函数使用 App Engine Mail API 发送邮件,可以在 php.ini 文件中启用它,如下所示:

extension = mailparse.so
sendmail_path = "php ./vendor/google/appengine-php-sdk/src/Runtime/SendMail.php -t -i"

如上例所示,添加 mailparse 扩展程序以启用原生 PHP 邮件功能,并将 sendmail_path 运行时配置设置为 App Engine 邮件函数实现。启用此功能后,对 mail() 的所有调用都将完全与 PHP 5.5 中调用的方式相同。

请参阅发送邮件接收邮件指南以及 Mail API 参考指南了解详情。

Memcache

如需使用 PHP 7/8 的 Memcache,您需要明确添加 Memcache 库的声明。之前,PHP 5.5 的 Memcache 不需要进行显式声明。此显式声明可让您灵活地在原生 PHP Memcache 和 App Engine Memcache 之间切换。

PHP 7/8 Memcache 类的行为与 PHP 5 Memcache 类相同,但显式声明除外。如需了解详情,请参阅 Memcache 概览

PHP 5.5

PHP Memcache 5.5 示例:

$memcache = new Memcache();
return $memcache->get($key);

PHP 5.5 的 Memcached 示例:

$memcache = new Memcached();
$memcache->set('who', $request->get('who'));
return $twig->render('memcache.html.twig', [
    'who' => $request->get('who'),
    'count' => $memcache->increment('count', 1, 0),
    'host' => $request->getHost(),
]);

PHP 7/8

PHP 7/8 版 Memcache API 示例:

use Google\AppEngine\Api\Memcache\Memcache;

$memcache = new Memcache();
return $memcache->get($key);

PHP 7/8 的 Memcached API 示例:

use Google\AppEngine\Api\Memcache\Memcached;

$memcache = new Memcached();
$memcache->set('who', $request->get('who'));
return $twig->render('memcache.html.twig', [
    'who' => $request->get('who'),
    'count' => $memcache->increment('count', 1, 0),
    'host' => $request->getHost(),
]);

如果您更喜欢在 PHP 7/8 中使用 PHP 5 版 Memcache 的原始行为,则可以继续隐式调用 Memcache,方法是在 composer.json 文件中添加更多行。从 Composer 导入 appengine-php-sdk 软件包后,将选择启用的文件路径添加到 autoload 部分中的 files 元素:

PHP 7/8

{
  "require": {
    "google/appengine-php-sdk": "^2.1" // Or any later version
  },
  "autoload": {
    "files": [
    "./vendor/google/appengine-php-sdk/src/Api/Memcache/MemcacheOptIn.php"
    ]
  }
}

模块

升级到 PHP 7/8 时,您无需更改应用的配置。Modules API 的行为、功能和设置说明保持不变。如需了解详情,请参阅模块概览Modules API 参考指南

会话

PHP 7/8 会话的工作原理与 PHP 5.5 会话相同。但是,设置说明不同,因为 PHP 5.5 会话默认使用 MemcacheSessionHandler 类。

如需使用 PHP 7/8 会话,您必须向 session_set_save_handler() 注册 MemcacheSessionHandler 类,并配置 session.save_path 到 Memcache。在访问 Memcache 信息时,您还应选择加入 Memcache

例如:

PHP 7/8

ini_set('session.save_path', 'Google\AppEngine\Api\Memcache\Memcache');
session_set_save_handler(new Google\AppEngine\Ext\Session\MemcacheSessionHandler(), true);

如需了解详情,请参阅 Session API 参考指南

Task Queue

升级到 PHP 7/8 时,您无需更改应用的配置。任务队列的行为、功能和设置说明保持不变。如需了解详情,请参阅任务队列概览指南和 Task Queue API 参考指南中的“会话”部分。

URL Fetch

如需使用 PHP 7/8 的网址提取,您需要添加网址提取库的显式声明。之前,PHP 5 的网址提取服务不需要显式声明,而是隐式使用。

在 PHP 5 中,App Engine 的网址提取服务是 PHP 5.5 中提取互联网内容的唯一方法,因此访问互联网的大多数 PHP 5.5 函数已经过修补,自动使用 UrlFetch

在 PHP 7/8 中,原生 PHP 网络可以访问互联网,因此该自动修补不会完成。在某些情况下,您可以使用原始 UrlFetch 机制,尤其是提供用来识别 App Engine 应用的 X-Appengine-Inbound-Appid 请求标头的机制正在向 App Engine 应用发出请求的请求。

如需为 PHP 7/8 启用网址提取,您可以在流封装容器中使用显式声明,也可以直接使用 UrlFetch 类,如以下部分所述。

方案 1a。流处理程序

您可以启用 App Engine 的网址提取服务以向 http://https:// PHP 流处理程序发出 HTTP 请求。为此,请按以下说明操作:

  1. 使用 stream_wrapper_unregister() 取消注册适用于 HTTP(S) 的原生 PHP 流处理程序。
  2. 使用 stream_wrapper_register() 将 HTTP(S) 注册到 UrlFetchStream 类。
  3. 使用要用于流封装容器的配置调用 file_get_contents()

如需进行比较,请参阅 PHP 5 和 PHP 7/8 的等效示例:

PHP 5.5

...
$context = [
    'http' => [
        'method' => 'POST',
        'header' => $headers,
        'content' => http_build_query($data),
    ]
];
$context = stream_context_create($context);

// Using Url Fetch service. No option to use the native php stream wrapper.
$result = file_get_contents('http://example.com', false, $context);
echo $result;

PHP 7/8

use google\appengine\api\urlfetch\UrlFetchStream;
...
$context = [
    'http' => [
        'method' => 'POST',
        'header' => $headers,
        'content' => http_build_query($data),
    ]
];
$context = stream_context_create($context);

// Using the native php stream wrapper.
$result = file_get_contents('http://example.com', false, $context);
echo $result;

stream_wrapper_unregister("http");
stream_wrapper_register("http", "UrlFetchStream");

// Now using the Url Fetch service.
$result = file_get_contents('http://example.com', false, $context);
echo $result;

stream_wrapper_unregister("http");
stream_wrapper_restore("http");

// Now using the native php stream wrapper again.

方案 1b。使用流处理程序的 HTTP 响应标头

将 HTTP(S) 响应标头与流处理程序结合使用的说明与使用流处理程序的说明类似:

  1. 使用 stream_wrapper_unregister() 取消注册适用于 HTTP(S) 的原生 PHP 流处理程序。
  2. 使用 stream_wrapper_register() 将 HTTP(S) 注册到 UrlFetchStream 类。
  3. fopen()(而不是 file_get_contents())替换为您所需的配置。
  4. 调用 stream_get_meta_data() 并通过将 'wrapper_data 的元数据编入索引来提取响应标头信息。响应标头以类似于 PHP 5.5 中的 $http_response_header 的数组形式返回。

PHP 5.5

...
$context = [
    'http' => [
        'method' => 'POST',
        'header' => $headers,
        'content' => http_build_query($data),
    ]
];
$context = stream_context_create($context);

// Using file_get_contents and the Url Fetch service.
$result = file_get_contents('http://example.com', false, $context);

// Print Http Response Headers
print_r($http_response_header);

PHP 7/8

use google\appengine\api\urlfetch\UrlFetchStream;
...
$context = [
    'http' => [
        'method' => 'POST',
        'header' => $headers,
        'content' => http_build_query($data),
    ]
];
$context = stream_context_create($context);

stream_wrapper_unregister("http");
stream_wrapper_register("http", "UrlFetchStream");

// Now using fopen and the Url Fetch service.
$result = fopen('http://example.com', 'r', false, $context);

// Print Http Response Headers
$meta_data = stream_get_meta_data($result);
$headers = $meta_data['wrapper_data'];
print_r($headers);

stream_wrapper_unregister("http");
stream_wrapper_restore("http");

方法 2. UrlFetch 类

UrlFetch 类是一种自定义类,可提供更有针对性的方法,使用 网址 Fetch 服务处理较小的范围中的 HTTP(S) 请求。与流处理程序选项不同,UrlFetch 类不会替换从流封装容器兼容函数发出的所有 HTTP(S) 请求来使用 URL Fetch 服务。与流处理程序选项相比,UrlFetch 类配置也更简单,因为它不需要使用各种 PHP API,例如:

  • stream_context_create()
  • stream_wrapper_unregister()
  • stream_wrapper_register()
  • file_get_contents()

以下 UrlFetch 类示例与流处理程序示例等效:

PHP 7/8

use google\appengine\api\urlfetch\UrlFetch;
...
$urlfetch = new UrlFetch();
$result = $urlfetch->fetch($url, 'POST', $headers, http_build_query($data));
echo $result->getContent();

用户

升级到 PHP 7/8 时,您无需更改应用的配置。Users API 的行为、功能和设置说明保持不变。如需了解详情,请参阅 Users API 概览Users API 参考指南

社区提供的库

升级到 PHP 7/8 时,您可以使用社区提供的 API 处理 datastore

其他注意事项

  • 如需在 PHP 7/8 应用中测试旧版捆绑服务功能,您可以使用本地开发服务器。运行 dev_appserver.py 命令时,请将 --php_executable_path 参数设置为 PHP 7/8 可执行文件。请注意,这与 PHP 5 不同,PHP 5 需要 php-cgi 可执行文件。

    如果项目具有 composer.json 文件,请将 --php-composer-path 设置为 composer.phar 文件的路径。

  • 如需部署应用,请使用 gcloud app deploy 命令。

  • PHP 7/8 运行时中的日志记录遵循 Cloud Logging 中的日志记录标准。在 PHP 7/8 运行时中,应用日志不再与请求日志捆绑,而是在不同的记录中分隔。如需详细了解读取和写入日志,请参阅写入和查看日志指南

示例

如需查看将旧版捆绑服务与 PHP 搭配使用的示例,请下载代码示例