前端时间在网上看见erlang 连接php-fpm的例子,自己跟到弄了一下,下面给我调试后的代码贴出来
我修正了原来代码的2处bug:
1、参数超过128字符出错
2、当php返回超过1024字节时候出错
文件名fastcgi.erl
- module(fastcgi). - compile(export_all).do_request(argv) -> env = [ { script_filename , e:/phpgame/game/gateway.php }, { websocket ,argv} ], io:format( argv msg: ~ts~n , [argv]), {ok, socket} = gen_tcp:connect( 127.0.0.1 , 9000 ,[binary, {packet, 0}, {active,true}], 10000 ), fcgi_send_record(socket, 1 , 1 , ), fcgi_send_record(socket, 4 , 1 , env), fcgi_send_record(socket, 4 , 1 , []), bin = phprespone(socket,[]), gen_tcp:close(socket), %% 原报文 = bin, = bin, %% 计算输出内容长度 dlen = contentlength - 52 , %% 获取内容 = str, io:fwrite( rs:~p~n ,[data]), {ok,data}.recv_msg(sock) -> receive {tcp, sock, bin} -> io:format( bin msg: ~p~n , [bin]), %% 原报文 = bin, = bin, %% 计算输出内容长度 dlen = contentlength - 52 , %% 获取内容 = str, io:fwrite( rs:~p~n ,[data]), {ok,data}; {tcp_closed,sock} -> io:format( socket close: ~p~n , [sock]); _other -> io:format( other msg: ~p~n , [_other]), recv_msg(sock) after 3000 -> io:format( time out.~n ) end. phprespone(sock,sofar) -> receive {tcp, sock, bin} -> phprespone(sock,[bin | sofar]); {tcp_closed,sock} -> list_to_binary(lists:reverse(sofar)); _other -> io:format( other msg: ~p~n , [_other]), phprespone(sock,sofar) after 3000 -> io:format( time out.~n ) end. %% 发送选项 fcgi_send_record(socket, type, requestid, namevaluelist) -> encodedrecord = fcgi_encode_record(type, requestid,namevaluelist), gen_tcp:send(socket, encodedrecord). %% 组包 fcgi_encode_record(type, requestid, namevaluelist) when is_list(namevaluelist) -> fcgi_encode_record(type, requestid,fcgi_encode_name_value_list(namevaluelist)); %% 判断contentdata是否满8字节,否则填充 fcgi_encode_record(type, requestid, contentdata) when is_binary(contentdata) -> contentlength = size(contentdata), paddinglength = if contentlength rem 8 == 0 -> 0; true -> 8 - (contentlength rem 8 ) end, %% 填充数据,每8字节组包 不足用0填充 paddingdata = , version = 1 , reserved = 0, . %% 将环境变量组成binary fcgi_encode_name_value_list(_namevaluelist = []) -> ; fcgi_encode_name_value_list(_namevaluelist = [{name, value} | tail]) -> . fcgi_encode_name_value(name, _value = undefined) -> fcgi_encode_name_value(name, ); fcgi_encode_name_value(name, value) when is_list(name) and is_list(value) -> namesize = length(name), namesizedata = , valuesize = length(value), if valuesize valuesizedata = ; valuesize > 127 -> valuesizedata = end, .
在windows 下启动php cgi可以这样做
php-cgi.exe -b 127.0.0.1:9000
在erlang shell中调用:
2> c(fastcgi).
{ok,fastcgi}
3> fastcgi:do_request({'uid':1}).
文笔不好,请大家多多包含