PHP 7.1:没有cURL与HTTP/2

问题描述:

我的问题不是要找出服务器是否支持HTTP/2(他们都这样做),但如何确保PHP正在使用HTTP/2与正确的cURL设置为CentOS中最新的PHP版本(由Remi的存储库构建)。我自己的回答解决了这方面的一些古怪问题。PHP 7.1:没有cURL与HTTP/2

我设置我的CentOS 7服务器支持HTTP/2与这一优良向导的帮助:Setting up HTTP/2 on your web server

所以我已经得到了最新版本,编译和安装他们和所有工作正常。页面与HTTP/2标题一起提供,完全按照它们应该的方式。

现在我想在我的PHP脚本中使用HTTP/2功能。主要通过以HTTP/2方式进行cURL调用。我发现我需要升级libcurl并使用特定的HTTP/2支持进行构建和编译。随着一些挫折,我得到了它的工作。

所以curl -V告诉我:

curl 7.55.0-DEV (x86_64-unknown-linux-gnu) libcurl/7.55.0-DEV OpenSSL/1.1.0f zlib/1.2.7 nghttp2/1.23.1 
Release-Date: [unreleased] 
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy 

太好了!

而且phpinfo()让我在新安装的OpenSSL的结合相同的版本(7.55.0-DEV),它是:

OpenSSL 1.1.0f 25 May 2017

而且Apache的,BTW:

Server version: Apache/2.4.26 (Unix) 
Server built: Jul 7 2017 09:47:22 

然而,当我用cURL调用写一个简单的PHP脚本,CURLOPT_HTTP_VERSION选项设置为CURL_HTTP_VERSION_2_0,如本例中所述:https://*.com/a/37146586/1005334,它告诉我se rver没有HTTP/2支持...

这怎么可能?

一件事我注意到,即将在phpinfo() OpenSSL的模块位仍然提到了我的老版本的OpenSSL(OpenSSL的1.0.1e-FIPS),虽然卷曲模块中提到的OpenSSL的版本规定的OpenSSL 1.1.0f。

我已经从Remi的仓库安装了PHP 7.1(它目前的版本是7.1.7),它是否是针对较旧的OpenSSL版本构建的,因此它不适用于我的新版本?我也在PHP/7中读取HTTP/2的支持不是很明显,但我认为它不应该是一个问题,对吧?

或者是OpenSSL不是问题,我应该看看其他地方,也许编译PHP从源头与一些预期的标志?

+0

[用PHP创建HTTP/2请求](https://*.com/q/37140780/1255289) – miken32

一些摆弄后的好处,似乎我可以打通一个PHP卷曲的呼叫与HTTP/2响应Remi的PHP软件包和新建的cURL/OpenSSL。

我用此片的代码来测试(从here截取):所需

if (curl_version()["features"] & CURL_VERSION_HTTP2 !== 0) { 
    $url = "https://www.google.com/"; 
    $ch = curl_init(); 
    curl_setopt_array($ch, [ 
     CURLOPT_URL   =>$url, 
     CURLOPT_HEADER   =>true, 
     CURLOPT_NOBODY   =>true, 
     CURLOPT_RETURNTRANSFER =>true, 
     CURLOPT_HTTP_VERSION =>CURL_HTTP_VERSION_2_0, 
    ]); 
    $response = curl_exec($ch); 
    if ($response !== false && strpos($response, "HTTP/2.0") === 0) { 
     echo "HTTP/2 support!"; 
    } elseif ($response !== false) { 
     echo "No HTTP/2 support on server."; 
    } else { 
     echo curl_error($ch); 
    } 
    curl_close($ch); 
} else { 
    echo "No HTTP/2 support on client."; 
} 

的调整,分别为:

CURLOPT_HTTP_VERSION => 3 

...和:

if ($response !== false && strpos($response, "HTTP/2") === 0) 

因此,而不是CURL_HTTP_VERSION_2_0作为cURL选项中的HTTP版本,我用3,这应该意味着相同,但显然PHP在使用CURL_HTTP_VERSION_2_0时没有选择正确的值。看看这个给出的原始反应,我注意到Google发回的是HTTP/2而不是HTTP/2.0

我希望这可以帮助别人!

我的存储库中的软件包是针对标准基础存储库构建的,因此OpenSSL 1.0.1e和Curl 7.29.0(使用NSS)。

所以,你必须重建其使用论文库一切采取的新功能(包括PHP)

+0

可能的重复我正在考虑它,但希望它不是必需的,因为我有Apache,cURL和OpenSSL一起玩。但是,似乎可以完成(请参阅我对自己问题的回答)。 – kasimir