简体   繁体   English

在Nginx和localhost上,Curl无法使用PHP

[英]Curl does not work from PHP on Nginx and localhost

When I send the Curl request from local PHP script to the local server via SSL (running nginx 1.9.4 on Windows via WPN-XM) then the browser is "waiting" until it gets the 504 error. 当我通过SSL将本地PHP脚本的Curl请求发送到本地服务器(通过WPN-XM在Windows上运行nginx 1.9.4)时,浏览器“等待”直到它出现504错误。 The PHP-fpm is probably dead, because the web server does not proccess any other request. PHP-fpm可能已经死了,因为Web服务器不会处理任何其他请求。

When I send the same request to the production server it works correctly. 当我向生产服务器发送相同的请求时,它可以正常工作。

When I send the Curl request from command line, then it works. 当我从命令行发送Curl请求时,它可以工作。

When I open the final resource in web browser then it works. 当我在Web浏览器中打开最终资源时,它可以工作。

I have spent 4 hours googling and reading Stac Owerflow, but did not find any other situation like I have. 我花了4个小时谷歌搜索和阅读Stac Owerflow,但没有找到像我这样的任何其他情况。

Thanks! 谢谢!


<?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);

This script will not work with the default configuration of WPN-XM v0.8.6, because there is only one php-cgi process listening in the background, but your example needs (at least) two of them. 此脚本不适用于WPN-XM v0.8.6的默认配置,因为后台只有一个php-cgi进程正在侦听,但您的示例需要(至少)其中两个。 php-cgi is already used by the script doing the curl request and so Nginx is unable to forward it to php-cgi. 执行curl请求的脚本已经使用了php-cgi,因此Nginx无法将其转发到php-cgi。 That means you will first run into a blank page with a loading indicator and then hit the connection timeout. 这意味着您将首先遇到带有加载指示符的空白页面,然后点击连接超时。

The underlying problem is that php-cgi does not automatically spawn new processes (when needed). 根本问题是php-cgi不会自动生成新进程(需要时)。 The issue is discussed over here: https://github.com/WPN-XM/WPN-XM/issues/323 这个问题在这里讨论: https//github.com/WPN-XM/WPN-XM/issues/323

There are two solutions: 有两种解决方案:

Update 03-2016: 更新03-2016:

To solve the situation for the WPN-XM stack i've added php-cgi-spawn\\spawn.exe by default. 为了解决WPN-XM堆栈的情况,我默认添加了php-cgi-spawn\\spawn.exe This allows to spawn multiple PHP daemons. 这允许生成多个PHP守护进程。 The spawner will be used in PHP version below v7.1. Spawner将在v7.1以下的PHP版本中使用。

PHP v7.1 will have this solution implemented and provide better FCGI MultiPlexing out-of-the-box. PHP v7.1将实现此解决方案,并提供更好的FCGI MultiPlexing开箱即用。


spawn-fcgi 产卵-FCGI

The first solution is a modification to start.bat . 第一个解决方案是对start.bat的修改。 You would simply put spawn-fcgi in front of php-cgi, like so: 你只需将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"

I have no clue where this tool is hiding, maybe there is a standalone download somewhere, but its possibly part of the lighttpd distribution for windows. 我不知道这个工具隐藏在哪里,也许在某处有一个独立的下载,但它可能是windows的lighttpd发行版的一部分。 I think i will compile it from source and make it available for WPN-XM. 我想我会从源代码编译它并使它可用于WPN-XM。

php upstream pool php上游池

The second solution needs two small steps to get a PHP worker pool up and running. 第二个解决方案需要两个小步骤才能启动并运行PHP工作池。

  • The first step is to alter the start.bat file to start multiple php-cgi daemons, each listening at a different port. 第一步是更改start.bat文件以启动多个php-cgi守护进程,每个守护程序在不同的端口进行侦听。 We add some more php-cgi starts: 我们再添加一些php-cgi开头:

     :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 
  • The next step is to modify server\\bin\\nginx\\conf\\nginx.conf and activate the php_pool , instead of using the single upstream. 下一步是修改server\\bin\\nginx\\conf\\nginx.conf并激活php_pool ,而不是使用单个上游。

    Simply look for fastcgi_pass php; 只需查看fastcgi_pass php; and change it to fastcgi_pass php_pool; 并将其更改为fastcgi_pass php_pool; .

This change will activate the following upstream pool, which is already defined: 此更改将激活以下上游池,该池已定义:

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;
}

That's all. 就这样。

Run start.bat and then your "curl post to localhost" example should work. 运行start.bat然后你的“curl post to localhost”示例应该可行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM