+
95
-

java如何与php-fpm通讯?

java如何与php-fpm通讯?

网友回复

+
15
-

java使用socket连接php-fpm,使用FastCGI协议直接通讯

FastCGI交互时序,从上到下,FCGI_BEGIN_REQUEST开始:

FastCGI协议:基于cgi,添加守护进程管理cgi程序,这样就不用像原始cgi那样,每个请求来fork新建cgi进程处理,处理完销毁进程的开销。

FastCGI如上交互时序,然后每条报文都有8byte报文头标识报文类型与长度

FCGI_BEGIN_REQUEST,FCGI_END_REQUEST是固定长度,确定请求的开始于结束

其他params,stdin,stdout等等都是不定长,每次发最大2byte 65536长度,由报文头的contentLength为2byte决定,可以连续多发,【必须】最后跟一个【同类型】contentLength为0的空报文标识这个类型的消息发送完毕

下面的代码可以远程ip调用,php-fpm配置改为监听0.0.0.0::9000

请求的param报文中确定访问的php文件与路径,确保php有权限,不行就试试777

import java.io.*;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.Map;

public class HelloWorld {

    public static void main(String[] args) throws Exception{
        Socket client=new Socket("127.0.0.1",9000);

        InputStream in=client.getInputStream();
        OutputStream out=client.getOutputStream();

        // protocol sequence
        int request_id=5678;
        //1.begin request
        byte[] begin_request_body = new byte[8];
        begin_request_body[0]=0; // roleB1
        begin_request_body[1]= fcgi_role.FCGI_RESPONDER; //roleB0
        begin_request_body[2]=0; // flags
        byte[] begin_request = fcgi.fcgiPacket(fcgi_request_type.FCGI_BEGIN_REQUEST,request_id,begin_request_body);
        System.out.println("FCGI_BEGIN_REQUEST:\n"+ Base64.getEncoder().encodeToString(begin_request));
        //2.params
        Map<String,String> params = new LinkedHashMap<>();
        params.put("GATEWAY_INTERFACE","FastCGI/1.0");
        params.put("REQUEST_METHOD","GET");
        params.put("SCRIPT_FILENAME","/index.php");
        params.put("SCRIPT_NAME","/index.php");
        params.put("QUERY_STRING","");
        params.put("REQUEST_URI","/index.php");
        params.put("DOCUMENT_URI","/index.php");
        params.put("SERVER_SOFTWARE","php/fcgiclient");
        params.put("REMOTE_ADDR","127.0.0.1");
        params.put("REMOTE_PORT","9985");
        params.put("SERVER_ADDR","127.0.0.1");
        params.put("SERVER_PORT","80");
        params.put("SERVER_NAME","DESKTOP-NCL22GF");
        params.put("SERVER_PROTOCOL","HTTP/1.1");
        params.put("CONTENT_TYPE","");
        params.put("CONTENT_LENGTH","0");

        System.out.println("\nparam pair base64:");
        ByteBuffer paramContainer = ByteBuffer.allocate(1024);
        for(String key:params.keySet()){
            byte[]BfwOnePair= fcgi.fcgiParam(key,params.get(key));
            paramContainer.put(onePair);

            System.out.println(key+" - "+params.get(key) +": "+Base64.getEncoder().encodeToString...

点击查看剩余70%

+
15
-

还可以使用fcgi4j这个java库

github地址https://github.com/Happyr/fcgi4j

使用方式

//create FastCGI connection
FCGIConnection connection = FCGIConnection.open();
connection.connect(new InetSocketAddress("localhost", 5672));

connection.beginRequest("/var/www/foobar.php");
connection.setRequestMethod("POST");

byte[] postData = "hello=world".getBytes();...

点击查看剩余70%

我知道答案,我要回答