<?php
/**
* http请求类(php + socket)
* @todo 这里还有很多未完善的地方,仅有简单的get post head请求
* @author chuangrain@gmail.com
* @version 1.0.0
*/ class HttpClient { const CRLF = "\r\n";
private $fh = null; //socket handle
private $errno = -1; //socket open error no
private $errstr = ''; //socket open error message
private $timeout = 30; //socket open timeout
private $line = array(); //request line
private $header = array();//request header
private $body = array(); //request body
private $url = array(); //request url
private $response = ''; //response
private $version = '1.1'; //http version public function __construct() { } /**
* 发送HTTP get请求
* @access public
* @param string $url 请求的url
*/
public function get($url = '') {
$this->setUrl($url);
$this->setLine();
$this->setHeader();
$this->request();
return $this->response;
} /**
* 发送HTTP post请求
* @access public
*/
public function post() {
$this->setLine('POST');
$this->request();
return $this->response;
} /**
* HTTP -> HEAD 方法,取得服务器响应一个 HTTP 请求所发送的所有标头
* @access public
* @param string $url 请求的url
* @param int $fmt 数据返回形式,关联数组与普通数组
* @return array 返回响应头信息
*/
public function head($url = '', $fmt = 0) {
$headers = null;
if (is_string($url)) {
$headers = get_headers($url, $fmt);
}
return $headers;
} /**
* 设置要请求的 url
* @todo 这里未做url验证
* @access public
* @param string $url request url
* @return bool
*/
public function setUrl($url = '') {
if (is_string($url)) {
$this->url = parse_url($url);
if (!isset($this->url['port'])) {//设置端口
$this->url['port'] = 80;
}
} else {
return false;
}
} /**
* 设置HTTP协议的版本
* @access public
* @param string $version HTTP版本,default value = 1.1
* @return bool 如果不在范围内返回false
*/
public function setVersion($version = "1.1") {
if ($version == '1.1' || $version == '1.0' || $version == '0.9') {
$this->version = $version;
} else {
return false;
}
} /**
* 设置HTTP请求行
* @access public
* @param string $method 请求方式 default value = GET
*/
private function setLine($method = "GET") {
//请求空:Method URI HttpVersion
if (isset($this->url['query'])) {
$this->line[0] = $method . " " . $this->url['path'] . "?" . $this->url['query'] . " HTTP/" . $this->version;
} else {
$this->line[0] = $method . " " . $this->url['path'] . " HTTP/" . $this->version;
}
} /**
* 设置HTTP请求头信息
* @access public
* @param array $header 请求头信息
*/
public function setHeader($header = null) {
$this->header[0] = "Host: " . $this->url['host'];
if (is_array($header)) {
foreach($header as $k => $v) {
$this->setHeaderKeyValue($k, $v);
}
}
} /**
* HTTP请求主体
* @access public
* @param array $body 请求主体
*/
public function setBody($body = null) {
if (is_array($body)) {
foreach ($body as $k => $v) {
$this->setBodyKeyValue($k, $v);
}
}
} /**
* 单条设置HTTP请求主体
* @access public
* @param string $key 请求主体的键
* @param string $value 请求主体的值
*/
public function setBodyKeyValue($key, $value) {
if (is_string($key)) {
$this->body[] = $key . "=" . $value;
}
} /**
* 单条设置HTTP请求头信息
* @access public
* @param string $key 请求头信息的键
* @param string $value 请求头信息的键
*/
public function setHeaderKeyValue($key, $value) {
if (is_string($key)) {
$this->header[] = $key . ": " . $value;
}
} /**
* socket连接host, 发送请求
* @access private
*/
private function request() {
//构造http请求
if (!empty($this->body)) {
$bodyStr = implode("&", $this->body);
$this->setHeaderKeyValue("Content-Length", strlen($bodyStr));
$this->body[] = $bodyStr;
$req = array_merge($this->line, $this->header, array(""), array($bodyStr), array(""));
} else {
$req = array_merge($this->line, $this->header, array(""), $this->body, array(""));
}
$req = implode(self::CRLF, $req); //socket连接host
$this->fh = fsockopen($this->url['host'], $this->url['port'], $this->errno, $this->errstr, $this->timeout); if (!$this->fh) {
echo "socket connect fail!";
return false;
} //写请求
fwrite($this->fh, $req); //读响应
while (!feof($this->fh)) {
$this->response .= fread($this->fh, 1024);
}
} /**
* 关闭socket连接
* @access public
*/
public function __destruct() {
if ($this->fh) {
fclose($this->fh);
}
} } $url = "http://localhost/xdebug/post_test.php"; /** get test **/
$http1 = new HttpClient();
var_dump($http1->get($url)); /** post test **/
$http2 = new HttpClient();
$header = array(
"Content-Type" => "application/x-www-form-urlencoded"
);
$body = array(
"username" => "1234",
"submit" => "Login"
);
$http2->setUrl($url);
$http2->setHeader($header);
$http2->setBody($body);
var_dump($http2->post()); /** head test **/
$http3 = new HttpClient();
var_dump($http3->head($url, 1));
post_test.php code list
[php] view plaincopyprint?
<?php var_dump($_POST); ?> <!DOCTYPE html>
<html>
<head>
<title>post request test</title>
</head>
<body>
<form action="" method="post">
<input type="text" name="username">
<input type="submit" name="submit" value="Login">
</form>
</body>
</html>

php+socket模拟表单发送请求的更多相关文章

  1. form表单发送请求实例

    <%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncodi ...

  2. Form表单发送到服务器时的编码方式

    ---恢复内容开始--- 表单中的表单中enctype是设置表单的MIME编码. 所谓MIME编码,是指当服务器传送数据给客户端时,必须指定这个文件是什么类型,才能方便客户端调用相应的应用软件来打开该 ...

  3. 织梦cmsf表单提交到邮箱 织梦表单发送到邮箱 织梦自定义表单发邮箱

    大家在做织梦做网站开发时会遇到一个问题:织梦的自定义表单是一个很鸡肋的功能,不仅在后台展示得奇丑,而且也没有提醒功能,使用起来很不方便.很多人用织梦自定义表单时,都想用户提交表单的时候可以发送到自己的 ...

  4. C# POST 表单发送文件

    表单提交协议规定:要先将 HTTP 要求的 Content-Type 设为 multipart/form-data,而且要设定一个 boundary 参数,这个参数是由应用程序自行产生,它会用来识别每 ...

  5. dedecms织梦自定义表单发送到邮箱-用163邮箱发送邮件

    https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=monline_3_dg&wd=dedecms 邮箱&oq=d ...

  6. php表单发送到邮箱V1.0

    html表单代码: <form action="index.php" name="form" method="POST"> &l ...

  7. php Socket模拟表单上传文件函数_学习

    模拟上传文件的php代码 里面访问地址.主机.上传文件名.内容.分隔符可以修改   function postFile($file) {     $clf = "\r\n";   ...

  8. HTTP 笔记与总结(3 )socket 编程:发送 GET 请求

    使用 PHP + socket 模拟发送 HTTP GET 请求,过程是: ① 打开连接 ② 构造 GET 请求的数据:写入请求行.请求头信息.请求主体信息(GET 请求没有主体信息) ③ 发送 GE ...

  9. PHP+SOCKET 模拟HTTP请求

    HTTP消息结构 客户端请求包括四部份:请求行(状态行).请求头.空行.请求主体(数据),如下图: 服务端响应包括四部份:响应行(状态行).响应头.空行.响应主体(数据),如图: HTTP请求方法: ...

随机推荐

  1. Hibernate 系列教程10-组成关系

    组成关系 在一个员工模型里面需要存入 员工公司所在地址的城市,街道 员工籍贯所在的城市,街道, 此时可以抽取城市,街道变成一个模型即是组成关系 Employee public class Employ ...

  2. 拖拽加点ui吧

    有一段时间没写东西了,真的是静下心来不容易的事情. 把之前的代码再翻看下,想想要加点ui什么的. 2d  塔防ui之前 我看过,但放到3d上做,其实难度是很大的. 不过,这不算什么,关键是 合理的 布 ...

  3. Light OJ 1006 - Hex-a-bonacci

    题目链接:http://acm.hust.edu.cn/vjudge/contest/121396#problem/G http://lightoj.com/volume_showproblem.ph ...

  4. Codeforces 691A Fashion in Berland

    水题. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #includ ...

  5. PAT (Advanced Level) 1104. Sum of Number Segments (20)

    简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...

  6. Android中在布局中写ViewPager无法渲染出来的问题

    今天刚刚使用Android Studio,在写ViewPager时,首先按F4把Dependencies添加一个V4包,然后写ViewPager,如下: <android.support.v4. ...

  7. Itext简绍及操作PDF文件

    iText简介 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML.Html文件转 ...

  8. iptables详解--转

    出处:http://yijiu.blog.51cto.com/433846/1356254 iptables详解 基本概念: 1.防火墙工作在主机边缘:对于进出本网络或者本主机的数据报文,根据事先设定 ...

  9. android zip解压缩

    android  zip解压缩 public class ZipUtils { public ZipUtils() { } /* 以输入流的形式解压 */ public static void UnZ ...

  10. CGI接口原理及实现(转载)

    原文:http://blog.csdn.net/duola_rain/article/details/15812585 CGI接口原理及实现(2012-12-7 Over) 1.CGI定义: CGI( ...