设为首页收藏本站

Erlang中文论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 29126|回复: 2
打印 上一主题 下一主题

Erlang与PHP通信

[复制链接]
跳转到指定楼层
楼主
发表于 2013-10-19 18:00:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
e2p.erl
  1. %% Author: [email protected]
  2. %% Created: 2011-5-5
  3. %% Description: TODO: Add description to e2p
  4. -module(e2p). % 定义模块名


  5. %% 对外公开的方法,要用列表[MethodName1/ArgNum,MethodName2/ArgNum,...]的形式。
  6. %% MethodName1为方法名
  7. %% /ArgNum 为方法要几个参数
  8. -export([request_url/0, request_url/3, request_url/5]).

  9. % -compile(export_all). %向外公布所有方法

  10. %% 发送请求
  11. request_url() ->
  12.         Url = "/phperlang/gateway.php",
  13.         SendMethod = "GET",
  14.         %Argument = [{"username","zengfeng"},{"password", "123456"},{"hello","yes"}],
  15.         %Argument = [{"username","zengfeng"}],
  16.         %Argument = [],
  17.         %Argument = ["user=aaaaa", "arg=bbbbbbbbbb","b=111111" ],
  18.         Argument = ["msg=ok&username=zengfeng&password=123456"]

  19.         request_url(Url, SendMethod, Argument).

  20. %% 发送请求
  21. %% @param Url 请求Url
  22. %% @param SendMethod 发送方式
  23. %% @param Argument 参数
  24. request_url(Url, SendMethod, Argument) ->
  25.         Host = "127.0.0.1",
  26.         Port = 80,
  27.         request_url(Host, Port, Url, SendMethod,Argument).

  28. %% 发送请求
  29. %% @param Host 服务器地址http://erlide.sourceforge.net/update
  30. %% @param Port 服务器端口
  31. %% @param Url 请求Url
  32. %% @param SendMethod 发送方式
  33. %% @param Argument 参数
  34. request_url(Host, Port, Url, SendMethod, Argument) ->
  35.         {ok, Socket} = gen_tcp:connect(Host, Port, [binary, {packet, 0}]), %连接服务器,如果Port是80就表示访问一个网站

  36.         %取得请求头内容
  37.         RequestHead = get_request_head(Url, SendMethod, Argument),
  38.         %RequestHead = "POST /phperlang/gateway.php?a=1&a2=2 HTTP/1.0\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:84\r\nConnection:close\r\n\r\narr=array('key1' => 'value1', 'key2' = 'value2')&username=zengfeng75&password=123456",

  39.         ok = gen_tcp:send(Socket, list_to_binary(RequestHead)),  %向服务器发送请求
  40.         receive_data(Socket, []). %接收服务器返回的数据

  41. %% 取得请求头内容, 如果不带参数
  42. %% @param Url 请求Url
  43. %% @param SendMethod 发送方式
  44. %% @param Argument 参数
  45. get_request_head_method(Url, SendMethod, []) ->
  46.         %第一行,请求方式和协议
  47.         HeadLine_1 = string:join([SendMethod, Url, "HTTP/1.0\r\n"], " "),
  48.         [HeadLine_1,"\r\n"];

  49. %% 取得请求头内容, 带参数,如果是以GET方式发送
  50. %% @param Url 请求Url
  51. %% @param SendMethod 发送方式
  52. %% @param Argument 参数
  53. get_request_head_method(Url, "GET", Argument) ->
  54.         ArgumentStr = arguments_join(Argument),
  55.         UrlAndArgs = string:join([Url, ArgumentStr], "?"),
  56.         %第一行,请求方式和协议
  57.         HeadLine_1 = string:join(["GET", UrlAndArgs, "HTTP/1.0\r\n"], " "),
  58.         [HeadLine_1, "\r\n"];

  59. %% 取得请求头内容, 带参数,如果是以POST方式发送
  60. %% @param Url 请求Url
  61. %% @param SendMethod 发送方式
  62. %% @param Argument 参数
  63. get_request_head_method(Url, "POST", Argument) ->
  64.         %第一行,请求方式和协议
  65.         HeadLine_1 = string:join(["POST", Url, "HTTP/1.0\r\n"], " "),
  66.         ArgumentStr = arguments_join(Argument), %处理参数为一个字符串
  67.         ArgumentStrLength = size(list_to_binary(ArgumentStr)), %取得要发送参数的总长度,如果是POST就要向服务说明发送的内容有多长Content-Length


  68.         [HeadLine_1,
  69.         "Content-Type:application/x-www-form-urlencoded\r\n",
  70.         string:join(["Content-Length:",integer_to_list(ArgumentStrLength),"\r\n"],""),
  71.         "Connection:close\r\n\r\n",
  72.         ArgumentStr
  73.         ].

  74. %% 取得请求头内容
  75. %% @param Url 请求Url
  76. %% @param SendMethod 发送方式
  77. %% @param Argument 参数
  78. get_request_head(Url, SendMethod, Argument) ->
  79.         get_request_head_method(Url, SendMethod, Argument).

  80. %% 合并参数
  81. arguments_join([]) -> [];
  82. %% 合并参数, 当参数是元组时如[{"username","zengfeng"}, {"passowrd", "123455"}]
  83. arguments_join([Head | _T] = L) when is_tuple(Head) ->
  84.         List = argument_join_key_value(L, []),  %合并参数的key和value
  85.         %io:format("arguments_join's List:~p~n", [List]),
  86.         arguments_join(List); %继续进行合并


  87. %% 合并参数, 当参数是列表时如["username=zengfeng", "password=1234"]
  88. %% 将会返回这种方试 "username=zengfeng&password=1234"
  89. arguments_join([Head | T] = L) ->
  90.         %io:format("arguments_join's T:~p~n", [T]),
  91.         case T of
  92.                 [] -> Head;
  93.                 _Other ->
  94.                         io:format("========================~n"),
  95.                                string:join(L, "&")
  96.         end.


  97. %合并参数的key和value 如[{"username","zengfeng"}, {"passowrd", "123455"}]
  98. %% 将会返回这种方试 ["username=zengfeng", "password=1234"]
  99. argument_join_key_value([{Key, Value} | T], Result) ->
  100.         %io:format("Result= ~p~n",[Result]),
  101.         case T of
  102.                 [] ->
  103.                         io:format("[]------------~n"),
  104.                         [(string:join([Key, Value], "="))| Result];               
  105.                 [{_Key, _Value} | _T] ->
  106.                         io:format("true----------~n"),
  107.                                argument_join_key_value(T, [(string:join([Key, Value], "=")) | Result])
  108.         end.






  109. %%接收数据
  110. receive_data(Socket, SoFar) ->
  111.         receive
  112.                 {tcp, Socket, Bin} ->
  113.                         receive_data(Socket, [Bin | SoFar]);
  114.                 {tcp_closed, Socket} ->
  115.                         Content = list_to_binary(lists:reverse(SoFar)), %此时的内容会包含PHP服务器发来的一些头
  116.                         %io:format("~p~n", [Content]),
  117.                         %<<_Head:1480, Data/binary>> = Content,
  118.                         get_content(Content) %将会把头去掉,得到PHP返回的输出
  119.         after 5000 -> %如果超时5秒就结束
  120.                         io:format("over time5000"),
  121.                         receive_data_over_time5000
  122.         end.

  123. %% 取得去掉头的数据
  124. get_content(Data) ->
  125.         %% 取得去掉头的数据,先试着头长度为165.为会如果正文内容长度超过8000时,头内容就不会变
  126.         split_content(Data, 165).

  127. %% 取得去掉头的数据
  128. split_content(Data, StartLength) when StartLength =:= 165 ->
  129.         {B1, B2} = split_binary(Data, StartLength),
  130.         {_B1_1, B1_2} = split_binary(B1, (StartLength - 27)),
  131.         HeadEnd = <<"Content-Type: text/html\r\n\r\n">>,
  132.         if
  133.                 B1_2 =:= HeadEnd ->
  134.                         B2;
  135.                 B1_2 =/= HeadEnd ->
  136.                         split_content(Data, 180)
  137.         end;
  138. %% 取得去掉头的数据
  139. split_content(Data, StartLength) ->
  140.         {B1, B2} = split_binary(Data, StartLength),
  141.         {_B1_1, B1_2} = split_binary(B1, (StartLength - 27)),
  142.         HeadEnd = <<"Content-Type: text/html\r\n\r\n">>,
  143.         if
  144.                 B1_2 =:= HeadEnd ->
  145.                         B2;
  146.                 B1_2 =/= HeadEnd ->
  147.                         split_content(Data, (StartLength + 1))
  148.         end.
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

沙发
发表于 2019-10-16 17:09:19 | 只看该作者
httpc:request 可以直接支持 erlang对外的http请求,OTP 21开始, 新加的模块 http_uri:encode 很方便的解决了uri 里 需要转义的部分, 例如参数带中文等。
回复 支持 反对

使用道具 举报

板凳
 楼主| 发表于 2019-11-17 12:09:13 | 只看该作者
哈哈,这个是13年的方法,那时的老方法
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|Erldoc.com  

GMT+8, 2024-4-19 22:31 , Processed in 0.388085 second(s), 11 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表