如何在 PHP 中发送 HTTP/2 POST 请求
Posted
技术标签:
【中文标题】如何在 PHP 中发送 HTTP/2 POST 请求【英文标题】:How do I send a HTTP/2 POST request in PHP 【发布时间】:2016-04-08 23:44:53 【问题描述】:我在Sending HTTP/2 POST request in Ruby 发现了一个类似的问题 但我想用 php 更新我的服务器
此处描述的新 Apple 推送通知基于 HTTP/2 的 API:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html
任何具有 HTTP/2 经验的人都可以帮助我以 PHP 客户端的身份发出请求。
【问题讨论】:
【参考方案1】:查看我为此目的构建的 Apache 和 CLI PHP Docker 映像,它们将 HTTP/2 支持添加到官方 PHP 5.6 docker 库中。这消除了任何HTTP/2 client preface string missing or corrupt
错误。
一旦你有了合适的环境,在尝试了几个 PHP 的 JWS/JWT 库后,我发现 Spomky-Labs/jose 可以完美地与 APN 配合使用。
【讨论】:
【参考方案2】:PHP >= 5.5.24 的 CURL 扩展支持 HTTP/2。 (自this commit)
您还需要安装 libcurl(curl 函数使用的底层库)并启用 HTTP/2 支持。这意味着比 7.38.0 更新的 libcurl,但实际上,越新越好。 Libcurl 必须在编译时使用 --with-nghttp2
标志显式启用 HTTP/2 支持。
只需像通常使用的那样使用 curl,并通过传入 CURL_HTTP_VERSION_2_0
将 CURLOPT_HTTP_VERSION
选项设置为使用 HTTP/2。然后你将把请求升级到版本 2如果客户端和服务器都支持它。
在 PHP 5.5.24 之前,如果 libcurl 构建时支持 HTTP/2,您可以显式传入 CURL_HTTP_VERSION_2_0
的 int 值,因为 PHP 仍会将其传递给 libcurl。目前,它的值为3
——这不应该改变,但可以。
if (!defined('CURL_HTTP_VERSION_2_0'))
define('CURL_HTTP_VERSION_2_0', 3);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
【讨论】:
我尝试在 Mac 和 Linux 上安装 XAMPP 的 5.6.21 和 7.0.6 版本,但我总是收到此错误:HTTP/2 client preface string missing or corrupt. Hex dump for received bytes ...
。你知道我怎么能解决这个问题吗?我可以从命令行发送推送通知,但在 PHP 中它不起作用。
我想了解使用 HTTP/2 和 curl 7.38.0 的推送通知是否可以在共享主机环境中工作?由于安全原因,以前的共享主机提供商会阻止端口 2195 和 2196,因此无法使用 TCP 套接字进行推送通知。
@raj:这是一个完全独立的问题,不适合对答案发表评论......
这还需要 openSSL 1.0.2,尽管 1.0.1 现在已经 5 年了,而且还在继续,但它在 centOS 6 上无法通过 yum 更新获得。【参考方案3】:
PHP >= 5.5.24 不足以使用 curl 发出 HTTP/2 请求,即使定义了 CURL_HTTP_VERSION_2_0 也是如此。如果您尝试向 APNS(Apple Push Notification Service)发出请求,您将收到如下错误消息:
?@@?HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 504f5354202f332f6465766963652f616538666562613534
由于 curl 是 libcurl 的 binding,因此您还必须启用 curl 并启用 http/2。
有关示例代码,请参阅我的 answer 以了解关于 SO 的类似问题
安装步骤,可以参考tutorial
【讨论】:
谢谢!这行得通。虽然我使用CURLINFO_HEADER_OUT
检查了请求标头,但它显示HTTP/1.1
。但它现在可以工作了,以前没有工作过。
我有 PHP 5.6、curl 7.54(支持 HTTP2)和 OpenSSL 1.0.1 但 CURL_HTTP_VERSION_2_0
仍然未定义,有什么想法吗? Apple 在尝试连接时返回 Unexpected HTTP/1.x request
错误消息。
@Andrew 检查您的 curl OpenSSL 版本是否高于 1.0.1。我最终不必要地重新编译了我的 PHP 版本,最终发现 Apple APN 需要一个从不版本的 TLS。
@andreszs 我遇到了同样的问题,直到我用sudo apachectl restart
重新启动了apache【参考方案4】:
目前 PHP 中没有直接的 HTTP/2
支持。
有一个想法可以在未来直接向 PHP 添加这样的支持: https://wiki.php.net/ideas/php6#http2_support
第 3 方库 Guzzle https://github.com/guzzle/guzzle 支持 HTTP/2,如果安装了正确的 php 和 curl 版本:
use GuzzleHttp\Client;
$client = new Client();
$client->get('https://http2.akamai.com/demo/tile-0.png', [
'version' => 2.0,
'debug' => true,
]);
【讨论】:
以上是关于如何在 PHP 中发送 HTTP/2 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章