spawn-fcgi php-fpm,搞不清FastCgi与PHP-fpm之间是个什么样的关系

补充前面大牛的回答,执行 man php-cgi:

NAME

php - PHP Command Line Interface 'CLI'

php-cgi - PHP Common Gateway Interface 'CGI' command

我认为php-cgi 是 PHP解释器 + CGI规范的实现。

下面代码,用node承担web服务器的责任,解析 http header为环境变量后通过管道转发到 php-cgi:

/**

* 测试使用 php-cgi

*/

var path = require("path");

const http = require('http');

var os = require("os"),

spawn = require('child_process').spawn

;

var Me = {

bin:"php-cgi"

,env:{

'SERVER_SOFTWARE':"nodejs"

,'SERVER_PROTOCOL':"HTTP/1.1"

,'GATEWAY_INTERFACE':"CGI/1.1"

,'SERVER_NAME':os.hostname()

,'REDIRECT_STATUS_ENV':0

},setEnv:function(env) {

for(var e in env) {

Me.env[e] = env[e];

}

},newRequestParams:function() {

var reqEnv = {};

for(var keys = Object.keys(Me.env), l = keys.length; l; --l) {

reqEnv[ keys[l-1] ] = Me.env[ keys[l-1] ];

}

return reqEnv;

},paramsForRequest:function(req, reqEnv) {

if (typeof(reqEnv) == "undefined") reqEnv = Me.newRequestParams();

reqdata = require("url").parse(req.url,true);

//set environment variables for this request

reqEnv['SCRIPT_NAME'] = reqdata.pathname;

reqEnv['PATH_INFO'] = path.normalize(reqEnv['DOCUMENT_ROOT']+reqdata.pathname);

reqEnv['PATH_TRANSLATED'] = path.normalize(reqEnv['DOCUMENT_ROOT']+reqdata.pathname);

reqEnv['QUERY_STRING'] = '';

reqEnv['REDIRCET_STATUS'] = 200;

for(var p in reqdata.query) {

reqEnv['QUERY_STRING'] += p+"="+encodeURIComponent(reqdata.query[p])+"&";

}

reqEnv['REQUEST_METHOD'] = req.method;

//add request headers, "User-Agent" -> "HTTP_USER_AGENT"

for (var header in req.headers) {

reqEnv['HTTP_' + header.toUpperCase().split("-").join("_")] = req.headers[header];

}

//copy in additional special headers..

if ('content-length' in req.headers) {

reqEnv['CONTENT_LENGTH'] = req.headers['content-length'];

}

if ('content-type' in req.headers) {

reqEnv['CONTENT_TYPE'] = req.headers['content-type'];

}

if ('authorization' in req.headers) {

reqEnv['AUTH_TYPE'] = req.headers.authorization.split(' ')[0];

}

return reqEnv;

},detectBinary:function() {

if (process.platform == 'win32') {

//detect a local "portable" php install.

Me.bin = require("php-bin-win32").bin;

}

/**

* This is an automatic function, will add a function you can override later on.

*/

},serveResponse:function(req, res, reqEnv, params) {

if (typeof(params) == "undefined") params = {};

var cgi = spawn(Me.bin, [], {

'env': reqEnv

});

console.log("===========REQ ENV=============");

console.log(reqEnv);

console.log("\n");

req.pipe(cgi.stdin);

if (params['sterr']) {

cgi.stderr.on('data',params.sterr);

} else {

cgi.stderr.on('data',function(data) {

console.log("cgi error:"+data.toString());

});

}

var headersSent = false;

cgi.stdout.on('data',function(data) {

if (headersSent) {

//stream data to browser as soon as it is available.

//console.log(data.toString());

res.write(data);

} else {

var lines = data.toString().split("\r\n");

//set headers until you get a blank line...

for(var l=0;l

if (lines[l] == "") {

if (!res.getHeader("content-length")) {

//stream the output

res.setHeader('Transfer-Encoding', 'chunked');

}

res.writeHead(200);

headersSent = true;

res.write(lines.slice(l+1).join('\r\n'));

break;

} else {

//set header

var header = lines[l].split(":");

res.setHeader(header[0], header[1]||'');

}

}

}

});

cgi.stdout.on('end',function() {

res.end();

});

}

}

var phpCGI=Me

const server = http.createServer((req, res) => {

phpCGI.detectBinary();//on windows get a portable php to run.

phpCGI.env['DOCUMENT_ROOT'] = __dirname+path.sep;

phpCGI.serveResponse(req, res, phpCGI.paramsForRequest(req));

});

server.on('clientError', (err, socket) => {

socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');

});

console.log("listen http://127.0.0.1:8000")

server.listen(8000);

PS:配置

cgi.force_redirect = 0

所以综上所述: php-cgi = php + cgi 实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值