Curl 在 Nginx 和本地主机上从 PHP 起不起作用

Curl does not work from PHP on Nginx and localhost

当我通过 SSL(运行 nginx 1.9.4 on Windows 通过 WPN-XM 将来自本地 PHP 脚本的 Curl 请求发送到本地服务器时,浏览器是"waiting" 直到出现 504 错误。 PHP-fpm 可能已死,因为 Web 服务器不处理任何其他请求。

当我向生产服务器发送相同的请求时,它工作正常。

当我从命令行发送 Curl 请求时,它起作用了。

当我在网络浏览器中打开最终资源时,它就可以工作了。

我花了 4 个小时在谷歌上搜索和阅读 Stac Owerflow,但没有发现任何其他情况。

谢谢!


<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://webserver.local/resource");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // just on local
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // just on local
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
$response = curl_exec($ch);

此脚本不适用于 WPN-XM v0.8.6 的默认配置, 因为只有一个 php-cgi 进程在后台监听,但您的示例需要(至少)其中两个。 php-cgi 已被执行 curl 请求的脚本使用,因此 Nginx 无法将其转发到 php-cgi。这意味着您将首先 运行 进入带有加载指示器的空白页面,然后点击连接超时。

潜在的问题是 php-cgi 不会自动生成新进程(需要时)。这个问题在这里讨论:https://github.com/WPN-XM/WPN-XM/issues/323

有两种解决方案:

2016 年 3 月更新:

To solve the situation for the WPN-XM stack i've added php-cgi-spawn\spawn.exe by default. This allows to spawn multiple PHP daemons. The spawner will be used in PHP version below v7.1.

PHP v7.1 will have this solution implemented and provide better FCGI MultiPlexing out-of-the-box.


spawn-fcgi

第一个方案是修改start.bat。您只需将 spawn-fcgi 放在 php-cgi 前面,如下所示:

spawn-fcgi -f "%_dir%\php-cgi.exe" -a 127.0.0.1 -p 9100 -C 6 -F 4 -P "%_dir%..\temp\php.pid"

我不知道这个工具藏在哪里,也许某处有一个独立的下载,但它可能是 windows 的 lighttpd 发行版的一部分。 我想我会从源代码编译它并使其可用于 WPN-XM。

php 上游池

第二个解决方案需要两个小步骤来启动 PHP 工作池并 运行ning。

  • 第一步是修改 start.bat 文件以启动多个 php-cgi 守护进程,每个守护进程监听不同的端口。我们再添加一些 php-cgi starts:

    :start-php
        echo Starting PHP FastCGI...
    
        set PHP_FCGI_MAX_REQUESTS=0
        set PHP_FCGI_CHILDREN=4
    
        %HIDECONSOLE% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9100 -c %~dp0bin\php\php.ini
        %HIDECONSOLE% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9101 -c %~dp0bin\php\php.ini
        %HIDECONSOLE% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9102 -c %~dp0bin\php\php.ini
        %HIDECONSOLE% %~dp0bin\php\php-cgi.exe -b 127.0.0.1:9103 -c %~dp0bin\php\php.ini
    
  • 下一步是修改server\bin\nginx\conf\nginx.conf并激活php_pool,而不是使用单个上游。

    只需查找 fastcgi_pass php; 并将其更改为 fastcgi_pass php_pool;

此更改将激活以下已定义的上游池:

upstream php_pool {
    server 127.0.0.1:9100 weight=1 max_fails=3 fail_timeout=20s;
    server 127.0.0.1:9101 weight=1 max_fails=3 fail_timeout=20s;
    server 127.0.0.1:9102 weight=1 max_fails=3 fail_timeout=20s;
    server 127.0.0.1:9103 weight=1 max_fails=3 fail_timeout=20s;
}

就是这样。

运行 start.bat 然后你的 "curl post to localhost" 示例应该可以工作。